diff options
267 files changed, 6862 insertions, 2525 deletions
diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt new file mode 100644 index 000000000000..392a4493eebd --- /dev/null +++ b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | NVIDIA Tegra20/Tegra30 high speed (DMA based) UART controller driver. | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : should be "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart". | ||
5 | - reg: Should contain UART controller registers location and length. | ||
6 | - interrupts: Should contain UART controller interrupts. | ||
7 | - nvidia,dma-request-selector : The Tegra DMA controller's phandle and | ||
8 | request selector for this UART controller. | ||
9 | |||
10 | Optional properties: | ||
11 | - nvidia,enable-modem-interrupt: Enable modem interrupts. Should be enable | ||
12 | only if all 8 lines of UART controller are pinmuxed. | ||
13 | |||
14 | Example: | ||
15 | |||
16 | serial@70006000 { | ||
17 | compatible = "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart"; | ||
18 | reg = <0x70006000 0x40>; | ||
19 | reg-shift = <2>; | ||
20 | interrupts = <0 36 0x04>; | ||
21 | nvidia,dma-request-selector = <&apbdma 8>; | ||
22 | nvidia,enable-modem-interrupt; | ||
23 | status = "disabled"; | ||
24 | }; | ||
diff --git a/Documentation/devicetree/bindings/tty/serial/arc-uart.txt b/Documentation/devicetree/bindings/tty/serial/arc-uart.txt new file mode 100644 index 000000000000..5cae2eb686f8 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/arc-uart.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | * Synopsys ARC UART : Non standard UART used in some of the ARC FPGA boards | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "snps,arc-uart" | ||
5 | - reg : offset and length of the register set for the device. | ||
6 | - interrupts : device interrupt | ||
7 | - clock-frequency : the input clock frequency for the UART | ||
8 | - current-speed : baud rate for UART | ||
9 | |||
10 | e.g. | ||
11 | |||
12 | arcuart0: serial@c0fc1000 { | ||
13 | compatible = "snps,arc-uart"; | ||
14 | reg = <0xc0fc1000 0x100>; | ||
15 | interrupts = <5>; | ||
16 | clock-frequency = <80000000>; | ||
17 | current-speed = <115200>; | ||
18 | status = "okay"; | ||
19 | }; | ||
20 | |||
21 | Note: Each port should have an alias correctly numbered in "aliases" node. | ||
22 | |||
23 | e.g. | ||
24 | aliases { | ||
25 | serial0 = &arcuart0; | ||
26 | }; | ||
diff --git a/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt b/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt index 6588b6950a7f..8e080b893b49 100644 --- a/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt +++ b/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt | |||
@@ -5,10 +5,16 @@ Required properties: | |||
5 | - reg : Address and length of the register set | 5 | - reg : Address and length of the register set |
6 | - interrupts : Should contain uart interrupt | 6 | - interrupts : Should contain uart interrupt |
7 | 7 | ||
8 | Optional properties: | ||
9 | - location : Decides the location of the USART I/O pins. | ||
10 | Allowed range : [0 .. 5] | ||
11 | Default: 0 | ||
12 | |||
8 | Example: | 13 | Example: |
9 | 14 | ||
10 | uart@0x4000c400 { | 15 | uart@0x4000c400 { |
11 | compatible = "efm32,uart"; | 16 | compatible = "efm32,uart"; |
12 | reg = <0x4000c400 0x400>; | 17 | reg = <0x4000c400 0x400>; |
13 | interrupts = <15>; | 18 | interrupts = <15>; |
19 | location = <0>; | ||
14 | }; | 20 | }; |
diff --git a/Documentation/serial/driver b/Documentation/serial/driver index 0a25a9191864..067c47d46917 100644 --- a/Documentation/serial/driver +++ b/Documentation/serial/driver | |||
@@ -133,6 +133,16 @@ hardware. | |||
133 | Interrupts: locally disabled. | 133 | Interrupts: locally disabled. |
134 | This call must not sleep | 134 | This call must not sleep |
135 | 135 | ||
136 | send_xchar(port,ch) | ||
137 | Transmit a high priority character, even if the port is stopped. | ||
138 | This is used to implement XON/XOFF flow control and tcflow(). If | ||
139 | the serial driver does not implement this function, the tty core | ||
140 | will append the character to the circular buffer and then call | ||
141 | start_tx() / stop_tx() to flush the data out. | ||
142 | |||
143 | Locking: none. | ||
144 | Interrupts: caller dependent. | ||
145 | |||
136 | stop_rx(port) | 146 | stop_rx(port) |
137 | Stop receiving characters; the port is in the process of | 147 | Stop receiving characters; the port is in the process of |
138 | being closed. | 148 | being closed. |
@@ -242,9 +252,8 @@ hardware. | |||
242 | 252 | ||
243 | pm(port,state,oldstate) | 253 | pm(port,state,oldstate) |
244 | Perform any power management related activities on the specified | 254 | Perform any power management related activities on the specified |
245 | port. State indicates the new state (defined by ACPI D0-D3), | 255 | port. State indicates the new state (defined by |
246 | oldstate indicates the previous state. Essentially, D0 means | 256 | enum uart_pm_state), oldstate indicates the previous state. |
247 | fully on, D3 means powered down. | ||
248 | 257 | ||
249 | This function should not be used to grab any resources. | 258 | This function should not be used to grab any resources. |
250 | 259 | ||
@@ -255,6 +264,10 @@ hardware. | |||
255 | Locking: none. | 264 | Locking: none. |
256 | Interrupts: caller dependent. | 265 | Interrupts: caller dependent. |
257 | 266 | ||
267 | set_wake(port,state) | ||
268 | Enable/disable power management wakeup on serial activity. Not | ||
269 | currently implemented. | ||
270 | |||
258 | type(port) | 271 | type(port) |
259 | Return a pointer to a string constant describing the specified | 272 | Return a pointer to a string constant describing the specified |
260 | port, or return NULL, in which case the string 'unknown' is | 273 | port, or return NULL, in which case the string 'unknown' is |
@@ -307,6 +320,31 @@ hardware. | |||
307 | Locking: none. | 320 | Locking: none. |
308 | Interrupts: caller dependent. | 321 | Interrupts: caller dependent. |
309 | 322 | ||
323 | poll_init(port) | ||
324 | Called by kgdb to perform the minimal hardware initialization needed | ||
325 | to support poll_put_char() and poll_get_char(). Unlike ->startup() | ||
326 | this should not request interrupts. | ||
327 | |||
328 | Locking: tty_mutex and tty_port->mutex taken. | ||
329 | Interrupts: n/a. | ||
330 | |||
331 | poll_put_char(port,ch) | ||
332 | Called by kgdb to write a single character directly to the serial | ||
333 | port. It can and should block until there is space in the TX FIFO. | ||
334 | |||
335 | Locking: none. | ||
336 | Interrupts: caller dependent. | ||
337 | This call must not sleep | ||
338 | |||
339 | poll_get_char(port) | ||
340 | Called by kgdb to read a single character directly from the serial | ||
341 | port. If data is available, it should be returned; otherwise | ||
342 | the function should return NO_POLL_CHAR immediately. | ||
343 | |||
344 | Locking: none. | ||
345 | Interrupts: caller dependent. | ||
346 | This call must not sleep | ||
347 | |||
310 | Other functions | 348 | Other functions |
311 | --------------- | 349 | --------------- |
312 | 350 | ||
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 775361f67bfd..dabc93649495 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -124,6 +124,7 @@ choice | |||
124 | 124 | ||
125 | config ALPHA_GENERIC | 125 | config ALPHA_GENERIC |
126 | bool "Generic" | 126 | bool "Generic" |
127 | depends on TTY | ||
127 | help | 128 | help |
128 | A generic kernel will run on all supported Alpha hardware. | 129 | A generic kernel will run on all supported Alpha hardware. |
129 | 130 | ||
@@ -490,6 +491,7 @@ config VGA_HOSE | |||
490 | 491 | ||
491 | config ALPHA_SRM | 492 | config ALPHA_SRM |
492 | bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME | 493 | bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME |
494 | depends on TTY | ||
493 | default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL | 495 | default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL |
494 | ---help--- | 496 | ---help--- |
495 | There are two different types of booting firmware on Alphas: SRM, | 497 | There are two different types of booting firmware on Alphas: SRM, |
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 59b7bbad8394..6f01d9ad7b81 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c | |||
@@ -44,7 +44,7 @@ typedef union _srmcons_result { | |||
44 | 44 | ||
45 | /* called with callback_lock held */ | 45 | /* called with callback_lock held */ |
46 | static int | 46 | static int |
47 | srmcons_do_receive_chars(struct tty_struct *tty) | 47 | srmcons_do_receive_chars(struct tty_port *port) |
48 | { | 48 | { |
49 | srmcons_result result; | 49 | srmcons_result result; |
50 | int count = 0, loops = 0; | 50 | int count = 0, loops = 0; |
@@ -52,13 +52,13 @@ srmcons_do_receive_chars(struct tty_struct *tty) | |||
52 | do { | 52 | do { |
53 | result.as_long = callback_getc(0); | 53 | result.as_long = callback_getc(0); |
54 | if (result.bits.status < 2) { | 54 | if (result.bits.status < 2) { |
55 | tty_insert_flip_char(tty, (char)result.bits.c, 0); | 55 | tty_insert_flip_char(port, (char)result.bits.c, 0); |
56 | count++; | 56 | count++; |
57 | } | 57 | } |
58 | } while((result.bits.status & 1) && (++loops < 10)); | 58 | } while((result.bits.status & 1) && (++loops < 10)); |
59 | 59 | ||
60 | if (count) | 60 | if (count) |
61 | tty_schedule_flip(tty); | 61 | tty_schedule_flip(port); |
62 | 62 | ||
63 | return count; | 63 | return count; |
64 | } | 64 | } |
@@ -73,7 +73,7 @@ srmcons_receive_chars(unsigned long data) | |||
73 | 73 | ||
74 | local_irq_save(flags); | 74 | local_irq_save(flags); |
75 | if (spin_trylock(&srmcons_callback_lock)) { | 75 | if (spin_trylock(&srmcons_callback_lock)) { |
76 | if (!srmcons_do_receive_chars(port->tty)) | 76 | if (!srmcons_do_receive_chars(port)) |
77 | incr = 100; | 77 | incr = 100; |
78 | spin_unlock(&srmcons_callback_lock); | 78 | spin_unlock(&srmcons_callback_lock); |
79 | } | 79 | } |
@@ -88,7 +88,7 @@ srmcons_receive_chars(unsigned long data) | |||
88 | 88 | ||
89 | /* called with callback_lock held */ | 89 | /* called with callback_lock held */ |
90 | static int | 90 | static int |
91 | srmcons_do_write(struct tty_struct *tty, const char *buf, int count) | 91 | srmcons_do_write(struct tty_port *port, const char *buf, int count) |
92 | { | 92 | { |
93 | static char str_cr[1] = "\r"; | 93 | static char str_cr[1] = "\r"; |
94 | long c, remaining = count; | 94 | long c, remaining = count; |
@@ -113,10 +113,10 @@ srmcons_do_write(struct tty_struct *tty, const char *buf, int count) | |||
113 | cur += result.bits.c; | 113 | cur += result.bits.c; |
114 | 114 | ||
115 | /* | 115 | /* |
116 | * Check for pending input iff a tty was provided | 116 | * Check for pending input iff a tty port was provided |
117 | */ | 117 | */ |
118 | if (tty) | 118 | if (port) |
119 | srmcons_do_receive_chars(tty); | 119 | srmcons_do_receive_chars(port); |
120 | } | 120 | } |
121 | 121 | ||
122 | while (need_cr) { | 122 | while (need_cr) { |
@@ -135,7 +135,7 @@ srmcons_write(struct tty_struct *tty, | |||
135 | unsigned long flags; | 135 | unsigned long flags; |
136 | 136 | ||
137 | spin_lock_irqsave(&srmcons_callback_lock, flags); | 137 | spin_lock_irqsave(&srmcons_callback_lock, flags); |
138 | srmcons_do_write(tty, (const char *) buf, count); | 138 | srmcons_do_write(tty->port, (const char *) buf, count); |
139 | spin_unlock_irqrestore(&srmcons_callback_lock, flags); | 139 | spin_unlock_irqrestore(&srmcons_callback_lock, flags); |
140 | 140 | ||
141 | return count; | 141 | return count; |
diff --git a/arch/arm/boot/dts/vt8500.dtsi b/arch/arm/boot/dts/vt8500.dtsi index d8645e990b21..cf31ced46602 100644 --- a/arch/arm/boot/dts/vt8500.dtsi +++ b/arch/arm/boot/dts/vt8500.dtsi | |||
@@ -45,6 +45,38 @@ | |||
45 | compatible = "fixed-clock"; | 45 | compatible = "fixed-clock"; |
46 | clock-frequency = <24000000>; | 46 | clock-frequency = <24000000>; |
47 | }; | 47 | }; |
48 | |||
49 | clkuart0: uart0 { | ||
50 | #clock-cells = <0>; | ||
51 | compatible = "via,vt8500-device-clock"; | ||
52 | clocks = <&ref24>; | ||
53 | enable-reg = <0x250>; | ||
54 | enable-bit = <1>; | ||
55 | }; | ||
56 | |||
57 | clkuart1: uart1 { | ||
58 | #clock-cells = <0>; | ||
59 | compatible = "via,vt8500-device-clock"; | ||
60 | clocks = <&ref24>; | ||
61 | enable-reg = <0x250>; | ||
62 | enable-bit = <2>; | ||
63 | }; | ||
64 | |||
65 | clkuart2: uart2 { | ||
66 | #clock-cells = <0>; | ||
67 | compatible = "via,vt8500-device-clock"; | ||
68 | clocks = <&ref24>; | ||
69 | enable-reg = <0x250>; | ||
70 | enable-bit = <3>; | ||
71 | }; | ||
72 | |||
73 | clkuart3: uart3 { | ||
74 | #clock-cells = <0>; | ||
75 | compatible = "via,vt8500-device-clock"; | ||
76 | clocks = <&ref24>; | ||
77 | enable-reg = <0x250>; | ||
78 | enable-bit = <4>; | ||
79 | }; | ||
48 | }; | 80 | }; |
49 | }; | 81 | }; |
50 | 82 | ||
@@ -83,28 +115,28 @@ | |||
83 | compatible = "via,vt8500-uart"; | 115 | compatible = "via,vt8500-uart"; |
84 | reg = <0xd8200000 0x1040>; | 116 | reg = <0xd8200000 0x1040>; |
85 | interrupts = <32>; | 117 | interrupts = <32>; |
86 | clocks = <&ref24>; | 118 | clocks = <&clkuart0>; |
87 | }; | 119 | }; |
88 | 120 | ||
89 | uart@d82b0000 { | 121 | uart@d82b0000 { |
90 | compatible = "via,vt8500-uart"; | 122 | compatible = "via,vt8500-uart"; |
91 | reg = <0xd82b0000 0x1040>; | 123 | reg = <0xd82b0000 0x1040>; |
92 | interrupts = <33>; | 124 | interrupts = <33>; |
93 | clocks = <&ref24>; | 125 | clocks = <&clkuart1>; |
94 | }; | 126 | }; |
95 | 127 | ||
96 | uart@d8210000 { | 128 | uart@d8210000 { |
97 | compatible = "via,vt8500-uart"; | 129 | compatible = "via,vt8500-uart"; |
98 | reg = <0xd8210000 0x1040>; | 130 | reg = <0xd8210000 0x1040>; |
99 | interrupts = <47>; | 131 | interrupts = <47>; |
100 | clocks = <&ref24>; | 132 | clocks = <&clkuart2>; |
101 | }; | 133 | }; |
102 | 134 | ||
103 | uart@d82c0000 { | 135 | uart@d82c0000 { |
104 | compatible = "via,vt8500-uart"; | 136 | compatible = "via,vt8500-uart"; |
105 | reg = <0xd82c0000 0x1040>; | 137 | reg = <0xd82c0000 0x1040>; |
106 | interrupts = <50>; | 138 | interrupts = <50>; |
107 | clocks = <&ref24>; | 139 | clocks = <&clkuart3>; |
108 | }; | 140 | }; |
109 | 141 | ||
110 | rtc@d8100000 { | 142 | rtc@d8100000 { |
diff --git a/arch/arm/boot/dts/wm8505.dtsi b/arch/arm/boot/dts/wm8505.dtsi index 330f833ac3b0..e74a1c0fb9a2 100644 --- a/arch/arm/boot/dts/wm8505.dtsi +++ b/arch/arm/boot/dts/wm8505.dtsi | |||
@@ -59,6 +59,54 @@ | |||
59 | compatible = "fixed-clock"; | 59 | compatible = "fixed-clock"; |
60 | clock-frequency = <24000000>; | 60 | clock-frequency = <24000000>; |
61 | }; | 61 | }; |
62 | |||
63 | clkuart0: uart0 { | ||
64 | #clock-cells = <0>; | ||
65 | compatible = "via,vt8500-device-clock"; | ||
66 | clocks = <&ref24>; | ||
67 | enable-reg = <0x250>; | ||
68 | enable-bit = <1>; | ||
69 | }; | ||
70 | |||
71 | clkuart1: uart1 { | ||
72 | #clock-cells = <0>; | ||
73 | compatible = "via,vt8500-device-clock"; | ||
74 | clocks = <&ref24>; | ||
75 | enable-reg = <0x250>; | ||
76 | enable-bit = <2>; | ||
77 | }; | ||
78 | |||
79 | clkuart2: uart2 { | ||
80 | #clock-cells = <0>; | ||
81 | compatible = "via,vt8500-device-clock"; | ||
82 | clocks = <&ref24>; | ||
83 | enable-reg = <0x250>; | ||
84 | enable-bit = <3>; | ||
85 | }; | ||
86 | |||
87 | clkuart3: uart3 { | ||
88 | #clock-cells = <0>; | ||
89 | compatible = "via,vt8500-device-clock"; | ||
90 | clocks = <&ref24>; | ||
91 | enable-reg = <0x250>; | ||
92 | enable-bit = <4>; | ||
93 | }; | ||
94 | |||
95 | clkuart4: uart4 { | ||
96 | #clock-cells = <0>; | ||
97 | compatible = "via,vt8500-device-clock"; | ||
98 | clocks = <&ref24>; | ||
99 | enable-reg = <0x250>; | ||
100 | enable-bit = <22>; | ||
101 | }; | ||
102 | |||
103 | clkuart5: uart5 { | ||
104 | #clock-cells = <0>; | ||
105 | compatible = "via,vt8500-device-clock"; | ||
106 | clocks = <&ref24>; | ||
107 | enable-reg = <0x250>; | ||
108 | enable-bit = <23>; | ||
109 | }; | ||
62 | }; | 110 | }; |
63 | }; | 111 | }; |
64 | 112 | ||
@@ -96,42 +144,42 @@ | |||
96 | compatible = "via,vt8500-uart"; | 144 | compatible = "via,vt8500-uart"; |
97 | reg = <0xd8200000 0x1040>; | 145 | reg = <0xd8200000 0x1040>; |
98 | interrupts = <32>; | 146 | interrupts = <32>; |
99 | clocks = <&ref24>; | 147 | clocks = <&clkuart0>; |
100 | }; | 148 | }; |
101 | 149 | ||
102 | uart@d82b0000 { | 150 | uart@d82b0000 { |
103 | compatible = "via,vt8500-uart"; | 151 | compatible = "via,vt8500-uart"; |
104 | reg = <0xd82b0000 0x1040>; | 152 | reg = <0xd82b0000 0x1040>; |
105 | interrupts = <33>; | 153 | interrupts = <33>; |
106 | clocks = <&ref24>; | 154 | clocks = <&clkuart1>; |
107 | }; | 155 | }; |
108 | 156 | ||
109 | uart@d8210000 { | 157 | uart@d8210000 { |
110 | compatible = "via,vt8500-uart"; | 158 | compatible = "via,vt8500-uart"; |
111 | reg = <0xd8210000 0x1040>; | 159 | reg = <0xd8210000 0x1040>; |
112 | interrupts = <47>; | 160 | interrupts = <47>; |
113 | clocks = <&ref24>; | 161 | clocks = <&clkuart2>; |
114 | }; | 162 | }; |
115 | 163 | ||
116 | uart@d82c0000 { | 164 | uart@d82c0000 { |
117 | compatible = "via,vt8500-uart"; | 165 | compatible = "via,vt8500-uart"; |
118 | reg = <0xd82c0000 0x1040>; | 166 | reg = <0xd82c0000 0x1040>; |
119 | interrupts = <50>; | 167 | interrupts = <50>; |
120 | clocks = <&ref24>; | 168 | clocks = <&clkuart3>; |
121 | }; | 169 | }; |
122 | 170 | ||
123 | uart@d8370000 { | 171 | uart@d8370000 { |
124 | compatible = "via,vt8500-uart"; | 172 | compatible = "via,vt8500-uart"; |
125 | reg = <0xd8370000 0x1040>; | 173 | reg = <0xd8370000 0x1040>; |
126 | interrupts = <31>; | 174 | interrupts = <31>; |
127 | clocks = <&ref24>; | 175 | clocks = <&clkuart4>; |
128 | }; | 176 | }; |
129 | 177 | ||
130 | uart@d8380000 { | 178 | uart@d8380000 { |
131 | compatible = "via,vt8500-uart"; | 179 | compatible = "via,vt8500-uart"; |
132 | reg = <0xd8380000 0x1040>; | 180 | reg = <0xd8380000 0x1040>; |
133 | interrupts = <30>; | 181 | interrupts = <30>; |
134 | clocks = <&ref24>; | 182 | clocks = <&clkuart5>; |
135 | }; | 183 | }; |
136 | 184 | ||
137 | rtc@d8100000 { | 185 | rtc@d8100000 { |
diff --git a/arch/arm/boot/dts/wm8650.dtsi b/arch/arm/boot/dts/wm8650.dtsi index 83b9467559bb..db3c0a12e052 100644 --- a/arch/arm/boot/dts/wm8650.dtsi +++ b/arch/arm/boot/dts/wm8650.dtsi | |||
@@ -75,6 +75,22 @@ | |||
75 | reg = <0x204>; | 75 | reg = <0x204>; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | clkuart0: uart0 { | ||
79 | #clock-cells = <0>; | ||
80 | compatible = "via,vt8500-device-clock"; | ||
81 | clocks = <&ref24>; | ||
82 | enable-reg = <0x250>; | ||
83 | enable-bit = <1>; | ||
84 | }; | ||
85 | |||
86 | clkuart1: uart1 { | ||
87 | #clock-cells = <0>; | ||
88 | compatible = "via,vt8500-device-clock"; | ||
89 | clocks = <&ref24>; | ||
90 | enable-reg = <0x250>; | ||
91 | enable-bit = <2>; | ||
92 | }; | ||
93 | |||
78 | arm: arm { | 94 | arm: arm { |
79 | #clock-cells = <0>; | 95 | #clock-cells = <0>; |
80 | compatible = "via,vt8500-device-clock"; | 96 | compatible = "via,vt8500-device-clock"; |
@@ -128,14 +144,14 @@ | |||
128 | compatible = "via,vt8500-uart"; | 144 | compatible = "via,vt8500-uart"; |
129 | reg = <0xd8200000 0x1040>; | 145 | reg = <0xd8200000 0x1040>; |
130 | interrupts = <32>; | 146 | interrupts = <32>; |
131 | clocks = <&ref24>; | 147 | clocks = <&clkuart0>; |
132 | }; | 148 | }; |
133 | 149 | ||
134 | uart@d82b0000 { | 150 | uart@d82b0000 { |
135 | compatible = "via,vt8500-uart"; | 151 | compatible = "via,vt8500-uart"; |
136 | reg = <0xd82b0000 0x1040>; | 152 | reg = <0xd82b0000 0x1040>; |
137 | interrupts = <33>; | 153 | interrupts = <33>; |
138 | clocks = <&ref24>; | 154 | clocks = <&clkuart1>; |
139 | }; | 155 | }; |
140 | 156 | ||
141 | rtc@d8100000 { | 157 | rtc@d8100000 { |
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index 401c1262d4ed..5914b5654591 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi | |||
@@ -44,14 +44,14 @@ | |||
44 | compatible = "xlnx,xuartps"; | 44 | compatible = "xlnx,xuartps"; |
45 | reg = <0xE0000000 0x1000>; | 45 | reg = <0xE0000000 0x1000>; |
46 | interrupts = <0 27 4>; | 46 | interrupts = <0 27 4>; |
47 | clock = <50000000>; | 47 | clocks = <&uart_clk 0>; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | uart1: uart@e0001000 { | 50 | uart1: uart@e0001000 { |
51 | compatible = "xlnx,xuartps"; | 51 | compatible = "xlnx,xuartps"; |
52 | reg = <0xE0001000 0x1000>; | 52 | reg = <0xE0001000 0x1000>; |
53 | interrupts = <0 50 4>; | 53 | interrupts = <0 50 4>; |
54 | clock = <50000000>; | 54 | clocks = <&uart_clk 1>; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | slcr: slcr@f8000000 { | 57 | slcr: slcr@f8000000 { |
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 9a23739f7026..442497363db9 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
17 | #include <linux/platform_data/sa11x0-serial.h> | 17 | #include <linux/platform_data/sa11x0-serial.h> |
18 | #include <linux/serial_core.h> | 18 | #include <linux/serial_core.h> |
19 | #include <linux/platform_device.h> | ||
19 | #include <linux/mfd/ucb1x00.h> | 20 | #include <linux/mfd/ucb1x00.h> |
20 | #include <linux/mtd/mtd.h> | 21 | #include <linux/mtd/mtd.h> |
21 | #include <linux/mtd/partitions.h> | 22 | #include <linux/mtd/partitions.h> |
diff --git a/arch/arm/plat-samsung/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h index b258a08de591..2fc89315553f 100644 --- a/arch/arm/plat-samsung/include/plat/adc.h +++ b/arch/arm/plat-samsung/include/plat/adc.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #define __ASM_PLAT_ADC_H __FILE__ | 15 | #define __ASM_PLAT_ADC_H __FILE__ |
16 | 16 | ||
17 | struct s3c_adc_client; | 17 | struct s3c_adc_client; |
18 | struct platform_device; | ||
18 | 19 | ||
19 | extern int s3c_adc_start(struct s3c_adc_client *client, | 20 | extern int s3c_adc_start(struct s3c_adc_client *client, |
20 | unsigned int channel, unsigned int nr_samples); | 21 | unsigned int channel, unsigned int nr_samples); |
diff --git a/arch/ia64/hp/sim/Kconfig b/arch/ia64/hp/sim/Kconfig index 8d513a8c5266..d84707d55203 100644 --- a/arch/ia64/hp/sim/Kconfig +++ b/arch/ia64/hp/sim/Kconfig | |||
@@ -8,6 +8,7 @@ config HP_SIMETH | |||
8 | 8 | ||
9 | config HP_SIMSERIAL | 9 | config HP_SIMSERIAL |
10 | bool "Simulated serial driver support" | 10 | bool "Simulated serial driver support" |
11 | depends on TTY | ||
11 | 12 | ||
12 | config HP_SIMSERIAL_CONSOLE | 13 | config HP_SIMSERIAL_CONSOLE |
13 | bool "Console for HP simulator" | 14 | bool "Console for HP simulator" |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index fc3924d18c1f..da2f319fb71d 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -53,7 +53,7 @@ struct tty_driver *hp_simserial_driver; | |||
53 | 53 | ||
54 | static struct console *console; | 54 | static struct console *console; |
55 | 55 | ||
56 | static void receive_chars(struct tty_struct *tty) | 56 | static void receive_chars(struct tty_port *port) |
57 | { | 57 | { |
58 | unsigned char ch; | 58 | unsigned char ch; |
59 | static unsigned char seen_esc = 0; | 59 | static unsigned char seen_esc = 0; |
@@ -81,10 +81,10 @@ static void receive_chars(struct tty_struct *tty) | |||
81 | } | 81 | } |
82 | seen_esc = 0; | 82 | seen_esc = 0; |
83 | 83 | ||
84 | if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) | 84 | if (tty_insert_flip_char(port, ch, TTY_NORMAL) == 0) |
85 | break; | 85 | break; |
86 | } | 86 | } |
87 | tty_flip_buffer_push(tty); | 87 | tty_flip_buffer_push(port); |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /* |
@@ -93,18 +93,9 @@ static void receive_chars(struct tty_struct *tty) | |||
93 | static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | 93 | static irqreturn_t rs_interrupt_single(int irq, void *dev_id) |
94 | { | 94 | { |
95 | struct serial_state *info = dev_id; | 95 | struct serial_state *info = dev_id; |
96 | struct tty_struct *tty = tty_port_tty_get(&info->port); | ||
97 | 96 | ||
98 | if (!tty) { | 97 | receive_chars(&info->port); |
99 | printk(KERN_INFO "%s: tty=0 problem\n", __func__); | 98 | |
100 | return IRQ_NONE; | ||
101 | } | ||
102 | /* | ||
103 | * pretty simple in our case, because we only get interrupts | ||
104 | * on inbound traffic | ||
105 | */ | ||
106 | receive_chars(tty); | ||
107 | tty_kref_put(tty); | ||
108 | return IRQ_HANDLED; | 99 | return IRQ_HANDLED; |
109 | } | 100 | } |
110 | 101 | ||
@@ -435,7 +426,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp) | |||
435 | struct tty_port *port = &info->port; | 426 | struct tty_port *port = &info->port; |
436 | 427 | ||
437 | tty->driver_data = info; | 428 | tty->driver_data = info; |
438 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 429 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
439 | 430 | ||
440 | /* | 431 | /* |
441 | * figure out which console to use (should be one already) | 432 | * figure out which console to use (should be one already) |
diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices index c4cdfe444c64..4bc945dfe467 100644 --- a/arch/m68k/Kconfig.devices +++ b/arch/m68k/Kconfig.devices | |||
@@ -41,7 +41,7 @@ config NFBLOCK | |||
41 | 41 | ||
42 | config NFCON | 42 | config NFCON |
43 | tristate "NatFeat console driver" | 43 | tristate "NatFeat console driver" |
44 | depends on NATFEAT | 44 | depends on TTY && NATFEAT |
45 | help | 45 | help |
46 | Say Y to include support for the ARAnyM NatFeat console driver | 46 | Say Y to include support for the ARAnyM NatFeat console driver |
47 | which allows the console output to be redirected to the stderr | 47 | which allows the console output to be redirected to the stderr |
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index 9cb9d43a3a0e..e05ad4da44d9 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c | |||
@@ -118,7 +118,7 @@ static struct resource sc26xx_rsrc[] = { | |||
118 | } | 118 | } |
119 | }; | 119 | }; |
120 | 120 | ||
121 | #include <linux/platform_data/sccnxp.h> | 121 | #include <linux/platform_data/serial-sccnxp.h> |
122 | 122 | ||
123 | static struct sccnxp_pdata sccnxp_data = { | 123 | static struct sccnxp_pdata sccnxp_data = { |
124 | .reg_shift = 2, | 124 | .reg_shift = 2, |
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index 81d5cb9b6569..bf6e949a2f87 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c | |||
@@ -524,7 +524,7 @@ static int mask_test_and_clear(volatile u8 *ptr, u8 mask) | |||
524 | static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port) | 524 | static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port) |
525 | { | 525 | { |
526 | struct uart_icount *icount = &port->uart.icount; | 526 | struct uart_icount *icount = &port->uart.icount; |
527 | struct tty_struct *tty = port->uart.state->port.tty; | 527 | struct tty_port *tport = &port->uart.state->port; |
528 | unsigned ix; | 528 | unsigned ix; |
529 | int count; | 529 | int count; |
530 | u8 st, ch, push, status, overrun; | 530 | u8 st, ch, push, status, overrun; |
@@ -534,10 +534,10 @@ static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port) | |||
534 | push = 0; | 534 | push = 0; |
535 | 535 | ||
536 | count = CIRC_CNT(port->rx_inp, port->rx_outp, MNSC_BUFFER_SIZE); | 536 | count = CIRC_CNT(port->rx_inp, port->rx_outp, MNSC_BUFFER_SIZE); |
537 | count = tty_buffer_request_room(tty, count); | 537 | count = tty_buffer_request_room(tport, count); |
538 | if (count == 0) { | 538 | if (count == 0) { |
539 | if (!tty->low_latency) | 539 | if (!tport->low_latency) |
540 | tty_flip_buffer_push(tty); | 540 | tty_flip_buffer_push(tport); |
541 | return; | 541 | return; |
542 | } | 542 | } |
543 | 543 | ||
@@ -545,8 +545,8 @@ try_again: | |||
545 | /* pull chars out of the hat */ | 545 | /* pull chars out of the hat */ |
546 | ix = ACCESS_ONCE(port->rx_outp); | 546 | ix = ACCESS_ONCE(port->rx_outp); |
547 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) { | 547 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) { |
548 | if (push && !tty->low_latency) | 548 | if (push && !tport->low_latency) |
549 | tty_flip_buffer_push(tty); | 549 | tty_flip_buffer_push(tport); |
550 | return; | 550 | return; |
551 | } | 551 | } |
552 | 552 | ||
@@ -666,19 +666,19 @@ insert: | |||
666 | else | 666 | else |
667 | flag = TTY_NORMAL; | 667 | flag = TTY_NORMAL; |
668 | 668 | ||
669 | tty_insert_flip_char(tty, ch, flag); | 669 | tty_insert_flip_char(tport, ch, flag); |
670 | } | 670 | } |
671 | 671 | ||
672 | /* overrun is special, since it's reported immediately, and doesn't | 672 | /* overrun is special, since it's reported immediately, and doesn't |
673 | * affect the current character | 673 | * affect the current character |
674 | */ | 674 | */ |
675 | if (overrun) | 675 | if (overrun) |
676 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 676 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
677 | 677 | ||
678 | count--; | 678 | count--; |
679 | if (count <= 0) { | 679 | if (count <= 0) { |
680 | if (!tty->low_latency) | 680 | if (!tport->low_latency) |
681 | tty_flip_buffer_push(tty); | 681 | tty_flip_buffer_push(tport); |
682 | return; | 682 | return; |
683 | } | 683 | } |
684 | 684 | ||
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 9f2820659da2..c600f39aa453 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -21,6 +21,7 @@ config PARISC | |||
21 | select HAVE_MOD_ARCH_SPECIFIC | 21 | select HAVE_MOD_ARCH_SPECIFIC |
22 | select MODULES_USE_ELF_RELA | 22 | select MODULES_USE_ELF_RELA |
23 | select CLONE_BACKWARDS | 23 | select CLONE_BACKWARDS |
24 | select TTY # Needed for pdc_cons.c | ||
24 | 25 | ||
25 | help | 26 | help |
26 | The PA-RISC microprocessor is designed by Hewlett-Packard and used | 27 | The PA-RISC microprocessor is designed by Hewlett-Packard and used |
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index efc5e7d30530..d5cae55195ec 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c | |||
@@ -138,23 +138,17 @@ static const struct tty_operations pdc_console_tty_ops = { | |||
138 | static void pdc_console_poll(unsigned long unused) | 138 | static void pdc_console_poll(unsigned long unused) |
139 | { | 139 | { |
140 | int data, count = 0; | 140 | int data, count = 0; |
141 | struct tty_struct *tty = tty_port_tty_get(&tty_port); | ||
142 | |||
143 | if (!tty) | ||
144 | return; | ||
145 | 141 | ||
146 | while (1) { | 142 | while (1) { |
147 | data = pdc_console_poll_key(NULL); | 143 | data = pdc_console_poll_key(NULL); |
148 | if (data == -1) | 144 | if (data == -1) |
149 | break; | 145 | break; |
150 | tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); | 146 | tty_insert_flip_char(&tty_port, data & 0xFF, TTY_NORMAL); |
151 | count ++; | 147 | count ++; |
152 | } | 148 | } |
153 | 149 | ||
154 | if (count) | 150 | if (count) |
155 | tty_flip_buffer_push(tty); | 151 | tty_flip_buffer_push(&tty_port); |
156 | |||
157 | tty_kref_put(tty); | ||
158 | 152 | ||
159 | if (pdc_cons.flags & CON_ENABLED) | 153 | if (pdc_cons.flags & CON_ENABLED) |
160 | mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); | 154 | mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY); |
diff --git a/arch/sparc/kernel/kgdb_32.c b/arch/sparc/kernel/kgdb_32.c index 2e424a576a36..dcf210811af4 100644 --- a/arch/sparc/kernel/kgdb_32.c +++ b/arch/sparc/kernel/kgdb_32.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <linux/kgdb.h> | 6 | #include <linux/kgdb.h> |
7 | #include <linux/kdebug.h> | 7 | #include <linux/kdebug.h> |
8 | #include <linux/sched.h> | ||
8 | 9 | ||
9 | #include <asm/kdebug.h> | 10 | #include <asm/kdebug.h> |
10 | #include <asm/ptrace.h> | 11 | #include <asm/ptrace.h> |
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 1bb7ad4aeff4..36136e81f5d8 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -121,6 +121,7 @@ config DEBUG_COPY_FROM_USER | |||
121 | def_bool n | 121 | def_bool n |
122 | 122 | ||
123 | config HVC_TILE | 123 | config HVC_TILE |
124 | depends on TTY | ||
124 | select HVC_DRIVER | 125 | select HVC_DRIVER |
125 | def_bool y | 126 | def_bool y |
126 | 127 | ||
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index 648121b037d5..bceee6623b00 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common | |||
@@ -12,6 +12,7 @@ config UML | |||
12 | select GENERIC_CPU_DEVICES | 12 | select GENERIC_CPU_DEVICES |
13 | select GENERIC_IO | 13 | select GENERIC_IO |
14 | select GENERIC_CLOCKEVENTS | 14 | select GENERIC_CLOCKEVENTS |
15 | select TTY # Needed for line.c | ||
15 | 16 | ||
16 | config MMU | 17 | config MMU |
17 | bool | 18 | bool |
diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h index 02b5a76e98d9..78f1b8999964 100644 --- a/arch/um/drivers/chan.h +++ b/arch/um/drivers/chan.h | |||
@@ -27,8 +27,7 @@ struct chan { | |||
27 | void *data; | 27 | void *data; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | extern void chan_interrupt(struct line *line, | 30 | extern void chan_interrupt(struct line *line, int irq); |
31 | struct tty_struct *tty, int irq); | ||
32 | extern int parse_chan_pair(char *str, struct line *line, int device, | 31 | extern int parse_chan_pair(char *str, struct line *line, int device, |
33 | const struct chan_opts *opts, char **error_out); | 32 | const struct chan_opts *opts, char **error_out); |
34 | extern int write_chan(struct chan *chan, const char *buf, int len, | 33 | extern int write_chan(struct chan *chan, const char *buf, int len, |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index e9a0abc6a32f..15c553c239a1 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -81,12 +81,6 @@ static const struct chan_ops not_configged_ops = { | |||
81 | }; | 81 | }; |
82 | #endif /* CONFIG_NOCONFIG_CHAN */ | 82 | #endif /* CONFIG_NOCONFIG_CHAN */ |
83 | 83 | ||
84 | static void tty_receive_char(struct tty_struct *tty, char ch) | ||
85 | { | ||
86 | if (tty) | ||
87 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | ||
88 | } | ||
89 | |||
90 | static int open_one_chan(struct chan *chan) | 84 | static int open_one_chan(struct chan *chan) |
91 | { | 85 | { |
92 | int fd, err; | 86 | int fd, err; |
@@ -137,11 +131,9 @@ void chan_enable_winch(struct chan *chan, struct tty_struct *tty) | |||
137 | static void line_timer_cb(struct work_struct *work) | 131 | static void line_timer_cb(struct work_struct *work) |
138 | { | 132 | { |
139 | struct line *line = container_of(work, struct line, task.work); | 133 | struct line *line = container_of(work, struct line, task.work); |
140 | struct tty_struct *tty = tty_port_tty_get(&line->port); | ||
141 | 134 | ||
142 | if (!line->throttled) | 135 | if (!line->throttled) |
143 | chan_interrupt(line, tty, line->driver->read_irq); | 136 | chan_interrupt(line, line->driver->read_irq); |
144 | tty_kref_put(tty); | ||
145 | } | 137 | } |
146 | 138 | ||
147 | int enable_chan(struct line *line) | 139 | int enable_chan(struct line *line) |
@@ -552,8 +544,9 @@ int parse_chan_pair(char *str, struct line *line, int device, | |||
552 | return 0; | 544 | return 0; |
553 | } | 545 | } |
554 | 546 | ||
555 | void chan_interrupt(struct line *line, struct tty_struct *tty, int irq) | 547 | void chan_interrupt(struct line *line, int irq) |
556 | { | 548 | { |
549 | struct tty_port *port = &line->port; | ||
557 | struct chan *chan = line->chan_in; | 550 | struct chan *chan = line->chan_in; |
558 | int err; | 551 | int err; |
559 | char c; | 552 | char c; |
@@ -562,21 +555,24 @@ void chan_interrupt(struct line *line, struct tty_struct *tty, int irq) | |||
562 | goto out; | 555 | goto out; |
563 | 556 | ||
564 | do { | 557 | do { |
565 | if (tty && !tty_buffer_request_room(tty, 1)) { | 558 | if (!tty_buffer_request_room(port, 1)) { |
566 | schedule_delayed_work(&line->task, 1); | 559 | schedule_delayed_work(&line->task, 1); |
567 | goto out; | 560 | goto out; |
568 | } | 561 | } |
569 | err = chan->ops->read(chan->fd, &c, chan->data); | 562 | err = chan->ops->read(chan->fd, &c, chan->data); |
570 | if (err > 0) | 563 | if (err > 0) |
571 | tty_receive_char(tty, c); | 564 | tty_insert_flip_char(port, c, TTY_NORMAL); |
572 | } while (err > 0); | 565 | } while (err > 0); |
573 | 566 | ||
574 | if (err == 0) | 567 | if (err == 0) |
575 | reactivate_fd(chan->fd, irq); | 568 | reactivate_fd(chan->fd, irq); |
576 | if (err == -EIO) { | 569 | if (err == -EIO) { |
577 | if (chan->primary) { | 570 | if (chan->primary) { |
578 | if (tty != NULL) | 571 | struct tty_struct *tty = tty_port_tty_get(&line->port); |
572 | if (tty != NULL) { | ||
579 | tty_hangup(tty); | 573 | tty_hangup(tty); |
574 | tty_kref_put(tty); | ||
575 | } | ||
580 | if (line->chan_out != chan) | 576 | if (line->chan_out != chan) |
581 | close_one_chan(line->chan_out, 1); | 577 | close_one_chan(line->chan_out, 1); |
582 | } | 578 | } |
@@ -585,6 +581,5 @@ void chan_interrupt(struct line *line, struct tty_struct *tty, int irq) | |||
585 | return; | 581 | return; |
586 | } | 582 | } |
587 | out: | 583 | out: |
588 | if (tty) | 584 | tty_flip_buffer_push(port); |
589 | tty_flip_buffer_push(tty); | ||
590 | } | 585 | } |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 9ffc28bd4b7a..f1b38571f94e 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -19,11 +19,10 @@ static irqreturn_t line_interrupt(int irq, void *data) | |||
19 | { | 19 | { |
20 | struct chan *chan = data; | 20 | struct chan *chan = data; |
21 | struct line *line = chan->line; | 21 | struct line *line = chan->line; |
22 | struct tty_struct *tty = tty_port_tty_get(&line->port); | ||
23 | 22 | ||
24 | if (line) | 23 | if (line) |
25 | chan_interrupt(line, tty, irq); | 24 | chan_interrupt(line, irq); |
26 | tty_kref_put(tty); | 25 | |
27 | return IRQ_HANDLED; | 26 | return IRQ_HANDLED; |
28 | } | 27 | } |
29 | 28 | ||
@@ -234,7 +233,7 @@ void line_unthrottle(struct tty_struct *tty) | |||
234 | struct line *line = tty->driver_data; | 233 | struct line *line = tty->driver_data; |
235 | 234 | ||
236 | line->throttled = 0; | 235 | line->throttled = 0; |
237 | chan_interrupt(line, tty, line->driver->read_irq); | 236 | chan_interrupt(line, line->driver->read_irq); |
238 | 237 | ||
239 | /* | 238 | /* |
240 | * Maybe there is enough stuff pending that calling the interrupt | 239 | * Maybe there is enough stuff pending that calling the interrupt |
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index 7872a3330fb5..29043d2048a0 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig | |||
@@ -2,6 +2,7 @@ config LGUEST_GUEST | |||
2 | bool "Lguest guest support" | 2 | bool "Lguest guest support" |
3 | select PARAVIRT | 3 | select PARAVIRT |
4 | depends on X86_32 | 4 | depends on X86_32 |
5 | select TTY | ||
5 | select VIRTUALIZATION | 6 | select VIRTUALIZATION |
6 | select VIRTIO | 7 | select VIRTIO |
7 | select VIRTIO_CONSOLE | 8 | select VIRTIO_CONSOLE |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 5aab1acabf1c..ad64c73b8675 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -132,6 +132,7 @@ choice | |||
132 | 132 | ||
133 | config XTENSA_PLATFORM_ISS | 133 | config XTENSA_PLATFORM_ISS |
134 | bool "ISS" | 134 | bool "ISS" |
135 | depends on TTY | ||
135 | select XTENSA_CALIBRATE_CCOUNT | 136 | select XTENSA_CALIBRATE_CCOUNT |
136 | select SERIAL_CONSOLE | 137 | select SERIAL_CONSOLE |
137 | select XTENSA_ISS_NETWORK | 138 | select XTENSA_ISS_NETWORK |
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 8207a119eee9..da9866f7fecf 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c | |||
@@ -58,7 +58,8 @@ static int rs_open(struct tty_struct *tty, struct file * filp) | |||
58 | tty->port = &serial_port; | 58 | tty->port = &serial_port; |
59 | spin_lock(&timer_lock); | 59 | spin_lock(&timer_lock); |
60 | if (tty->count == 1) { | 60 | if (tty->count == 1) { |
61 | setup_timer(&serial_timer, rs_poll, (unsigned long)tty); | 61 | setup_timer(&serial_timer, rs_poll, |
62 | (unsigned long)&serial_port); | ||
62 | mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); | 63 | mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); |
63 | } | 64 | } |
64 | spin_unlock(&timer_lock); | 65 | spin_unlock(&timer_lock); |
@@ -97,8 +98,7 @@ static int rs_write(struct tty_struct * tty, | |||
97 | 98 | ||
98 | static void rs_poll(unsigned long priv) | 99 | static void rs_poll(unsigned long priv) |
99 | { | 100 | { |
100 | struct tty_struct* tty = (struct tty_struct*) priv; | 101 | struct tty_port *port = (struct tty_port *)priv; |
101 | |||
102 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; | 102 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; |
103 | int i = 0; | 103 | int i = 0; |
104 | unsigned char c; | 104 | unsigned char c; |
@@ -107,12 +107,12 @@ static void rs_poll(unsigned long priv) | |||
107 | 107 | ||
108 | while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){ | 108 | while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){ |
109 | __simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0); | 109 | __simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0); |
110 | tty_insert_flip_char(tty, c, TTY_NORMAL); | 110 | tty_insert_flip_char(port, c, TTY_NORMAL); |
111 | i++; | 111 | i++; |
112 | } | 112 | } |
113 | 113 | ||
114 | if (i) | 114 | if (i) |
115 | tty_flip_buffer_push(tty); | 115 | tty_flip_buffer_push(port); |
116 | 116 | ||
117 | 117 | ||
118 | mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); | 118 | mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); |
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index e9f203eadb1f..fdfd61a2d523 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -26,6 +26,7 @@ config BT_HCIBTSDIO | |||
26 | 26 | ||
27 | config BT_HCIUART | 27 | config BT_HCIUART |
28 | tristate "HCI UART driver" | 28 | tristate "HCI UART driver" |
29 | depends on TTY | ||
29 | help | 30 | help |
30 | Bluetooth HCI UART driver. | 31 | Bluetooth HCI UART driver. |
31 | This driver is required if you want to use Bluetooth devices with | 32 | This driver is required if you want to use Bluetooth devices with |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 72bedad6bf8c..3bb6fa3930be 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -53,7 +53,7 @@ source "drivers/tty/serial/Kconfig" | |||
53 | 53 | ||
54 | config TTY_PRINTK | 54 | config TTY_PRINTK |
55 | bool "TTY driver to output user messages via printk" | 55 | bool "TTY driver to output user messages via printk" |
56 | depends on EXPERT | 56 | depends on EXPERT && TTY |
57 | default n | 57 | default n |
58 | ---help--- | 58 | ---help--- |
59 | If you say Y here, the support for writing user messages (i.e. | 59 | If you say Y here, the support for writing user messages (i.e. |
@@ -159,7 +159,7 @@ source "drivers/tty/hvc/Kconfig" | |||
159 | 159 | ||
160 | config VIRTIO_CONSOLE | 160 | config VIRTIO_CONSOLE |
161 | tristate "Virtio console" | 161 | tristate "Virtio console" |
162 | depends on VIRTIO | 162 | depends on VIRTIO && TTY |
163 | select HVC_DRIVER | 163 | select HVC_DRIVER |
164 | help | 164 | help |
165 | Virtio console for use with lguest and other hypervisors. | 165 | Virtio console for use with lguest and other hypervisors. |
@@ -392,6 +392,7 @@ config XILINX_HWICAP | |||
392 | 392 | ||
393 | config R3964 | 393 | config R3964 |
394 | tristate "Siemens R3964 line discipline" | 394 | tristate "Siemens R3964 line discipline" |
395 | depends on TTY | ||
395 | ---help--- | 396 | ---help--- |
396 | This driver allows synchronous communication with devices using the | 397 | This driver allows synchronous communication with devices using the |
397 | Siemens R3964 packet protocol. Unless you are dealing with special | 398 | Siemens R3964 packet protocol. Unless you are dealing with special |
@@ -439,7 +440,7 @@ source "drivers/char/pcmcia/Kconfig" | |||
439 | 440 | ||
440 | config MWAVE | 441 | config MWAVE |
441 | tristate "ACP Modem (Mwave) support" | 442 | tristate "ACP Modem (Mwave) support" |
442 | depends on X86 | 443 | depends on X86 && TTY |
443 | select SERIAL_8250 | 444 | select SERIAL_8250 |
444 | ---help--- | 445 | ---help--- |
445 | The ACP modem (Mwave) for Linux is a WinModem. It is composed of a | 446 | The ACP modem (Mwave) for Linux is a WinModem. It is composed of a |
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig index 6614416a8623..2a166d56738a 100644 --- a/drivers/char/pcmcia/Kconfig +++ b/drivers/char/pcmcia/Kconfig | |||
@@ -7,7 +7,7 @@ menu "PCMCIA character devices" | |||
7 | 7 | ||
8 | config SYNCLINK_CS | 8 | config SYNCLINK_CS |
9 | tristate "SyncLink PC Card support" | 9 | tristate "SyncLink PC Card support" |
10 | depends on PCMCIA | 10 | depends on PCMCIA && TTY |
11 | help | 11 | help |
12 | Enable support for the SyncLink PC Card serial adapter, running | 12 | Enable support for the SyncLink PC Card serial adapter, running |
13 | asynchronous and HDLC communications up to 512Kbps. The port is | 13 | asynchronous and HDLC communications up to 512Kbps. The port is |
@@ -45,7 +45,7 @@ config CARDMAN_4040 | |||
45 | 45 | ||
46 | config IPWIRELESS | 46 | config IPWIRELESS |
47 | tristate "IPWireless 3G UMTS PCMCIA card support" | 47 | tristate "IPWireless 3G UMTS PCMCIA card support" |
48 | depends on PCMCIA && NETDEVICES | 48 | depends on PCMCIA && NETDEVICES && TTY |
49 | select PPP | 49 | select PPP |
50 | help | 50 | help |
51 | This is a driver for 3G UMTS PCMCIA card from IPWireless company. In | 51 | This is a driver for 3G UMTS PCMCIA card from IPWireless company. In |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index b66eaa04f8cb..d0c9852ab875 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -210,7 +210,7 @@ typedef struct _mgslpc_info { | |||
210 | char testing_irq; | 210 | char testing_irq; |
211 | unsigned int init_error; /* startup error (DIAGS) */ | 211 | unsigned int init_error; /* startup error (DIAGS) */ |
212 | 212 | ||
213 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 213 | char *flag_buf; |
214 | bool drop_rts_on_tx_done; | 214 | bool drop_rts_on_tx_done; |
215 | 215 | ||
216 | struct _input_signal_events input_signal_events; | 216 | struct _input_signal_events input_signal_events; |
@@ -765,9 +765,6 @@ static void bh_handler(struct work_struct *work) | |||
765 | struct tty_struct *tty; | 765 | struct tty_struct *tty; |
766 | int action; | 766 | int action; |
767 | 767 | ||
768 | if (!info) | ||
769 | return; | ||
770 | |||
771 | if (debug_level >= DEBUG_LEVEL_BH) | 768 | if (debug_level >= DEBUG_LEVEL_BH) |
772 | printk( "%s(%d):bh_handler(%s) entry\n", | 769 | printk( "%s(%d):bh_handler(%s) entry\n", |
773 | __FILE__,__LINE__,info->device_name); | 770 | __FILE__,__LINE__,info->device_name); |
@@ -886,21 +883,14 @@ static void rx_ready_hdlc(MGSLPC_INFO *info, int eom) | |||
886 | issue_command(info, CHA, CMD_RXFIFO); | 883 | issue_command(info, CHA, CMD_RXFIFO); |
887 | } | 884 | } |
888 | 885 | ||
889 | static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) | 886 | static void rx_ready_async(MGSLPC_INFO *info, int tcd) |
890 | { | 887 | { |
888 | struct tty_port *port = &info->port; | ||
891 | unsigned char data, status, flag; | 889 | unsigned char data, status, flag; |
892 | int fifo_count; | 890 | int fifo_count; |
893 | int work = 0; | 891 | int work = 0; |
894 | struct mgsl_icount *icount = &info->icount; | 892 | struct mgsl_icount *icount = &info->icount; |
895 | 893 | ||
896 | if (!tty) { | ||
897 | /* tty is not available anymore */ | ||
898 | issue_command(info, CHA, CMD_RXRESET); | ||
899 | if (debug_level >= DEBUG_LEVEL_ISR) | ||
900 | printk("%s(%d):rx_ready_async(tty=NULL)\n",__FILE__,__LINE__); | ||
901 | return; | ||
902 | } | ||
903 | |||
904 | if (tcd) { | 894 | if (tcd) { |
905 | /* early termination, get FIFO count from RBCL register */ | 895 | /* early termination, get FIFO count from RBCL register */ |
906 | fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f); | 896 | fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f); |
@@ -913,7 +903,7 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) | |||
913 | } else | 903 | } else |
914 | fifo_count = 32; | 904 | fifo_count = 32; |
915 | 905 | ||
916 | tty_buffer_request_room(tty, fifo_count); | 906 | tty_buffer_request_room(port, fifo_count); |
917 | /* Flush received async data to receive data buffer. */ | 907 | /* Flush received async data to receive data buffer. */ |
918 | while (fifo_count) { | 908 | while (fifo_count) { |
919 | data = read_reg(info, CHA + RXFIFO); | 909 | data = read_reg(info, CHA + RXFIFO); |
@@ -944,7 +934,7 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) | |||
944 | else if (status & BIT6) | 934 | else if (status & BIT6) |
945 | flag = TTY_FRAME; | 935 | flag = TTY_FRAME; |
946 | } | 936 | } |
947 | work += tty_insert_flip_char(tty, data, flag); | 937 | work += tty_insert_flip_char(port, data, flag); |
948 | } | 938 | } |
949 | issue_command(info, CHA, CMD_RXFIFO); | 939 | issue_command(info, CHA, CMD_RXFIFO); |
950 | 940 | ||
@@ -957,7 +947,7 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) | |||
957 | } | 947 | } |
958 | 948 | ||
959 | if (work) | 949 | if (work) |
960 | tty_flip_buffer_push(tty); | 950 | tty_flip_buffer_push(port); |
961 | } | 951 | } |
962 | 952 | ||
963 | 953 | ||
@@ -1217,7 +1207,7 @@ static irqreturn_t mgslpc_isr(int dummy, void *dev_id) | |||
1217 | if (info->params.mode == MGSL_MODE_HDLC) | 1207 | if (info->params.mode == MGSL_MODE_HDLC) |
1218 | rx_ready_hdlc(info, isr & IRQ_RXEOM); | 1208 | rx_ready_hdlc(info, isr & IRQ_RXEOM); |
1219 | else | 1209 | else |
1220 | rx_ready_async(info, isr & IRQ_RXEOM, tty); | 1210 | rx_ready_async(info, isr & IRQ_RXEOM); |
1221 | } | 1211 | } |
1222 | 1212 | ||
1223 | /* transmit IRQs */ | 1213 | /* transmit IRQs */ |
@@ -1353,7 +1343,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) | |||
1353 | reset_device(info); | 1343 | reset_device(info); |
1354 | 1344 | ||
1355 | if (!tty || tty->termios.c_cflag & HUPCL) { | 1345 | if (!tty || tty->termios.c_cflag & HUPCL) { |
1356 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 1346 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1357 | set_signals(info); | 1347 | set_signals(info); |
1358 | } | 1348 | } |
1359 | 1349 | ||
@@ -1415,12 +1405,12 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty) | |||
1415 | 1405 | ||
1416 | cflag = tty->termios.c_cflag; | 1406 | cflag = tty->termios.c_cflag; |
1417 | 1407 | ||
1418 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 1408 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
1419 | /* otherwise assert DTR and RTS */ | 1409 | /* otherwise assert RTS and DTR */ |
1420 | if (cflag & CBAUD) | 1410 | if (cflag & CBAUD) |
1421 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 1411 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
1422 | else | 1412 | else |
1423 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 1413 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1424 | 1414 | ||
1425 | /* byte size and parity */ | 1415 | /* byte size and parity */ |
1426 | 1416 | ||
@@ -2311,7 +2301,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2311 | /* Handle transition to B0 status */ | 2301 | /* Handle transition to B0 status */ |
2312 | if (old_termios->c_cflag & CBAUD && | 2302 | if (old_termios->c_cflag & CBAUD && |
2313 | !(tty->termios.c_cflag & CBAUD)) { | 2303 | !(tty->termios.c_cflag & CBAUD)) { |
2314 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2304 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2315 | spin_lock_irqsave(&info->lock,flags); | 2305 | spin_lock_irqsave(&info->lock,flags); |
2316 | set_signals(info); | 2306 | set_signals(info); |
2317 | spin_unlock_irqrestore(&info->lock,flags); | 2307 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -2474,9 +2464,9 @@ static void dtr_rts(struct tty_port *port, int onoff) | |||
2474 | 2464 | ||
2475 | spin_lock_irqsave(&info->lock,flags); | 2465 | spin_lock_irqsave(&info->lock,flags); |
2476 | if (onoff) | 2466 | if (onoff) |
2477 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 2467 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
2478 | else | 2468 | else |
2479 | info->serial_signals &= ~SerialSignal_RTS + SerialSignal_DTR; | 2469 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2480 | set_signals(info); | 2470 | set_signals(info); |
2481 | spin_unlock_irqrestore(&info->lock,flags); | 2471 | spin_unlock_irqrestore(&info->lock,flags); |
2482 | } | 2472 | } |
@@ -2521,7 +2511,7 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp) | |||
2521 | goto cleanup; | 2511 | goto cleanup; |
2522 | } | 2512 | } |
2523 | 2513 | ||
2524 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 2514 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
2525 | 2515 | ||
2526 | spin_lock_irqsave(&info->netlock, flags); | 2516 | spin_lock_irqsave(&info->netlock, flags); |
2527 | if (info->netcount) { | 2517 | if (info->netcount) { |
@@ -2674,6 +2664,14 @@ static int rx_alloc_buffers(MGSLPC_INFO *info) | |||
2674 | if (info->rx_buf == NULL) | 2664 | if (info->rx_buf == NULL) |
2675 | return -ENOMEM; | 2665 | return -ENOMEM; |
2676 | 2666 | ||
2667 | /* unused flag buffer to satisfy receive_buf calling interface */ | ||
2668 | info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL); | ||
2669 | if (!info->flag_buf) { | ||
2670 | kfree(info->rx_buf); | ||
2671 | info->rx_buf = NULL; | ||
2672 | return -ENOMEM; | ||
2673 | } | ||
2674 | |||
2677 | rx_reset_buffers(info); | 2675 | rx_reset_buffers(info); |
2678 | return 0; | 2676 | return 0; |
2679 | } | 2677 | } |
@@ -2682,6 +2680,8 @@ static void rx_free_buffers(MGSLPC_INFO *info) | |||
2682 | { | 2680 | { |
2683 | kfree(info->rx_buf); | 2681 | kfree(info->rx_buf); |
2684 | info->rx_buf = NULL; | 2682 | info->rx_buf = NULL; |
2683 | kfree(info->flag_buf); | ||
2684 | info->flag_buf = NULL; | ||
2685 | } | 2685 | } |
2686 | 2686 | ||
2687 | static int claim_resources(MGSLPC_INFO *info) | 2687 | static int claim_resources(MGSLPC_INFO *info) |
@@ -3575,8 +3575,8 @@ static void get_signals(MGSLPC_INFO *info) | |||
3575 | { | 3575 | { |
3576 | unsigned char status = 0; | 3576 | unsigned char status = 0; |
3577 | 3577 | ||
3578 | /* preserve DTR and RTS */ | 3578 | /* preserve RTS and DTR */ |
3579 | info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; | 3579 | info->serial_signals &= SerialSignal_RTS | SerialSignal_DTR; |
3580 | 3580 | ||
3581 | if (read_reg(info, CHB + VSTR) & BIT7) | 3581 | if (read_reg(info, CHB + VSTR) & BIT7) |
3582 | info->serial_signals |= SerialSignal_DCD; | 3582 | info->serial_signals |= SerialSignal_DCD; |
@@ -3590,7 +3590,7 @@ static void get_signals(MGSLPC_INFO *info) | |||
3590 | info->serial_signals |= SerialSignal_DSR; | 3590 | info->serial_signals |= SerialSignal_DSR; |
3591 | } | 3591 | } |
3592 | 3592 | ||
3593 | /* Set the state of DTR and RTS based on contents of | 3593 | /* Set the state of RTS and DTR based on contents of |
3594 | * serial_signals member of device extension. | 3594 | * serial_signals member of device extension. |
3595 | */ | 3595 | */ |
3596 | static void set_signals(MGSLPC_INFO *info) | 3596 | static void set_signals(MGSLPC_INFO *info) |
@@ -4009,8 +4009,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
4009 | spin_unlock_irqrestore(&info->netlock, flags); | 4009 | spin_unlock_irqrestore(&info->netlock, flags); |
4010 | return rc; | 4010 | return rc; |
4011 | } | 4011 | } |
4012 | /* assert DTR and RTS, apply hardware settings */ | 4012 | /* assert RTS and DTR, apply hardware settings */ |
4013 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 4013 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
4014 | mgslpc_program_hw(info, tty); | 4014 | mgslpc_program_hw(info, tty); |
4015 | tty_kref_put(tty); | 4015 | tty_kref_put(tty); |
4016 | 4016 | ||
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 51044cc55cf2..88d9ef6b5b4a 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/module.h> | ||
30 | #include <drm/drmP.h> | 31 | #include <drm/drmP.h> |
31 | #include <drm/drm_crtc.h> | 32 | #include <drm/drm_crtc.h> |
32 | #include <drm/drm_crtc_helper.h> | 33 | #include <drm/drm_crtc_helper.h> |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 9b94a78ca776..8bb810e1900b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -802,6 +802,7 @@ config I2C_PARPORT_LIGHT | |||
802 | 802 | ||
803 | config I2C_TAOS_EVM | 803 | config I2C_TAOS_EVM |
804 | tristate "TAOS evaluation module" | 804 | tristate "TAOS evaluation module" |
805 | depends on TTY | ||
805 | select SERIO | 806 | select SERIO |
806 | select SERIO_SERPORT | 807 | select SERIO_SERPORT |
807 | default n | 808 | default n |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 560c243bfcaf..6e9cc765e0dc 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -36,6 +36,7 @@ config SERIO_I8042 | |||
36 | config SERIO_SERPORT | 36 | config SERIO_SERPORT |
37 | tristate "Serial port line discipline" | 37 | tristate "Serial port line discipline" |
38 | default y | 38 | default y |
39 | depends on TTY | ||
39 | help | 40 | help |
40 | Say Y here if you plan to use an input device (mouse, joystick, | 41 | Say Y here if you plan to use an input device (mouse, joystick, |
41 | tablet, 6dof) that communicates over the RS232 serial (COM) port. | 42 | tablet, 6dof) that communicates over the RS232 serial (COM) port. |
diff --git a/drivers/ipack/devices/Kconfig b/drivers/ipack/devices/Kconfig index 0b82fdc198c0..907a8cb48f2a 100644 --- a/drivers/ipack/devices/Kconfig +++ b/drivers/ipack/devices/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SERIAL_IPOCTAL | 1 | config SERIAL_IPOCTAL |
2 | tristate "IndustryPack IP-OCTAL uart support" | 2 | tristate "IndustryPack IP-OCTAL uart support" |
3 | depends on IPACK_BUS | 3 | depends on IPACK_BUS && TTY |
4 | help | 4 | help |
5 | This driver supports the IPOCTAL serial port device for the IndustryPack bus. | 5 | This driver supports the IPOCTAL serial port device for the IndustryPack bus. |
6 | default n | 6 | default n |
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 576d53d92677..ab20a0851dd2 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c | |||
@@ -133,9 +133,9 @@ static int ipoctal_get_icount(struct tty_struct *tty, | |||
133 | return 0; | 133 | return 0; |
134 | } | 134 | } |
135 | 135 | ||
136 | static void ipoctal_irq_rx(struct ipoctal_channel *channel, | 136 | static void ipoctal_irq_rx(struct ipoctal_channel *channel, u8 sr) |
137 | struct tty_struct *tty, u8 sr) | ||
138 | { | 137 | { |
138 | struct tty_port *port = &channel->tty_port; | ||
139 | unsigned char value; | 139 | unsigned char value; |
140 | unsigned char flag = TTY_NORMAL; | 140 | unsigned char flag = TTY_NORMAL; |
141 | u8 isr; | 141 | u8 isr; |
@@ -149,7 +149,7 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel, | |||
149 | if (sr & SR_OVERRUN_ERROR) { | 149 | if (sr & SR_OVERRUN_ERROR) { |
150 | channel->stats.overrun_err++; | 150 | channel->stats.overrun_err++; |
151 | /* Overrun doesn't affect the current character*/ | 151 | /* Overrun doesn't affect the current character*/ |
152 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 152 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
153 | } | 153 | } |
154 | if (sr & SR_PARITY_ERROR) { | 154 | if (sr & SR_PARITY_ERROR) { |
155 | channel->stats.parity_err++; | 155 | channel->stats.parity_err++; |
@@ -165,7 +165,7 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel, | |||
165 | flag = TTY_BREAK; | 165 | flag = TTY_BREAK; |
166 | } | 166 | } |
167 | } | 167 | } |
168 | tty_insert_flip_char(tty, value, flag); | 168 | tty_insert_flip_char(port, value, flag); |
169 | 169 | ||
170 | /* Check if there are more characters in RX FIFO | 170 | /* Check if there are more characters in RX FIFO |
171 | * If there are more, the isr register for this channel | 171 | * If there are more, the isr register for this channel |
@@ -175,7 +175,7 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel, | |||
175 | sr = ioread8(&channel->regs->r.sr); | 175 | sr = ioread8(&channel->regs->r.sr); |
176 | } while (isr & channel->isr_rx_rdy_mask); | 176 | } while (isr & channel->isr_rx_rdy_mask); |
177 | 177 | ||
178 | tty_flip_buffer_push(tty); | 178 | tty_flip_buffer_push(port); |
179 | } | 179 | } |
180 | 180 | ||
181 | static void ipoctal_irq_tx(struct ipoctal_channel *channel) | 181 | static void ipoctal_irq_tx(struct ipoctal_channel *channel) |
@@ -208,15 +208,11 @@ static void ipoctal_irq_tx(struct ipoctal_channel *channel) | |||
208 | static void ipoctal_irq_channel(struct ipoctal_channel *channel) | 208 | static void ipoctal_irq_channel(struct ipoctal_channel *channel) |
209 | { | 209 | { |
210 | u8 isr, sr; | 210 | u8 isr, sr; |
211 | struct tty_struct *tty; | ||
212 | 211 | ||
213 | /* If there is no client, skip the check */ | 212 | /* If there is no client, skip the check */ |
214 | if (!atomic_read(&channel->open)) | 213 | if (!atomic_read(&channel->open)) |
215 | return; | 214 | return; |
216 | 215 | ||
217 | tty = tty_port_tty_get(&channel->tty_port); | ||
218 | if (!tty) | ||
219 | return; | ||
220 | /* The HW is organized in pair of channels. See which register we need | 216 | /* The HW is organized in pair of channels. See which register we need |
221 | * to read from */ | 217 | * to read from */ |
222 | isr = ioread8(&channel->block_regs->r.isr); | 218 | isr = ioread8(&channel->block_regs->r.isr); |
@@ -235,14 +231,13 @@ static void ipoctal_irq_channel(struct ipoctal_channel *channel) | |||
235 | 231 | ||
236 | /* RX data */ | 232 | /* RX data */ |
237 | if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) | 233 | if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) |
238 | ipoctal_irq_rx(channel, tty, sr); | 234 | ipoctal_irq_rx(channel, sr); |
239 | 235 | ||
240 | /* TX of each character */ | 236 | /* TX of each character */ |
241 | if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) | 237 | if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) |
242 | ipoctal_irq_tx(channel); | 238 | ipoctal_irq_tx(channel); |
243 | 239 | ||
244 | tty_flip_buffer_push(tty); | 240 | tty_flip_buffer_push(&channel->tty_port); |
245 | tty_kref_put(tty); | ||
246 | } | 241 | } |
247 | 242 | ||
248 | static irqreturn_t ipoctal_irq_handler(void *arg) | 243 | static irqreturn_t ipoctal_irq_handler(void *arg) |
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig index 86cd75a0e84d..ef661acdda17 100644 --- a/drivers/isdn/Kconfig +++ b/drivers/isdn/Kconfig | |||
@@ -22,6 +22,7 @@ if ISDN | |||
22 | 22 | ||
23 | menuconfig ISDN_I4L | 23 | menuconfig ISDN_I4L |
24 | tristate "Old ISDN4Linux (deprecated)" | 24 | tristate "Old ISDN4Linux (deprecated)" |
25 | depends on TTY | ||
25 | ---help--- | 26 | ---help--- |
26 | This driver allows you to use an ISDN adapter for networking | 27 | This driver allows you to use an ISDN adapter for networking |
27 | connections and as dialin/out device. The isdn-tty's have a built | 28 | connections and as dialin/out device. The isdn-tty's have a built |
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig index 15c3ffd9d860..f04686580040 100644 --- a/drivers/isdn/capi/Kconfig +++ b/drivers/isdn/capi/Kconfig | |||
@@ -18,6 +18,7 @@ config CAPI_TRACE | |||
18 | 18 | ||
19 | config ISDN_CAPI_MIDDLEWARE | 19 | config ISDN_CAPI_MIDDLEWARE |
20 | bool "CAPI2.0 Middleware support" | 20 | bool "CAPI2.0 Middleware support" |
21 | depends on TTY | ||
21 | help | 22 | help |
22 | This option will enhance the capabilities of the /dev/capi20 | 23 | This option will enhance the capabilities of the /dev/capi20 |
23 | interface. It will provide a means of moving a data connection, | 24 | interface. It will provide a means of moving a data connection, |
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig index b18a92c32184..dde5e09e6267 100644 --- a/drivers/isdn/gigaset/Kconfig +++ b/drivers/isdn/gigaset/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | menuconfig ISDN_DRV_GIGASET | 1 | menuconfig ISDN_DRV_GIGASET |
2 | tristate "Siemens Gigaset support" | 2 | tristate "Siemens Gigaset support" |
3 | depends on TTY | ||
3 | select CRC_CCITT | 4 | select CRC_CCITT |
4 | select BITREVERSE | 5 | select BITREVERSE |
5 | help | 6 | help |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 20b7e7a1190f..e2b539675b66 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -134,7 +134,7 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
134 | 134 | ||
135 | if (cs->port.count == 1) { | 135 | if (cs->port.count == 1) { |
136 | tty_port_tty_set(&cs->port, tty); | 136 | tty_port_tty_set(&cs->port, tty); |
137 | tty->low_latency = 1; | 137 | cs->port.low_latency = 1; |
138 | } | 138 | } |
139 | 139 | ||
140 | mutex_unlock(&cs->mutex); | 140 | mutex_unlock(&cs->mutex); |
@@ -546,16 +546,8 @@ void gigaset_if_free(struct cardstate *cs) | |||
546 | void gigaset_if_receive(struct cardstate *cs, | 546 | void gigaset_if_receive(struct cardstate *cs, |
547 | unsigned char *buffer, size_t len) | 547 | unsigned char *buffer, size_t len) |
548 | { | 548 | { |
549 | struct tty_struct *tty = tty_port_tty_get(&cs->port); | 549 | tty_insert_flip_string(&cs->port, buffer, len); |
550 | 550 | tty_flip_buffer_push(&cs->port); | |
551 | if (tty == NULL) { | ||
552 | gig_dbg(DEBUG_IF, "receive on closed device"); | ||
553 | return; | ||
554 | } | ||
555 | |||
556 | tty_insert_flip_string(tty, buffer, len); | ||
557 | tty_flip_buffer_push(tty); | ||
558 | tty_kref_put(tty); | ||
559 | } | 551 | } |
560 | EXPORT_SYMBOL_GPL(gigaset_if_receive); | 552 | EXPORT_SYMBOL_GPL(gigaset_if_receive); |
561 | 553 | ||
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig index eadc1cd34a20..b8611e3e5e74 100644 --- a/drivers/isdn/hardware/mISDN/Kconfig +++ b/drivers/isdn/hardware/mISDN/Kconfig | |||
@@ -76,6 +76,7 @@ config MISDN_NETJET | |||
76 | tristate "Support for NETJet cards" | 76 | tristate "Support for NETJet cards" |
77 | depends on MISDN | 77 | depends on MISDN |
78 | depends on PCI | 78 | depends on PCI |
79 | depends on TTY | ||
79 | select MISDN_IPAC | 80 | select MISDN_IPAC |
80 | select ISDN_HDLC | 81 | select ISDN_HDLC |
81 | select ISDN_I4L | 82 | select ISDN_I4L |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index e2a945ee9f05..b87d9e577be2 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -876,7 +876,7 @@ isdn_readbchan(int di, int channel, u_char *buf, u_char *fp, int len, wait_queue | |||
876 | * of the mapping (di,ch)<->minor, happen during the sleep? --he | 876 | * of the mapping (di,ch)<->minor, happen during the sleep? --he |
877 | */ | 877 | */ |
878 | int | 878 | int |
879 | isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | 879 | isdn_readbchan_tty(int di, int channel, struct tty_port *port, int cisco_hack) |
880 | { | 880 | { |
881 | int count; | 881 | int count; |
882 | int count_pull; | 882 | int count_pull; |
@@ -891,7 +891,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
891 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) | 891 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) |
892 | return 0; | 892 | return 0; |
893 | 893 | ||
894 | len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]); | 894 | len = tty_buffer_request_room(port, dev->drv[di]->rcvcount[channel]); |
895 | if (len == 0) | 895 | if (len == 0) |
896 | return len; | 896 | return len; |
897 | 897 | ||
@@ -912,7 +912,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
912 | while ((count_pull < skb->len) && (len > 0)) { | 912 | while ((count_pull < skb->len) && (len > 0)) { |
913 | /* push every character but the last to the tty buffer directly */ | 913 | /* push every character but the last to the tty buffer directly */ |
914 | if (count_put) | 914 | if (count_put) |
915 | tty_insert_flip_char(tty, last, TTY_NORMAL); | 915 | tty_insert_flip_char(port, last, TTY_NORMAL); |
916 | len--; | 916 | len--; |
917 | if (dev->drv[di]->DLEflag & DLEmask) { | 917 | if (dev->drv[di]->DLEflag & DLEmask) { |
918 | last = DLE; | 918 | last = DLE; |
@@ -940,7 +940,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
940 | } | 940 | } |
941 | count_put = count_pull; | 941 | count_put = count_pull; |
942 | if (count_put > 1) | 942 | if (count_put > 1) |
943 | tty_insert_flip_string(tty, skb->data, count_put - 1); | 943 | tty_insert_flip_string(port, skb->data, count_put - 1); |
944 | last = skb->data[count_put - 1]; | 944 | last = skb->data[count_put - 1]; |
945 | len -= count_put; | 945 | len -= count_put; |
946 | #ifdef CONFIG_ISDN_AUDIO | 946 | #ifdef CONFIG_ISDN_AUDIO |
@@ -952,16 +952,16 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
952 | * Now we can dequeue it. | 952 | * Now we can dequeue it. |
953 | */ | 953 | */ |
954 | if (cisco_hack) | 954 | if (cisco_hack) |
955 | tty_insert_flip_char(tty, last, 0xFF); | 955 | tty_insert_flip_char(port, last, 0xFF); |
956 | else | 956 | else |
957 | tty_insert_flip_char(tty, last, TTY_NORMAL); | 957 | tty_insert_flip_char(port, last, TTY_NORMAL); |
958 | #ifdef CONFIG_ISDN_AUDIO | 958 | #ifdef CONFIG_ISDN_AUDIO |
959 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | 959 | ISDN_AUDIO_SKB_LOCK(skb) = 0; |
960 | #endif | 960 | #endif |
961 | skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); | 961 | skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); |
962 | dev_kfree_skb(skb); | 962 | dev_kfree_skb(skb); |
963 | } else { | 963 | } else { |
964 | tty_insert_flip_char(tty, last, TTY_NORMAL); | 964 | tty_insert_flip_char(port, last, TTY_NORMAL); |
965 | /* Not yet emptied this buff, so it | 965 | /* Not yet emptied this buff, so it |
966 | * must stay in the queue, for further calls | 966 | * must stay in the queue, for further calls |
967 | * but we pull off the data we got until now. | 967 | * but we pull off the data we got until now. |
diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h index 9a471f62e1d4..2260ef07ab9c 100644 --- a/drivers/isdn/i4l/isdn_common.h +++ b/drivers/isdn/i4l/isdn_common.h | |||
@@ -37,7 +37,7 @@ extern void isdn_timer_ctrl(int tf, int onoff); | |||
37 | extern void isdn_unexclusive_channel(int di, int ch); | 37 | extern void isdn_unexclusive_channel(int di, int ch); |
38 | extern int isdn_getnum(char **); | 38 | extern int isdn_getnum(char **); |
39 | extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); | 39 | extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); |
40 | extern int isdn_readbchan_tty(int, int, struct tty_struct *, int); | 40 | extern int isdn_readbchan_tty(int, int, struct tty_port *, int); |
41 | extern int isdn_get_free_channel(int, int, int, int, int, char *); | 41 | extern int isdn_get_free_channel(int, int, int, int, int, char *); |
42 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); | 42 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); |
43 | extern int register_isdn(isdn_if *i); | 43 | extern int register_isdn(isdn_if *i); |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index e09dc8a5e743..d8a7d8323414 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -60,18 +60,14 @@ static int si2bit[8] = | |||
60 | static int | 60 | static int |
61 | isdn_tty_try_read(modem_info *info, struct sk_buff *skb) | 61 | isdn_tty_try_read(modem_info *info, struct sk_buff *skb) |
62 | { | 62 | { |
63 | struct tty_port *port = &info->port; | ||
63 | int c; | 64 | int c; |
64 | int len; | 65 | int len; |
65 | struct tty_struct *tty; | ||
66 | char last; | 66 | char last; |
67 | 67 | ||
68 | if (!info->online) | 68 | if (!info->online) |
69 | return 0; | 69 | return 0; |
70 | 70 | ||
71 | tty = info->port.tty; | ||
72 | if (!tty) | ||
73 | return 0; | ||
74 | |||
75 | if (!(info->mcr & UART_MCR_RTS)) | 71 | if (!(info->mcr & UART_MCR_RTS)) |
76 | return 0; | 72 | return 0; |
77 | 73 | ||
@@ -81,7 +77,7 @@ isdn_tty_try_read(modem_info *info, struct sk_buff *skb) | |||
81 | #endif | 77 | #endif |
82 | ; | 78 | ; |
83 | 79 | ||
84 | c = tty_buffer_request_room(tty, len); | 80 | c = tty_buffer_request_room(port, len); |
85 | if (c < len) | 81 | if (c < len) |
86 | return 0; | 82 | return 0; |
87 | 83 | ||
@@ -91,25 +87,25 @@ isdn_tty_try_read(modem_info *info, struct sk_buff *skb) | |||
91 | unsigned char *dp = skb->data; | 87 | unsigned char *dp = skb->data; |
92 | while (--l) { | 88 | while (--l) { |
93 | if (*dp == DLE) | 89 | if (*dp == DLE) |
94 | tty_insert_flip_char(tty, DLE, 0); | 90 | tty_insert_flip_char(port, DLE, 0); |
95 | tty_insert_flip_char(tty, *dp++, 0); | 91 | tty_insert_flip_char(port, *dp++, 0); |
96 | } | 92 | } |
97 | if (*dp == DLE) | 93 | if (*dp == DLE) |
98 | tty_insert_flip_char(tty, DLE, 0); | 94 | tty_insert_flip_char(port, DLE, 0); |
99 | last = *dp; | 95 | last = *dp; |
100 | } else { | 96 | } else { |
101 | #endif | 97 | #endif |
102 | if (len > 1) | 98 | if (len > 1) |
103 | tty_insert_flip_string(tty, skb->data, len - 1); | 99 | tty_insert_flip_string(port, skb->data, len - 1); |
104 | last = skb->data[len - 1]; | 100 | last = skb->data[len - 1]; |
105 | #ifdef CONFIG_ISDN_AUDIO | 101 | #ifdef CONFIG_ISDN_AUDIO |
106 | } | 102 | } |
107 | #endif | 103 | #endif |
108 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) | 104 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) |
109 | tty_insert_flip_char(tty, last, 0xFF); | 105 | tty_insert_flip_char(port, last, 0xFF); |
110 | else | 106 | else |
111 | tty_insert_flip_char(tty, last, TTY_NORMAL); | 107 | tty_insert_flip_char(port, last, TTY_NORMAL); |
112 | tty_flip_buffer_push(tty); | 108 | tty_flip_buffer_push(port); |
113 | kfree_skb(skb); | 109 | kfree_skb(skb); |
114 | 110 | ||
115 | return 1; | 111 | return 1; |
@@ -126,7 +122,6 @@ isdn_tty_readmodem(void) | |||
126 | int midx; | 122 | int midx; |
127 | int i; | 123 | int i; |
128 | int r; | 124 | int r; |
129 | struct tty_struct *tty; | ||
130 | modem_info *info; | 125 | modem_info *info; |
131 | 126 | ||
132 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) { | 127 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) { |
@@ -144,20 +139,21 @@ isdn_tty_readmodem(void) | |||
144 | if ((info->vonline & 1) && (info->emu.vpar[1])) | 139 | if ((info->vonline & 1) && (info->emu.vpar[1])) |
145 | isdn_audio_eval_silence(info); | 140 | isdn_audio_eval_silence(info); |
146 | #endif | 141 | #endif |
147 | tty = info->port.tty; | 142 | if (info->mcr & UART_MCR_RTS) { |
148 | if (tty) { | 143 | /* CISCO AsyncPPP Hack */ |
149 | if (info->mcr & UART_MCR_RTS) { | 144 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) |
150 | /* CISCO AsyncPPP Hack */ | 145 | r = isdn_readbchan_tty(info->isdn_driver, |
151 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) | 146 | info->isdn_channel, |
152 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); | 147 | &info->port, 0); |
153 | else | 148 | else |
154 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); | 149 | r = isdn_readbchan_tty(info->isdn_driver, |
155 | if (r) | 150 | info->isdn_channel, |
156 | tty_flip_buffer_push(tty); | 151 | &info->port, 1); |
157 | } else | 152 | if (r) |
158 | r = 1; | 153 | tty_flip_buffer_push(&info->port); |
159 | } else | 154 | } else |
160 | r = 1; | 155 | r = 1; |
156 | |||
161 | if (r) { | 157 | if (r) { |
162 | info->rcvsched = 0; | 158 | info->rcvsched = 0; |
163 | resched = 1; | 159 | resched = 1; |
@@ -2229,7 +2225,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) | |||
2229 | void | 2225 | void |
2230 | isdn_tty_at_cout(char *msg, modem_info *info) | 2226 | isdn_tty_at_cout(char *msg, modem_info *info) |
2231 | { | 2227 | { |
2232 | struct tty_struct *tty; | 2228 | struct tty_port *port = &info->port; |
2233 | atemu *m = &info->emu; | 2229 | atemu *m = &info->emu; |
2234 | char *p; | 2230 | char *p; |
2235 | char c; | 2231 | char c; |
@@ -2246,15 +2242,14 @@ isdn_tty_at_cout(char *msg, modem_info *info) | |||
2246 | l = strlen(msg); | 2242 | l = strlen(msg); |
2247 | 2243 | ||
2248 | spin_lock_irqsave(&info->readlock, flags); | 2244 | spin_lock_irqsave(&info->readlock, flags); |
2249 | tty = info->port.tty; | 2245 | if (port->flags & ASYNC_CLOSING) { |
2250 | if ((info->port.flags & ASYNC_CLOSING) || (!tty)) { | ||
2251 | spin_unlock_irqrestore(&info->readlock, flags); | 2246 | spin_unlock_irqrestore(&info->readlock, flags); |
2252 | return; | 2247 | return; |
2253 | } | 2248 | } |
2254 | 2249 | ||
2255 | /* use queue instead of direct, if online and */ | 2250 | /* use queue instead of direct, if online and */ |
2256 | /* data is in queue or buffer is full */ | 2251 | /* data is in queue or buffer is full */ |
2257 | if (info->online && ((tty_buffer_request_room(tty, l) < l) || | 2252 | if (info->online && ((tty_buffer_request_room(port, l) < l) || |
2258 | !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { | 2253 | !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { |
2259 | skb = alloc_skb(l, GFP_ATOMIC); | 2254 | skb = alloc_skb(l, GFP_ATOMIC); |
2260 | if (!skb) { | 2255 | if (!skb) { |
@@ -2285,7 +2280,7 @@ isdn_tty_at_cout(char *msg, modem_info *info) | |||
2285 | if (skb) { | 2280 | if (skb) { |
2286 | *sp++ = c; | 2281 | *sp++ = c; |
2287 | } else { | 2282 | } else { |
2288 | if (tty_insert_flip_char(tty, c, TTY_NORMAL) == 0) | 2283 | if (tty_insert_flip_char(port, c, TTY_NORMAL) == 0) |
2289 | break; | 2284 | break; |
2290 | } | 2285 | } |
2291 | } | 2286 | } |
@@ -2299,7 +2294,7 @@ isdn_tty_at_cout(char *msg, modem_info *info) | |||
2299 | 2294 | ||
2300 | } else { | 2295 | } else { |
2301 | spin_unlock_irqrestore(&info->readlock, flags); | 2296 | spin_unlock_irqrestore(&info->readlock, flags); |
2302 | tty_flip_buffer_push(tty); | 2297 | tty_flip_buffer_push(port); |
2303 | } | 2298 | } |
2304 | } | 2299 | } |
2305 | 2300 | ||
diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 6cdcdb0d3d58..89875ea19ade 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config LGUEST | 1 | config LGUEST |
2 | tristate "Linux hypervisor example code" | 2 | tristate "Linux hypervisor example code" |
3 | depends on X86_32 && EVENTFD | 3 | depends on X86_32 && EVENTFD && TTY |
4 | select HVC_DRIVER | 4 | select HVC_DRIVER |
5 | ---help--- | 5 | ---help--- |
6 | This is a very simple module which allows you to run | 6 | This is a very simple module which allows you to run |
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig index ea1e6545df36..f359be7e9dd9 100644 --- a/drivers/media/radio/wl128x/Kconfig +++ b/drivers/media/radio/wl128x/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | menu "Texas Instruments WL128x FM driver (ST based)" | 4 | menu "Texas Instruments WL128x FM driver (ST based)" |
5 | config RADIO_WL128X | 5 | config RADIO_WL128X |
6 | tristate "Texas Instruments WL128x FM Radio" | 6 | tristate "Texas Instruments WL128x FM Radio" |
7 | depends on VIDEO_V4L2 && RFKILL && GPIOLIB | 7 | depends on VIDEO_V4L2 && RFKILL && GPIOLIB && TTY |
8 | select TI_ST if NET | 8 | select TI_ST if NET |
9 | help | 9 | help |
10 | Choose Y here if you have this FM radio chip. | 10 | Choose Y here if you have this FM radio chip. |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 8f59d88897e7..668a5822ab4e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -127,7 +127,7 @@ config PHANTOM | |||
127 | 127 | ||
128 | config INTEL_MID_PTI | 128 | config INTEL_MID_PTI |
129 | tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" | 129 | tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" |
130 | depends on PCI | 130 | depends on PCI && TTY |
131 | default n | 131 | default n |
132 | help | 132 | help |
133 | The PTI (Parallel Trace Interface) driver directs | 133 | The PTI (Parallel Trace Interface) driver directs |
diff --git a/drivers/misc/ti-st/Kconfig b/drivers/misc/ti-st/Kconfig index abb5de1afce3..f34dcc514730 100644 --- a/drivers/misc/ti-st/Kconfig +++ b/drivers/misc/ti-st/Kconfig | |||
@@ -5,7 +5,7 @@ | |||
5 | menu "Texas Instruments shared transport line discipline" | 5 | menu "Texas Instruments shared transport line discipline" |
6 | config TI_ST | 6 | config TI_ST |
7 | tristate "Shared transport core driver" | 7 | tristate "Shared transport core driver" |
8 | depends on NET && GPIOLIB | 8 | depends on NET && GPIOLIB && TTY |
9 | select FW_LOADER | 9 | select FW_LOADER |
10 | help | 10 | help |
11 | This enables the shared transport core driver for TI | 11 | This enables the shared transport core driver for TI |
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index 3b1f783bf924..5562308699bc 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig | |||
@@ -52,6 +52,7 @@ config MMC_BLOCK_BOUNCE | |||
52 | 52 | ||
53 | config SDIO_UART | 53 | config SDIO_UART |
54 | tristate "SDIO UART/GPS class support" | 54 | tristate "SDIO UART/GPS class support" |
55 | depends on TTY | ||
55 | help | 56 | help |
56 | SDIO function driver for SDIO cards that implements the UART | 57 | SDIO function driver for SDIO cards that implements the UART |
57 | class, as well as the GPS class which appears like a UART. | 58 | class, as well as the GPS class which appears like a UART. |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index bd57a11acc79..c931dfe6a59c 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -381,7 +381,6 @@ static void sdio_uart_stop_rx(struct sdio_uart_port *port) | |||
381 | static void sdio_uart_receive_chars(struct sdio_uart_port *port, | 381 | static void sdio_uart_receive_chars(struct sdio_uart_port *port, |
382 | unsigned int *status) | 382 | unsigned int *status) |
383 | { | 383 | { |
384 | struct tty_struct *tty = tty_port_tty_get(&port->port); | ||
385 | unsigned int ch, flag; | 384 | unsigned int ch, flag; |
386 | int max_count = 256; | 385 | int max_count = 256; |
387 | 386 | ||
@@ -418,23 +417,19 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port, | |||
418 | } | 417 | } |
419 | 418 | ||
420 | if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) | 419 | if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) |
421 | if (tty) | 420 | tty_insert_flip_char(&port->port, ch, flag); |
422 | tty_insert_flip_char(tty, ch, flag); | ||
423 | 421 | ||
424 | /* | 422 | /* |
425 | * Overrun is special. Since it's reported immediately, | 423 | * Overrun is special. Since it's reported immediately, |
426 | * it doesn't affect the current character. | 424 | * it doesn't affect the current character. |
427 | */ | 425 | */ |
428 | if (*status & ~port->ignore_status_mask & UART_LSR_OE) | 426 | if (*status & ~port->ignore_status_mask & UART_LSR_OE) |
429 | if (tty) | 427 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
430 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
431 | 428 | ||
432 | *status = sdio_in(port, UART_LSR); | 429 | *status = sdio_in(port, UART_LSR); |
433 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 430 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
434 | if (tty) { | 431 | |
435 | tty_flip_buffer_push(tty); | 432 | tty_flip_buffer_push(&port->port); |
436 | tty_kref_put(tty); | ||
437 | } | ||
438 | } | 433 | } |
439 | 434 | ||
440 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) | 435 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) |
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig index abf4d7a9dcce..60c2142373c9 100644 --- a/drivers/net/caif/Kconfig +++ b/drivers/net/caif/Kconfig | |||
@@ -6,7 +6,7 @@ comment "CAIF transport drivers" | |||
6 | 6 | ||
7 | config CAIF_TTY | 7 | config CAIF_TTY |
8 | tristate "CAIF TTY transport driver" | 8 | tristate "CAIF TTY transport driver" |
9 | depends on CAIF | 9 | depends on CAIF && TTY |
10 | default n | 10 | default n |
11 | ---help--- | 11 | ---help--- |
12 | The CAIF TTY transport driver is a Line Discipline (ldisc) | 12 | The CAIF TTY transport driver is a Line Discipline (ldisc) |
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 5de74e762021..666891a9a248 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c | |||
@@ -91,7 +91,7 @@ static inline void update_tty_status(struct ser_device *ser) | |||
91 | ser->tty->hw_stopped << 4 | | 91 | ser->tty->hw_stopped << 4 | |
92 | ser->tty->flow_stopped << 3 | | 92 | ser->tty->flow_stopped << 3 | |
93 | ser->tty->packet << 2 | | 93 | ser->tty->packet << 2 | |
94 | ser->tty->low_latency << 1 | | 94 | ser->tty->port->low_latency << 1 | |
95 | ser->tty->warned; | 95 | ser->tty->warned; |
96 | } | 96 | } |
97 | static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) | 97 | static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) |
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 1cca19f1c490..9862b2e07644 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
@@ -11,6 +11,7 @@ config CAN_VCAN | |||
11 | 11 | ||
12 | config CAN_SLCAN | 12 | config CAN_SLCAN |
13 | tristate "Serial / USB serial CAN Adaptors (slcan)" | 13 | tristate "Serial / USB serial CAN Adaptors (slcan)" |
14 | depends on TTY | ||
14 | ---help--- | 15 | ---help--- |
15 | CAN driver for several 'low cost' CAN interfaces that are attached | 16 | CAN driver for several 'low cost' CAN interfaces that are attached |
16 | via serial lines or via USB-to-serial adapters using the LAWICEL | 17 | via serial lines or via USB-to-serial adapters using the LAWICEL |
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig index 95dbcfdf131d..bf5e59687680 100644 --- a/drivers/net/hamradio/Kconfig +++ b/drivers/net/hamradio/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config MKISS | 1 | config MKISS |
2 | tristate "Serial port KISS driver" | 2 | tristate "Serial port KISS driver" |
3 | depends on AX25 | 3 | depends on AX25 && TTY |
4 | select CRC16 | 4 | select CRC16 |
5 | ---help--- | 5 | ---help--- |
6 | KISS is a protocol used for the exchange of data between a computer | 6 | KISS is a protocol used for the exchange of data between a computer |
@@ -18,7 +18,7 @@ config MKISS | |||
18 | 18 | ||
19 | config 6PACK | 19 | config 6PACK |
20 | tristate "Serial port 6PACK driver" | 20 | tristate "Serial port 6PACK driver" |
21 | depends on AX25 | 21 | depends on AX25 && TTY |
22 | ---help--- | 22 | ---help--- |
23 | 6pack is a transmission protocol for the data exchange between your | 23 | 6pack is a transmission protocol for the data exchange between your |
24 | PC and your TNC (the Terminal Node Controller acts as a kind of | 24 | PC and your TNC (the Terminal Node Controller acts as a kind of |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 59e9d9e1fd0f..2a30193d0d50 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -5,7 +5,7 @@ comment "SIR device drivers" | |||
5 | 5 | ||
6 | config IRTTY_SIR | 6 | config IRTTY_SIR |
7 | tristate "IrTTY (uses Linux serial driver)" | 7 | tristate "IrTTY (uses Linux serial driver)" |
8 | depends on IRDA | 8 | depends on IRDA && TTY |
9 | help | 9 | help |
10 | Say Y here if you want to build support for the IrTTY line | 10 | Say Y here if you want to build support for the IrTTY line |
11 | discipline. To compile it as a module, choose M here: the module | 11 | discipline. To compile it as a module, choose M here: the module |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 6e4d4b62c9a8..a41267197839 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -210,7 +210,7 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t | |||
210 | * been received, which can now be decapsulated and delivered for | 210 | * been received, which can now be decapsulated and delivered for |
211 | * further processing | 211 | * further processing |
212 | * | 212 | * |
213 | * calling context depends on underlying driver and tty->low_latency! | 213 | * calling context depends on underlying driver and tty->port->low_latency! |
214 | * for example (low_latency: 1 / 0): | 214 | * for example (low_latency: 1 / 0): |
215 | * serial.c: uart-interrupt / softint | 215 | * serial.c: uart-interrupt / softint |
216 | * usbserial: urb-complete-interrupt / softint | 216 | * usbserial: urb-complete-interrupt / softint |
diff --git a/drivers/net/ppp/Kconfig b/drivers/net/ppp/Kconfig index 278dea0c4c98..1373c6d7278d 100644 --- a/drivers/net/ppp/Kconfig +++ b/drivers/net/ppp/Kconfig | |||
@@ -147,6 +147,7 @@ config PPPOL2TP | |||
147 | Support for PPP-over-L2TP socket family. L2TP is a protocol | 147 | Support for PPP-over-L2TP socket family. L2TP is a protocol |
148 | used by ISPs and enterprises to tunnel PPP traffic over UDP | 148 | used by ISPs and enterprises to tunnel PPP traffic over UDP |
149 | tunnels. L2TP is replacing PPTP for VPN uses. | 149 | tunnels. L2TP is replacing PPTP for VPN uses. |
150 | if TTY | ||
150 | 151 | ||
151 | config PPP_ASYNC | 152 | config PPP_ASYNC |
152 | tristate "PPP support for async serial ports" | 153 | tristate "PPP support for async serial ports" |
@@ -172,4 +173,6 @@ config PPP_SYNC_TTY | |||
172 | 173 | ||
173 | To compile this driver as a module, choose M here. | 174 | To compile this driver as a module, choose M here. |
174 | 175 | ||
176 | endif # TTY | ||
177 | |||
175 | endif # PPP | 178 | endif # PPP |
diff --git a/drivers/net/slip/Kconfig b/drivers/net/slip/Kconfig index 211b160e4e9c..48e68714eef3 100644 --- a/drivers/net/slip/Kconfig +++ b/drivers/net/slip/Kconfig | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | config SLIP | 5 | config SLIP |
6 | tristate "SLIP (serial line) support" | 6 | tristate "SLIP (serial line) support" |
7 | depends on TTY | ||
7 | ---help--- | 8 | ---help--- |
8 | Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to | 9 | Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to |
9 | connect to your Internet service provider or to connect to some | 10 | connect to your Internet service provider or to connect to some |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 3a44a5d7bf9e..da92ed3797aa 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -443,7 +443,7 @@ config USB_NET_QMI_WWAN | |||
443 | 443 | ||
444 | config USB_HSO | 444 | config USB_HSO |
445 | tristate "Option USB High Speed Mobile Devices" | 445 | tristate "Option USB High Speed Mobile Devices" |
446 | depends on USB && RFKILL | 446 | depends on USB && RFKILL && TTY |
447 | default n | 447 | default n |
448 | help | 448 | help |
449 | Choose this option if you have an Option HSDPA/HSUPA card. | 449 | Choose this option if you have an Option HSDPA/HSUPA card. |
@@ -491,7 +491,7 @@ config USB_SIERRA_NET | |||
491 | 491 | ||
492 | config USB_VL600 | 492 | config USB_VL600 |
493 | tristate "LG VL600 modem dongle" | 493 | tristate "LG VL600 modem dongle" |
494 | depends on USB_NET_CDCETHER | 494 | depends on USB_NET_CDCETHER && TTY |
495 | select USB_ACM | 495 | select USB_ACM |
496 | help | 496 | help |
497 | Select this if you want to use an LG Electronics 4G/LTE usb modem | 497 | Select this if you want to use an LG Electronics 4G/LTE usb modem |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 41e5dfb5ee64..e2dd3249b6bd 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -2035,25 +2035,23 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) | |||
2035 | tty = tty_port_tty_get(&serial->port); | 2035 | tty = tty_port_tty_get(&serial->port); |
2036 | 2036 | ||
2037 | /* Push data to tty */ | 2037 | /* Push data to tty */ |
2038 | if (tty) { | 2038 | write_length_remaining = urb->actual_length - |
2039 | write_length_remaining = urb->actual_length - | 2039 | serial->curr_rx_urb_offset; |
2040 | serial->curr_rx_urb_offset; | 2040 | D1("data to push to tty"); |
2041 | D1("data to push to tty"); | 2041 | while (write_length_remaining) { |
2042 | while (write_length_remaining) { | 2042 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { |
2043 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 2043 | tty_kref_put(tty); |
2044 | tty_kref_put(tty); | 2044 | return -1; |
2045 | return -1; | ||
2046 | } | ||
2047 | curr_write_len = tty_insert_flip_string | ||
2048 | (tty, urb->transfer_buffer + | ||
2049 | serial->curr_rx_urb_offset, | ||
2050 | write_length_remaining); | ||
2051 | serial->curr_rx_urb_offset += curr_write_len; | ||
2052 | write_length_remaining -= curr_write_len; | ||
2053 | tty_flip_buffer_push(tty); | ||
2054 | } | 2045 | } |
2055 | tty_kref_put(tty); | 2046 | curr_write_len = tty_insert_flip_string(&serial->port, |
2047 | urb->transfer_buffer + serial->curr_rx_urb_offset, | ||
2048 | write_length_remaining); | ||
2049 | serial->curr_rx_urb_offset += curr_write_len; | ||
2050 | write_length_remaining -= curr_write_len; | ||
2051 | tty_flip_buffer_push(&serial->port); | ||
2056 | } | 2052 | } |
2053 | tty_kref_put(tty); | ||
2054 | |||
2057 | if (write_length_remaining == 0) { | 2055 | if (write_length_remaining == 0) { |
2058 | serial->curr_rx_urb_offset = 0; | 2056 | serial->curr_rx_urb_offset = 0; |
2059 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; | 2057 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; |
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 13daec88d918..94e234975c61 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig | |||
@@ -375,7 +375,7 @@ config LAPBETHER | |||
375 | 375 | ||
376 | config X25_ASY | 376 | config X25_ASY |
377 | tristate "X.25 async driver" | 377 | tristate "X.25 async driver" |
378 | depends on LAPB && X25 | 378 | depends on LAPB && X25 && TTY |
379 | ---help--- | 379 | ---help--- |
380 | Send and receive X.25 frames over regular asynchronous serial | 380 | Send and receive X.25 frames over regular asynchronous serial |
381 | lines such as telephone lines equipped with ordinary modems. | 381 | lines such as telephone lines equipped with ordinary modems. |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index ef6169adb845..1b8bdb7e9bf4 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -63,6 +63,7 @@ enum parport_pc_pci_cards { | |||
63 | timedia_9079b, | 63 | timedia_9079b, |
64 | timedia_9079c, | 64 | timedia_9079c, |
65 | wch_ch353_2s1p, | 65 | wch_ch353_2s1p, |
66 | sunix_2s1p, | ||
66 | }; | 67 | }; |
67 | 68 | ||
68 | /* each element directly indexed from enum list, above */ | 69 | /* each element directly indexed from enum list, above */ |
@@ -148,8 +149,12 @@ static struct parport_pc_pci cards[] = { | |||
148 | /* timedia_9079b */ { 1, { { 2, 3 }, } }, | 149 | /* timedia_9079b */ { 1, { { 2, 3 }, } }, |
149 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, | 150 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, |
150 | /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, | 151 | /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, |
152 | /* sunix_2s1p */ { 1, { { 3, -1 }, } }, | ||
151 | }; | 153 | }; |
152 | 154 | ||
155 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 | ||
156 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 | ||
157 | |||
153 | static struct pci_device_id parport_serial_pci_tbl[] = { | 158 | static struct pci_device_id parport_serial_pci_tbl[] = { |
154 | /* PCI cards */ | 159 | /* PCI cards */ |
155 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L, | 160 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L, |
@@ -246,8 +251,18 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
246 | { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, | 251 | { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, |
247 | { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, | 252 | { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, |
248 | { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, | 253 | { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, |
254 | |||
249 | /* WCH CARDS */ | 255 | /* WCH CARDS */ |
250 | { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, | 256 | { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, |
257 | |||
258 | /* | ||
259 | * More SUNIX variations. At least one of these has part number | ||
260 | * '5079A but subdevice 0x102. That board reports 0x0708 as | ||
261 | * its PCI Class. | ||
262 | */ | ||
263 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, | ||
264 | 0x0102, 0, 0, sunix_2s1p }, | ||
265 | |||
251 | { 0, } /* terminate list */ | 266 | { 0, } /* terminate list */ |
252 | }; | 267 | }; |
253 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); | 268 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); |
@@ -470,6 +485,12 @@ static struct pciserial_board pci_parport_serial_boards[] = { | |||
470 | .base_baud = 115200, | 485 | .base_baud = 115200, |
471 | .uart_offset = 8, | 486 | .uart_offset = 8, |
472 | }, | 487 | }, |
488 | [sunix_2s1p] = { | ||
489 | .flags = FL_BASE0|FL_BASE_BARS, | ||
490 | .num_ports = 2, | ||
491 | .base_baud = 921600, | ||
492 | .uart_offset = 8, | ||
493 | }, | ||
473 | }; | 494 | }; |
474 | 495 | ||
475 | struct parport_serial_private { | 496 | struct parport_serial_private { |
diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig index 445197d4a8c4..6efd9b60d8ff 100644 --- a/drivers/pps/clients/Kconfig +++ b/drivers/pps/clients/Kconfig | |||
@@ -17,7 +17,7 @@ config PPS_CLIENT_KTIMER | |||
17 | 17 | ||
18 | config PPS_CLIENT_LDISC | 18 | config PPS_CLIENT_LDISC |
19 | tristate "PPS line discipline" | 19 | tristate "PPS line discipline" |
20 | depends on PPS | 20 | depends on PPS && TTY |
21 | help | 21 | help |
22 | If you say yes here you get support for a PPS source connected | 22 | If you say yes here you get support for a PPS source connected |
23 | with the CD (Carrier Detect) pin of your serial port. | 23 | with the CD (Carrier Detect) pin of your serial port. |
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c index 79451f2dea6a..73bd3bb4d93b 100644 --- a/drivers/pps/clients/pps-ldisc.c +++ b/drivers/pps/clients/pps-ldisc.c | |||
@@ -25,18 +25,27 @@ | |||
25 | #include <linux/serial_core.h> | 25 | #include <linux/serial_core.h> |
26 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
27 | #include <linux/pps_kernel.h> | 27 | #include <linux/pps_kernel.h> |
28 | #include <linux/bug.h> | ||
28 | 29 | ||
29 | #define PPS_TTY_MAGIC 0x0001 | 30 | #define PPS_TTY_MAGIC 0x0001 |
30 | 31 | ||
31 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, | 32 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status) |
32 | struct pps_event_time *ts) | ||
33 | { | 33 | { |
34 | struct pps_device *pps = (struct pps_device *)tty->disc_data; | 34 | struct pps_device *pps; |
35 | struct pps_event_time ts; | ||
36 | |||
37 | pps_get_ts(&ts); | ||
35 | 38 | ||
36 | BUG_ON(pps == NULL); | 39 | pps = pps_lookup_dev(tty); |
40 | /* | ||
41 | * This should never fail, but the ldisc locking is very | ||
42 | * convoluted, so don't crash just in case. | ||
43 | */ | ||
44 | if (WARN_ON_ONCE(pps == NULL)) | ||
45 | return; | ||
37 | 46 | ||
38 | /* Now do the PPS event report */ | 47 | /* Now do the PPS event report */ |
39 | pps_event(pps, ts, status ? PPS_CAPTUREASSERT : | 48 | pps_event(pps, &ts, status ? PPS_CAPTUREASSERT : |
40 | PPS_CAPTURECLEAR, NULL); | 49 | PPS_CAPTURECLEAR, NULL); |
41 | 50 | ||
42 | dev_dbg(pps->dev, "PPS %s at %lu\n", | 51 | dev_dbg(pps->dev, "PPS %s at %lu\n", |
@@ -67,9 +76,9 @@ static int pps_tty_open(struct tty_struct *tty) | |||
67 | pr_err("cannot register PPS source \"%s\"\n", info.path); | 76 | pr_err("cannot register PPS source \"%s\"\n", info.path); |
68 | return -ENOMEM; | 77 | return -ENOMEM; |
69 | } | 78 | } |
70 | tty->disc_data = pps; | 79 | pps->lookup_cookie = tty; |
71 | 80 | ||
72 | /* Should open N_TTY ldisc too */ | 81 | /* Now open the base class N_TTY ldisc */ |
73 | ret = alias_n_tty_open(tty); | 82 | ret = alias_n_tty_open(tty); |
74 | if (ret < 0) { | 83 | if (ret < 0) { |
75 | pr_err("cannot open tty ldisc \"%s\"\n", info.path); | 84 | pr_err("cannot open tty ldisc \"%s\"\n", info.path); |
@@ -81,7 +90,6 @@ static int pps_tty_open(struct tty_struct *tty) | |||
81 | return 0; | 90 | return 0; |
82 | 91 | ||
83 | err_unregister: | 92 | err_unregister: |
84 | tty->disc_data = NULL; | ||
85 | pps_unregister_source(pps); | 93 | pps_unregister_source(pps); |
86 | return ret; | 94 | return ret; |
87 | } | 95 | } |
@@ -90,11 +98,13 @@ static void (*alias_n_tty_close)(struct tty_struct *tty); | |||
90 | 98 | ||
91 | static void pps_tty_close(struct tty_struct *tty) | 99 | static void pps_tty_close(struct tty_struct *tty) |
92 | { | 100 | { |
93 | struct pps_device *pps = (struct pps_device *)tty->disc_data; | 101 | struct pps_device *pps = pps_lookup_dev(tty); |
94 | 102 | ||
95 | alias_n_tty_close(tty); | 103 | alias_n_tty_close(tty); |
96 | 104 | ||
97 | tty->disc_data = NULL; | 105 | if (WARN_ON(!pps)) |
106 | return; | ||
107 | |||
98 | dev_info(pps->dev, "removed\n"); | 108 | dev_info(pps->dev, "removed\n"); |
99 | pps_unregister_source(pps); | 109 | pps_unregister_source(pps); |
100 | } | 110 | } |
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 2420d5af0583..6437703eb10f 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c | |||
@@ -247,12 +247,15 @@ static int pps_cdev_open(struct inode *inode, struct file *file) | |||
247 | struct pps_device *pps = container_of(inode->i_cdev, | 247 | struct pps_device *pps = container_of(inode->i_cdev, |
248 | struct pps_device, cdev); | 248 | struct pps_device, cdev); |
249 | file->private_data = pps; | 249 | file->private_data = pps; |
250 | 250 | kobject_get(&pps->dev->kobj); | |
251 | return 0; | 251 | return 0; |
252 | } | 252 | } |
253 | 253 | ||
254 | static int pps_cdev_release(struct inode *inode, struct file *file) | 254 | static int pps_cdev_release(struct inode *inode, struct file *file) |
255 | { | 255 | { |
256 | struct pps_device *pps = container_of(inode->i_cdev, | ||
257 | struct pps_device, cdev); | ||
258 | kobject_put(&pps->dev->kobj); | ||
256 | return 0; | 259 | return 0; |
257 | } | 260 | } |
258 | 261 | ||
@@ -274,8 +277,10 @@ static void pps_device_destruct(struct device *dev) | |||
274 | { | 277 | { |
275 | struct pps_device *pps = dev_get_drvdata(dev); | 278 | struct pps_device *pps = dev_get_drvdata(dev); |
276 | 279 | ||
277 | /* release id here to protect others from using it while it's | 280 | cdev_del(&pps->cdev); |
278 | * still in use */ | 281 | |
282 | /* Now we can release the ID for re-use */ | ||
283 | pr_debug("deallocating pps%d\n", pps->id); | ||
279 | mutex_lock(&pps_idr_lock); | 284 | mutex_lock(&pps_idr_lock); |
280 | idr_remove(&pps_idr, pps->id); | 285 | idr_remove(&pps_idr, pps->id); |
281 | mutex_unlock(&pps_idr_lock); | 286 | mutex_unlock(&pps_idr_lock); |
@@ -332,6 +337,7 @@ int pps_register_cdev(struct pps_device *pps) | |||
332 | goto del_cdev; | 337 | goto del_cdev; |
333 | } | 338 | } |
334 | 339 | ||
340 | /* Override the release function with our own */ | ||
335 | pps->dev->release = pps_device_destruct; | 341 | pps->dev->release = pps_device_destruct; |
336 | 342 | ||
337 | pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, | 343 | pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, |
@@ -352,11 +358,44 @@ free_idr: | |||
352 | 358 | ||
353 | void pps_unregister_cdev(struct pps_device *pps) | 359 | void pps_unregister_cdev(struct pps_device *pps) |
354 | { | 360 | { |
361 | pr_debug("unregistering pps%d\n", pps->id); | ||
362 | pps->lookup_cookie = NULL; | ||
355 | device_destroy(pps_class, pps->dev->devt); | 363 | device_destroy(pps_class, pps->dev->devt); |
356 | cdev_del(&pps->cdev); | ||
357 | } | 364 | } |
358 | 365 | ||
359 | /* | 366 | /* |
367 | * Look up a pps device by magic cookie. | ||
368 | * The cookie is usually a pointer to some enclosing device, but this | ||
369 | * code doesn't care; you should never be dereferencing it. | ||
370 | * | ||
371 | * This is a bit of a kludge that is currently used only by the PPS | ||
372 | * serial line discipline. It may need to be tweaked when a second user | ||
373 | * is found. | ||
374 | * | ||
375 | * There is no function interface for setting the lookup_cookie field. | ||
376 | * It's initialized to NULL when the pps device is created, and if a | ||
377 | * client wants to use it, just fill it in afterward. | ||
378 | * | ||
379 | * The cookie is automatically set to NULL in pps_unregister_source() | ||
380 | * so that it will not be used again, even if the pps device cannot | ||
381 | * be removed from the idr due to pending references holding the minor | ||
382 | * number in use. | ||
383 | */ | ||
384 | struct pps_device *pps_lookup_dev(void const *cookie) | ||
385 | { | ||
386 | struct pps_device *pps; | ||
387 | unsigned id; | ||
388 | |||
389 | rcu_read_lock(); | ||
390 | idr_for_each_entry(&pps_idr, pps, id) | ||
391 | if (cookie == pps->lookup_cookie) | ||
392 | break; | ||
393 | rcu_read_unlock(); | ||
394 | return pps; | ||
395 | } | ||
396 | EXPORT_SYMBOL(pps_lookup_dev); | ||
397 | |||
398 | /* | ||
360 | * Module stuff | 399 | * Module stuff |
361 | */ | 400 | */ |
362 | 401 | ||
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig index 2c9a776bd63c..71bf959732fe 100644 --- a/drivers/s390/char/Kconfig +++ b/drivers/s390/char/Kconfig | |||
@@ -11,7 +11,7 @@ config TN3270 | |||
11 | config TN3270_TTY | 11 | config TN3270_TTY |
12 | def_tristate y | 12 | def_tristate y |
13 | prompt "Support for tty input/output on 3270 terminals" | 13 | prompt "Support for tty input/output on 3270 terminals" |
14 | depends on TN3270 | 14 | depends on TN3270 && TTY |
15 | help | 15 | help |
16 | Include support for using an IBM 3270 terminal as a Linux tty. | 16 | Include support for using an IBM 3270 terminal as a Linux tty. |
17 | 17 | ||
@@ -33,7 +33,7 @@ config TN3270_CONSOLE | |||
33 | config TN3215 | 33 | config TN3215 |
34 | def_bool y | 34 | def_bool y |
35 | prompt "Support for 3215 line mode terminal" | 35 | prompt "Support for 3215 line mode terminal" |
36 | depends on CCW | 36 | depends on CCW && TTY |
37 | help | 37 | help |
38 | Include support for IBM 3215 line-mode terminals. | 38 | Include support for IBM 3215 line-mode terminals. |
39 | 39 | ||
@@ -51,7 +51,7 @@ config CCW_CONSOLE | |||
51 | config SCLP_TTY | 51 | config SCLP_TTY |
52 | def_bool y | 52 | def_bool y |
53 | prompt "Support for SCLP line mode terminal" | 53 | prompt "Support for SCLP line mode terminal" |
54 | depends on S390 | 54 | depends on S390 && TTY |
55 | help | 55 | help |
56 | Include support for IBM SCLP line-mode terminals. | 56 | Include support for IBM SCLP line-mode terminals. |
57 | 57 | ||
@@ -66,7 +66,7 @@ config SCLP_CONSOLE | |||
66 | config SCLP_VT220_TTY | 66 | config SCLP_VT220_TTY |
67 | def_bool y | 67 | def_bool y |
68 | prompt "Support for SCLP VT220-compatible terminal" | 68 | prompt "Support for SCLP VT220-compatible terminal" |
69 | depends on S390 | 69 | depends on S390 && TTY |
70 | help | 70 | help |
71 | Include support for an IBM SCLP VT220-compatible terminal. | 71 | Include support for an IBM SCLP VT220-compatible terminal. |
72 | 72 | ||
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 33b7141a182f..7b00fa634d40 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -412,8 +412,9 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm, | |||
412 | break; | 412 | break; |
413 | 413 | ||
414 | case CTRLCHAR_CTRL: | 414 | case CTRLCHAR_CTRL: |
415 | tty_insert_flip_char(tty, cchar, TTY_NORMAL); | 415 | tty_insert_flip_char(&raw->port, cchar, |
416 | tty_flip_buffer_push(tty); | 416 | TTY_NORMAL); |
417 | tty_flip_buffer_push(&raw->port); | ||
417 | break; | 418 | break; |
418 | 419 | ||
419 | case CTRLCHAR_NONE: | 420 | case CTRLCHAR_NONE: |
@@ -425,8 +426,9 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm, | |||
425 | count++; | 426 | count++; |
426 | } else | 427 | } else |
427 | count -= 2; | 428 | count -= 2; |
428 | tty_insert_flip_string(tty, raw->inbuf, count); | 429 | tty_insert_flip_string(&raw->port, raw->inbuf, |
429 | tty_flip_buffer_push(tty); | 430 | count); |
431 | tty_flip_buffer_push(&raw->port); | ||
430 | break; | 432 | break; |
431 | } | 433 | } |
432 | } else if (req->type == RAW3215_WRITE) { | 434 | } else if (req->type == RAW3215_WRITE) { |
@@ -970,7 +972,7 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp) | |||
970 | 972 | ||
971 | tty_port_tty_set(&raw->port, tty); | 973 | tty_port_tty_set(&raw->port, tty); |
972 | 974 | ||
973 | tty->low_latency = 0; /* don't use bottom half for pushing chars */ | 975 | raw->port.low_latency = 0; /* don't use bottom half for pushing chars */ |
974 | /* | 976 | /* |
975 | * Start up 3215 device | 977 | * Start up 3215 device |
976 | */ | 978 | */ |
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h index d0ae2be58191..a31f339211d5 100644 --- a/drivers/s390/char/keyboard.h +++ b/drivers/s390/char/keyboard.h | |||
@@ -43,22 +43,14 @@ int kbd_ioctl(struct kbd_data *, unsigned int, unsigned long); | |||
43 | static inline void | 43 | static inline void |
44 | kbd_put_queue(struct tty_port *port, int ch) | 44 | kbd_put_queue(struct tty_port *port, int ch) |
45 | { | 45 | { |
46 | struct tty_struct *tty = tty_port_tty_get(port); | 46 | tty_insert_flip_char(port, ch, 0); |
47 | if (!tty) | 47 | tty_schedule_flip(port); |
48 | return; | ||
49 | tty_insert_flip_char(tty, ch, 0); | ||
50 | tty_schedule_flip(tty); | ||
51 | tty_kref_put(tty); | ||
52 | } | 48 | } |
53 | 49 | ||
54 | static inline void | 50 | static inline void |
55 | kbd_puts_queue(struct tty_port *port, char *cp) | 51 | kbd_puts_queue(struct tty_port *port, char *cp) |
56 | { | 52 | { |
57 | struct tty_struct *tty = tty_port_tty_get(port); | ||
58 | if (!tty) | ||
59 | return; | ||
60 | while (*cp) | 53 | while (*cp) |
61 | tty_insert_flip_char(tty, *cp++, 0); | 54 | tty_insert_flip_char(port, *cp++, 0); |
62 | tty_schedule_flip(tty); | 55 | tty_schedule_flip(port); |
63 | tty_kref_put(tty); | ||
64 | } | 56 | } |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 877fbc37c1e7..14b4cb8abcc8 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
@@ -65,7 +65,7 @@ sclp_tty_open(struct tty_struct *tty, struct file *filp) | |||
65 | { | 65 | { |
66 | tty_port_tty_set(&sclp_port, tty); | 66 | tty_port_tty_set(&sclp_port, tty); |
67 | tty->driver_data = NULL; | 67 | tty->driver_data = NULL; |
68 | tty->low_latency = 0; | 68 | sclp_port.low_latency = 0; |
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | 71 | ||
@@ -342,8 +342,8 @@ sclp_tty_input(unsigned char* buf, unsigned int count) | |||
342 | case CTRLCHAR_SYSRQ: | 342 | case CTRLCHAR_SYSRQ: |
343 | break; | 343 | break; |
344 | case CTRLCHAR_CTRL: | 344 | case CTRLCHAR_CTRL: |
345 | tty_insert_flip_char(tty, cchar, TTY_NORMAL); | 345 | tty_insert_flip_char(&sclp_port, cchar, TTY_NORMAL); |
346 | tty_flip_buffer_push(tty); | 346 | tty_flip_buffer_push(&sclp_port); |
347 | break; | 347 | break; |
348 | case CTRLCHAR_NONE: | 348 | case CTRLCHAR_NONE: |
349 | /* send (normal) input to line discipline */ | 349 | /* send (normal) input to line discipline */ |
@@ -351,11 +351,11 @@ sclp_tty_input(unsigned char* buf, unsigned int count) | |||
351 | (strncmp((const char *) buf + count - 2, "^n", 2) && | 351 | (strncmp((const char *) buf + count - 2, "^n", 2) && |
352 | strncmp((const char *) buf + count - 2, "\252n", 2))) { | 352 | strncmp((const char *) buf + count - 2, "\252n", 2))) { |
353 | /* add the auto \n */ | 353 | /* add the auto \n */ |
354 | tty_insert_flip_string(tty, buf, count); | 354 | tty_insert_flip_string(&sclp_port, buf, count); |
355 | tty_insert_flip_char(tty, '\n', TTY_NORMAL); | 355 | tty_insert_flip_char(&sclp_port, '\n', TTY_NORMAL); |
356 | } else | 356 | } else |
357 | tty_insert_flip_string(tty, buf, count - 2); | 357 | tty_insert_flip_string(&sclp_port, buf, count - 2); |
358 | tty_flip_buffer_push(tty); | 358 | tty_flip_buffer_push(&sclp_port); |
359 | break; | 359 | break; |
360 | } | 360 | } |
361 | tty_kref_put(tty); | 361 | tty_kref_put(tty); |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index effcc8756e0a..6c92f62623be 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -461,14 +461,9 @@ sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
461 | static void | 461 | static void |
462 | sclp_vt220_receiver_fn(struct evbuf_header *evbuf) | 462 | sclp_vt220_receiver_fn(struct evbuf_header *evbuf) |
463 | { | 463 | { |
464 | struct tty_struct *tty = tty_port_tty_get(&sclp_vt220_port); | ||
465 | char *buffer; | 464 | char *buffer; |
466 | unsigned int count; | 465 | unsigned int count; |
467 | 466 | ||
468 | /* Ignore input if device is not open */ | ||
469 | if (tty == NULL) | ||
470 | return; | ||
471 | |||
472 | buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header)); | 467 | buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header)); |
473 | count = evbuf->length - sizeof(struct evbuf_header); | 468 | count = evbuf->length - sizeof(struct evbuf_header); |
474 | 469 | ||
@@ -480,11 +475,10 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf) | |||
480 | /* Send input to line discipline */ | 475 | /* Send input to line discipline */ |
481 | buffer++; | 476 | buffer++; |
482 | count--; | 477 | count--; |
483 | tty_insert_flip_string(tty, buffer, count); | 478 | tty_insert_flip_string(&sclp_vt220_port, buffer, count); |
484 | tty_flip_buffer_push(tty); | 479 | tty_flip_buffer_push(&sclp_vt220_port); |
485 | break; | 480 | break; |
486 | } | 481 | } |
487 | tty_kref_put(tty); | ||
488 | } | 482 | } |
489 | 483 | ||
490 | /* | 484 | /* |
@@ -495,7 +489,7 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp) | |||
495 | { | 489 | { |
496 | if (tty->count == 1) { | 490 | if (tty->count == 1) { |
497 | tty_port_tty_set(&sclp_vt220_port, tty); | 491 | tty_port_tty_set(&sclp_vt220_port, tty); |
498 | tty->low_latency = 0; | 492 | sclp_vt220_port.low_latency = 0; |
499 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | 493 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { |
500 | tty->winsize.ws_row = 24; | 494 | tty->winsize.ws_row = 24; |
501 | tty->winsize.ws_col = 80; | 495 | tty->winsize.ws_col = 80; |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 43ea0593bdb0..3860e796b65f 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
@@ -860,7 +860,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) | |||
860 | tty->driver_data = tp; | 860 | tty->driver_data = tp; |
861 | tty->winsize.ws_row = tp->view.rows - 2; | 861 | tty->winsize.ws_row = tp->view.rows - 2; |
862 | tty->winsize.ws_col = tp->view.cols; | 862 | tty->winsize.ws_col = tp->view.cols; |
863 | tty->low_latency = 0; | 863 | tp->port.low_latency = 0; |
864 | /* why to reassign? */ | 864 | /* why to reassign? */ |
865 | tty_port_tty_set(&tp->port, tty); | 865 | tty_port_tty_set(&tp->port, tty); |
866 | tp->inattr = TF_INPUT; | 866 | tp->inattr = TF_INPUT; |
@@ -893,7 +893,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) | |||
893 | } | 893 | } |
894 | 894 | ||
895 | tty_port_tty_set(&tp->port, tty); | 895 | tty_port_tty_set(&tp->port, tty); |
896 | tty->low_latency = 0; | 896 | tp->port.low_latency = 0; |
897 | tty->winsize.ws_row = tp->view.rows - 2; | 897 | tty->winsize.ws_row = tp->view.rows - 2; |
898 | tty->winsize.ws_col = tp->view.cols; | 898 | tty->winsize.ws_col = tp->view.cols; |
899 | 899 | ||
diff --git a/drivers/staging/ccg/Kconfig b/drivers/staging/ccg/Kconfig index 8997a8c757aa..7ed5bc6caadb 100644 --- a/drivers/staging/ccg/Kconfig +++ b/drivers/staging/ccg/Kconfig | |||
@@ -2,7 +2,7 @@ if USB_GADGET | |||
2 | 2 | ||
3 | config USB_G_CCG | 3 | config USB_G_CCG |
4 | tristate "Configurable Composite Gadget (STAGING)" | 4 | tristate "Configurable Composite Gadget (STAGING)" |
5 | depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM | 5 | depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM && TTY |
6 | help | 6 | help |
7 | The Configurable Composite Gadget supports multiple USB | 7 | The Configurable Composite Gadget supports multiple USB |
8 | functions: acm, mass storage, rndis and FunctionFS. | 8 | functions: acm, mass storage, rndis and FunctionFS. |
diff --git a/drivers/staging/ccg/u_serial.c b/drivers/staging/ccg/u_serial.c index 373c40656b52..b10947ae0ac5 100644 --- a/drivers/staging/ccg/u_serial.c +++ b/drivers/staging/ccg/u_serial.c | |||
@@ -491,12 +491,8 @@ static void gs_rx_push(unsigned long _port) | |||
491 | 491 | ||
492 | req = list_first_entry(queue, struct usb_request, list); | 492 | req = list_first_entry(queue, struct usb_request, list); |
493 | 493 | ||
494 | /* discard data if tty was closed */ | ||
495 | if (!tty) | ||
496 | goto recycle; | ||
497 | |||
498 | /* leave data queued if tty was rx throttled */ | 494 | /* leave data queued if tty was rx throttled */ |
499 | if (test_bit(TTY_THROTTLED, &tty->flags)) | 495 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) |
500 | break; | 496 | break; |
501 | 497 | ||
502 | switch (req->status) { | 498 | switch (req->status) { |
@@ -529,7 +525,7 @@ static void gs_rx_push(unsigned long _port) | |||
529 | size -= n; | 525 | size -= n; |
530 | } | 526 | } |
531 | 527 | ||
532 | count = tty_insert_flip_string(tty, packet, size); | 528 | count = tty_insert_flip_string(&port->port, packet, size); |
533 | if (count) | 529 | if (count) |
534 | do_push = true; | 530 | do_push = true; |
535 | if (count != size) { | 531 | if (count != size) { |
@@ -542,7 +538,6 @@ static void gs_rx_push(unsigned long _port) | |||
542 | } | 538 | } |
543 | port->n_read = 0; | 539 | port->n_read = 0; |
544 | } | 540 | } |
545 | recycle: | ||
546 | list_move(&req->list, &port->read_pool); | 541 | list_move(&req->list, &port->read_pool); |
547 | port->read_started--; | 542 | port->read_started--; |
548 | } | 543 | } |
@@ -550,8 +545,8 @@ recycle: | |||
550 | /* Push from tty to ldisc; without low_latency set this is handled by | 545 | /* Push from tty to ldisc; without low_latency set this is handled by |
551 | * a workqueue, so we won't get callbacks and can hold port_lock | 546 | * a workqueue, so we won't get callbacks and can hold port_lock |
552 | */ | 547 | */ |
553 | if (tty && do_push) | 548 | if (do_push) |
554 | tty_flip_buffer_push(tty); | 549 | tty_flip_buffer_push(&port->port); |
555 | 550 | ||
556 | 551 | ||
557 | /* We want our data queue to become empty ASAP, keeping data | 552 | /* We want our data queue to become empty ASAP, keeping data |
diff --git a/drivers/staging/dgrp/Kconfig b/drivers/staging/dgrp/Kconfig index 39f4bb65ec83..e4c41552923a 100644 --- a/drivers/staging/dgrp/Kconfig +++ b/drivers/staging/dgrp/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | config DGRP | 1 | config DGRP |
2 | tristate "Digi Realport driver" | 2 | tristate "Digi Realport driver" |
3 | default n | 3 | default n |
4 | depends on SYSFS | 4 | depends on SYSFS && TTY |
5 | ---help--- | 5 | ---help--- |
6 | Support for Digi Realport devices. These devices allow you to | 6 | Support for Digi Realport devices. These devices allow you to |
7 | access remote serial ports as if they are local tty devices. This | 7 | access remote serial ports as if they are local tty devices. This |
diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 2d1bbfd5b67c..e6018823b9de 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/types.h> | 38 | #include <linux/types.h> |
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/device.h> | ||
40 | #include <linux/tty.h> | 41 | #include <linux/tty.h> |
41 | #include <linux/tty_flip.h> | 42 | #include <linux/tty_flip.h> |
42 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
@@ -211,7 +212,7 @@ static void dgrp_input(struct ch_struct *ch) | |||
211 | data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; | 212 | data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; |
212 | 213 | ||
213 | /* len is the amount of data we are going to transfer here */ | 214 | /* len is the amount of data we are going to transfer here */ |
214 | len = tty_buffer_request_room(tty, data_len); | 215 | len = tty_buffer_request_room(&ch->port, data_len); |
215 | 216 | ||
216 | /* Check DPA flow control */ | 217 | /* Check DPA flow control */ |
217 | if ((nd->nd_dpa_debug) && | 218 | if ((nd->nd_dpa_debug) && |
@@ -232,9 +233,9 @@ static void dgrp_input(struct ch_struct *ch) | |||
232 | (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) | 233 | (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) |
233 | dgrp_dpa_data(nd, 1, myflipbuf, len); | 234 | dgrp_dpa_data(nd, 1, myflipbuf, len); |
234 | 235 | ||
235 | tty_insert_flip_string_flags(tty, myflipbuf, | 236 | tty_insert_flip_string_flags(&ch->port, myflipbuf, |
236 | myflipflagbuf, len); | 237 | myflipflagbuf, len); |
237 | tty_flip_buffer_push(tty); | 238 | tty_flip_buffer_push(&ch->port); |
238 | 239 | ||
239 | ch->ch_rxcount += len; | 240 | ch->ch_rxcount += len; |
240 | } | 241 | } |
@@ -2956,9 +2957,9 @@ check_query: | |||
2956 | I_BRKINT(ch->ch_tun.un_tty) && | 2957 | I_BRKINT(ch->ch_tun.un_tty) && |
2957 | !(I_IGNBRK(ch->ch_tun.un_tty))) { | 2958 | !(I_IGNBRK(ch->ch_tun.un_tty))) { |
2958 | 2959 | ||
2959 | tty_buffer_request_room(ch->ch_tun.un_tty, 1); | 2960 | tty_buffer_request_room(&ch->port, 1); |
2960 | tty_insert_flip_char(ch->ch_tun.un_tty, 0, TTY_BREAK); | 2961 | tty_insert_flip_char(&ch->port, 0, TTY_BREAK); |
2961 | tty_flip_buffer_push(ch->ch_tun.un_tty); | 2962 | tty_flip_buffer_push(&ch->port); |
2962 | 2963 | ||
2963 | } | 2964 | } |
2964 | 2965 | ||
diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index 51d3ed3dca27..654f6010b473 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/tty.h> | 40 | #include <linux/tty.h> |
41 | #include <linux/tty_flip.h> | 41 | #include <linux/tty_flip.h> |
42 | #include <linux/device.h> | ||
42 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
43 | #include <linux/uaccess.h> | 44 | #include <linux/uaccess.h> |
44 | 45 | ||
diff --git a/drivers/staging/fwserial/Kconfig b/drivers/staging/fwserial/Kconfig index b2f8331e4acf..a0812d99136f 100644 --- a/drivers/staging/fwserial/Kconfig +++ b/drivers/staging/fwserial/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config FIREWIRE_SERIAL | 1 | config FIREWIRE_SERIAL |
2 | tristate "TTY over Firewire" | 2 | tristate "TTY over Firewire" |
3 | depends on FIREWIRE | 3 | depends on FIREWIRE && TTY |
4 | help | 4 | help |
5 | This enables TTY over IEEE 1394, providing high-speed serial | 5 | This enables TTY over IEEE 1394, providing high-speed serial |
6 | connectivity to cabled peers. This driver implements a | 6 | connectivity to cabled peers. This driver implements a |
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 8859c75f16fa..5a6fb44f38a8 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c | |||
@@ -500,16 +500,11 @@ static void fwtty_do_hangup(struct work_struct *work) | |||
500 | static void fwtty_emit_breaks(struct work_struct *work) | 500 | static void fwtty_emit_breaks(struct work_struct *work) |
501 | { | 501 | { |
502 | struct fwtty_port *port = to_port(to_delayed_work(work), emit_breaks); | 502 | struct fwtty_port *port = to_port(to_delayed_work(work), emit_breaks); |
503 | struct tty_struct *tty; | ||
504 | static const char buf[16]; | 503 | static const char buf[16]; |
505 | unsigned long now = jiffies; | 504 | unsigned long now = jiffies; |
506 | unsigned long elapsed = now - port->break_last; | 505 | unsigned long elapsed = now - port->break_last; |
507 | int n, t, c, brk = 0; | 506 | int n, t, c, brk = 0; |
508 | 507 | ||
509 | tty = tty_port_tty_get(&port->port); | ||
510 | if (!tty) | ||
511 | return; | ||
512 | |||
513 | /* generate breaks at the line rate (but at least 1) */ | 508 | /* generate breaks at the line rate (but at least 1) */ |
514 | n = (elapsed * port->cps) / HZ + 1; | 509 | n = (elapsed * port->cps) / HZ + 1; |
515 | port->break_last = now; | 510 | port->break_last = now; |
@@ -518,15 +513,14 @@ static void fwtty_emit_breaks(struct work_struct *work) | |||
518 | 513 | ||
519 | while (n) { | 514 | while (n) { |
520 | t = min(n, 16); | 515 | t = min(n, 16); |
521 | c = tty_insert_flip_string_fixed_flag(tty, buf, TTY_BREAK, t); | 516 | c = tty_insert_flip_string_fixed_flag(&port->port, buf, |
517 | TTY_BREAK, t); | ||
522 | n -= c; | 518 | n -= c; |
523 | brk += c; | 519 | brk += c; |
524 | if (c < t) | 520 | if (c < t) |
525 | break; | 521 | break; |
526 | } | 522 | } |
527 | tty_flip_buffer_push(tty); | 523 | tty_flip_buffer_push(&port->port); |
528 | |||
529 | tty_kref_put(tty); | ||
530 | 524 | ||
531 | if (port->mstatus & (UART_LSR_BI << 24)) | 525 | if (port->mstatus & (UART_LSR_BI << 24)) |
532 | schedule_delayed_work(&port->emit_breaks, FREQ_BREAKS); | 526 | schedule_delayed_work(&port->emit_breaks, FREQ_BREAKS); |
@@ -540,13 +534,9 @@ static void fwtty_pushrx(struct work_struct *work) | |||
540 | struct buffered_rx *buf, *next; | 534 | struct buffered_rx *buf, *next; |
541 | int n, c = 0; | 535 | int n, c = 0; |
542 | 536 | ||
543 | tty = tty_port_tty_get(&port->port); | ||
544 | if (!tty) | ||
545 | return; | ||
546 | |||
547 | spin_lock_bh(&port->lock); | 537 | spin_lock_bh(&port->lock); |
548 | list_for_each_entry_safe(buf, next, &port->buf_list, list) { | 538 | list_for_each_entry_safe(buf, next, &port->buf_list, list) { |
549 | n = tty_insert_flip_string_fixed_flag(tty, buf->data, | 539 | n = tty_insert_flip_string_fixed_flag(&port->port, buf->data, |
550 | TTY_NORMAL, buf->n); | 540 | TTY_NORMAL, buf->n); |
551 | c += n; | 541 | c += n; |
552 | port->buffered -= n; | 542 | port->buffered -= n; |
@@ -555,7 +545,11 @@ static void fwtty_pushrx(struct work_struct *work) | |||
555 | memmove(buf->data, buf->data + n, buf->n - n); | 545 | memmove(buf->data, buf->data + n, buf->n - n); |
556 | buf->n -= n; | 546 | buf->n -= n; |
557 | } | 547 | } |
558 | __fwtty_throttle(port, tty); | 548 | tty = tty_port_tty_get(&port->port); |
549 | if (tty) { | ||
550 | __fwtty_throttle(port, tty); | ||
551 | tty_kref_put(tty); | ||
552 | } | ||
559 | break; | 553 | break; |
560 | } else { | 554 | } else { |
561 | list_del(&buf->list); | 555 | list_del(&buf->list); |
@@ -563,13 +557,11 @@ static void fwtty_pushrx(struct work_struct *work) | |||
563 | } | 557 | } |
564 | } | 558 | } |
565 | if (c > 0) | 559 | if (c > 0) |
566 | tty_flip_buffer_push(tty); | 560 | tty_flip_buffer_push(&port->port); |
567 | 561 | ||
568 | if (list_empty(&port->buf_list)) | 562 | if (list_empty(&port->buf_list)) |
569 | clear_bit(BUFFERING_RX, &port->flags); | 563 | clear_bit(BUFFERING_RX, &port->flags); |
570 | spin_unlock_bh(&port->lock); | 564 | spin_unlock_bh(&port->lock); |
571 | |||
572 | tty_kref_put(tty); | ||
573 | } | 565 | } |
574 | 566 | ||
575 | static int fwtty_buffer_rx(struct fwtty_port *port, unsigned char *d, size_t n) | 567 | static int fwtty_buffer_rx(struct fwtty_port *port, unsigned char *d, size_t n) |
@@ -607,10 +599,6 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) | |||
607 | unsigned lsr; | 599 | unsigned lsr; |
608 | int err = 0; | 600 | int err = 0; |
609 | 601 | ||
610 | tty = tty_port_tty_get(&port->port); | ||
611 | if (!tty) | ||
612 | return -ENOENT; | ||
613 | |||
614 | fwtty_dbg(port, "%d", n); | 602 | fwtty_dbg(port, "%d", n); |
615 | profile_size_distrib(port->stats.reads, n); | 603 | profile_size_distrib(port->stats.reads, n); |
616 | 604 | ||
@@ -630,7 +618,7 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) | |||
630 | 618 | ||
631 | lsr &= port->status_mask; | 619 | lsr &= port->status_mask; |
632 | if (lsr & ~port->ignore_mask & UART_LSR_OE) { | 620 | if (lsr & ~port->ignore_mask & UART_LSR_OE) { |
633 | if (!tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { | 621 | if (!tty_insert_flip_char(&port->port, 0, TTY_OVERRUN)) { |
634 | err = -EIO; | 622 | err = -EIO; |
635 | goto out; | 623 | goto out; |
636 | } | 624 | } |
@@ -644,18 +632,23 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) | |||
644 | } | 632 | } |
645 | 633 | ||
646 | if (!test_bit(BUFFERING_RX, &port->flags)) { | 634 | if (!test_bit(BUFFERING_RX, &port->flags)) { |
647 | c = tty_insert_flip_string_fixed_flag(tty, data, TTY_NORMAL, n); | 635 | c = tty_insert_flip_string_fixed_flag(&port->port, data, |
636 | TTY_NORMAL, n); | ||
648 | if (c > 0) | 637 | if (c > 0) |
649 | tty_flip_buffer_push(tty); | 638 | tty_flip_buffer_push(&port->port); |
650 | n -= c; | 639 | n -= c; |
651 | 640 | ||
652 | if (n) { | 641 | if (n) { |
653 | /* start buffering and throttling */ | 642 | /* start buffering and throttling */ |
654 | n -= fwtty_buffer_rx(port, &data[c], n); | 643 | n -= fwtty_buffer_rx(port, &data[c], n); |
655 | 644 | ||
656 | spin_lock_bh(&port->lock); | 645 | tty = tty_port_tty_get(&port->port); |
657 | __fwtty_throttle(port, tty); | 646 | if (tty) { |
658 | spin_unlock_bh(&port->lock); | 647 | spin_lock_bh(&port->lock); |
648 | __fwtty_throttle(port, tty); | ||
649 | spin_unlock_bh(&port->lock); | ||
650 | tty_kref_put(tty); | ||
651 | } | ||
659 | } | 652 | } |
660 | } else | 653 | } else |
661 | n -= fwtty_buffer_rx(port, data, n); | 654 | n -= fwtty_buffer_rx(port, data, n); |
@@ -666,8 +659,6 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) | |||
666 | } | 659 | } |
667 | 660 | ||
668 | out: | 661 | out: |
669 | tty_kref_put(tty); | ||
670 | |||
671 | port->icount.rx += len; | 662 | port->icount.rx += len; |
672 | port->stats.lost += n; | 663 | port->stats.lost += n; |
673 | return err; | 664 | return err; |
diff --git a/drivers/staging/sb105x/Kconfig b/drivers/staging/sb105x/Kconfig index 1facad625554..245e7847a354 100644 --- a/drivers/staging/sb105x/Kconfig +++ b/drivers/staging/sb105x/Kconfig | |||
@@ -1,8 +1,7 @@ | |||
1 | config SB105X | 1 | config SB105X |
2 | tristate "SystemBase PCI Multiport UART" | 2 | tristate "SystemBase PCI Multiport UART" |
3 | select SERIAL_CORE | 3 | select SERIAL_CORE |
4 | depends on PCI | 4 | depends on PCI && X86 && TTY && BROKEN |
5 | depends on X86 | ||
6 | help | 5 | help |
7 | A driver for the SystemBase Multi-2/PCI serial card | 6 | A driver for the SystemBase Multi-2/PCI serial card |
8 | 7 | ||
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 1b3e995d3a27..b1bb1a6abe81 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c | |||
@@ -255,12 +255,11 @@ static void ProcessModemStatus(struct quatech_port *qt_port, | |||
255 | wake_up_interruptible(&qt_port->wait); | 255 | wake_up_interruptible(&qt_port->wait); |
256 | } | 256 | } |
257 | 257 | ||
258 | static void ProcessRxChar(struct tty_struct *tty, struct usb_serial_port *port, | 258 | static void ProcessRxChar(struct usb_serial_port *port, unsigned char data) |
259 | unsigned char data) | ||
260 | { | 259 | { |
261 | struct urb *urb = port->read_urb; | 260 | struct urb *urb = port->read_urb; |
262 | if (urb->actual_length) | 261 | if (urb->actual_length) |
263 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 262 | tty_insert_flip_char(&port->port, data, TTY_NORMAL); |
264 | } | 263 | } |
265 | 264 | ||
266 | static void qt_write_bulk_callback(struct urb *urb) | 265 | static void qt_write_bulk_callback(struct urb *urb) |
@@ -291,8 +290,7 @@ static void qt_interrupt_callback(struct urb *urb) | |||
291 | /* FIXME */ | 290 | /* FIXME */ |
292 | } | 291 | } |
293 | 292 | ||
294 | static void qt_status_change_check(struct tty_struct *tty, | 293 | static void qt_status_change_check(struct urb *urb, |
295 | struct urb *urb, | ||
296 | struct quatech_port *qt_port, | 294 | struct quatech_port *qt_port, |
297 | struct usb_serial_port *port) | 295 | struct usb_serial_port *port) |
298 | { | 296 | { |
@@ -335,8 +333,8 @@ static void qt_status_change_check(struct tty_struct *tty, | |||
335 | case 0xff: | 333 | case 0xff: |
336 | dev_dbg(&port->dev, "No status sequence.\n"); | 334 | dev_dbg(&port->dev, "No status sequence.\n"); |
337 | 335 | ||
338 | ProcessRxChar(tty, port, data[i]); | 336 | ProcessRxChar(port, data[i]); |
339 | ProcessRxChar(tty, port, data[i + 1]); | 337 | ProcessRxChar(port, data[i + 1]); |
340 | 338 | ||
341 | i += 2; | 339 | i += 2; |
342 | break; | 340 | break; |
@@ -345,11 +343,11 @@ static void qt_status_change_check(struct tty_struct *tty, | |||
345 | continue; | 343 | continue; |
346 | } | 344 | } |
347 | 345 | ||
348 | if (tty && urb->actual_length) | 346 | if (urb->actual_length) |
349 | tty_insert_flip_char(tty, data[i], TTY_NORMAL); | 347 | tty_insert_flip_char(&port->port, data[i], TTY_NORMAL); |
350 | 348 | ||
351 | } | 349 | } |
352 | tty_flip_buffer_push(tty); | 350 | tty_flip_buffer_push(&port->port); |
353 | } | 351 | } |
354 | 352 | ||
355 | static void qt_read_bulk_callback(struct urb *urb) | 353 | static void qt_read_bulk_callback(struct urb *urb) |
@@ -358,7 +356,6 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
358 | struct usb_serial_port *port = urb->context; | 356 | struct usb_serial_port *port = urb->context; |
359 | struct usb_serial *serial = get_usb_serial(port, __func__); | 357 | struct usb_serial *serial = get_usb_serial(port, __func__); |
360 | struct quatech_port *qt_port = qt_get_port_private(port); | 358 | struct quatech_port *qt_port = qt_get_port_private(port); |
361 | struct tty_struct *tty; | ||
362 | int result; | 359 | int result; |
363 | 360 | ||
364 | if (urb->status) { | 361 | if (urb->status) { |
@@ -369,27 +366,23 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
369 | return; | 366 | return; |
370 | } | 367 | } |
371 | 368 | ||
372 | tty = tty_port_tty_get(&port->port); | ||
373 | if (!tty) | ||
374 | return; | ||
375 | |||
376 | dev_dbg(&port->dev, | 369 | dev_dbg(&port->dev, |
377 | "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); | 370 | "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); |
378 | 371 | ||
379 | if (port_paranoia_check(port, __func__) != 0) { | 372 | if (port_paranoia_check(port, __func__) != 0) { |
380 | qt_port->ReadBulkStopped = 1; | 373 | qt_port->ReadBulkStopped = 1; |
381 | goto exit; | 374 | return; |
382 | } | 375 | } |
383 | 376 | ||
384 | if (!serial) | 377 | if (!serial) |
385 | goto exit; | 378 | return; |
386 | 379 | ||
387 | if (qt_port->closePending == 1) { | 380 | if (qt_port->closePending == 1) { |
388 | /* Were closing , stop reading */ | 381 | /* Were closing , stop reading */ |
389 | dev_dbg(&port->dev, | 382 | dev_dbg(&port->dev, |
390 | "%s - (qt_port->closepending == 1\n", __func__); | 383 | "%s - (qt_port->closepending == 1\n", __func__); |
391 | qt_port->ReadBulkStopped = 1; | 384 | qt_port->ReadBulkStopped = 1; |
392 | goto exit; | 385 | return; |
393 | } | 386 | } |
394 | 387 | ||
395 | /* | 388 | /* |
@@ -399,7 +392,7 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
399 | */ | 392 | */ |
400 | if (qt_port->RxHolding == 1) { | 393 | if (qt_port->RxHolding == 1) { |
401 | qt_port->ReadBulkStopped = 1; | 394 | qt_port->ReadBulkStopped = 1; |
402 | goto exit; | 395 | return; |
403 | } | 396 | } |
404 | 397 | ||
405 | if (urb->status) { | 398 | if (urb->status) { |
@@ -408,11 +401,11 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
408 | dev_dbg(&port->dev, | 401 | dev_dbg(&port->dev, |
409 | "%s - nonzero read bulk status received: %d\n", | 402 | "%s - nonzero read bulk status received: %d\n", |
410 | __func__, urb->status); | 403 | __func__, urb->status); |
411 | goto exit; | 404 | return; |
412 | } | 405 | } |
413 | 406 | ||
414 | if (urb->actual_length) | 407 | if (urb->actual_length) |
415 | qt_status_change_check(tty, urb, qt_port, port); | 408 | qt_status_change_check(urb, qt_port, port); |
416 | 409 | ||
417 | /* Continue trying to always read */ | 410 | /* Continue trying to always read */ |
418 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 411 | usb_fill_bulk_urb(port->read_urb, serial->dev, |
@@ -428,14 +421,12 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
428 | __func__, result); | 421 | __func__, result); |
429 | else { | 422 | else { |
430 | if (urb->actual_length) { | 423 | if (urb->actual_length) { |
431 | tty_flip_buffer_push(tty); | 424 | tty_flip_buffer_push(&port->port); |
432 | tty_schedule_flip(tty); | 425 | tty_schedule_flip(&port->port); |
433 | } | 426 | } |
434 | } | 427 | } |
435 | 428 | ||
436 | schedule_work(&port->work); | 429 | schedule_work(&port->work); |
437 | exit: | ||
438 | tty_kref_put(tty); | ||
439 | } | 430 | } |
440 | 431 | ||
441 | /* | 432 | /* |
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index 822ac3d24788..775af26b9914 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/consolemap.h> | 2 | #include <linux/consolemap.h> |
3 | #include <linux/interrupt.h> | 3 | #include <linux/interrupt.h> |
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | #include <linux/device.h> /* for dev_warn */ | ||
5 | #include <linux/selection.h> | 6 | #include <linux/selection.h> |
6 | 7 | ||
7 | #include "speakup.h" | 8 | #include "speakup.h" |
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 0ecf22b6a38e..978db344bda0 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig | |||
@@ -1,3 +1,14 @@ | |||
1 | config TTY | ||
2 | bool "Enable TTY" if EXPERT | ||
3 | default y | ||
4 | ---help--- | ||
5 | Allows you to remove TTY support which can save space, and | ||
6 | blocks features that require TTY from inclusion in the kernel. | ||
7 | TTY is required for any text terminals or serial port | ||
8 | communication. Most users should leave this enabled. | ||
9 | |||
10 | if TTY | ||
11 | |||
1 | config VT | 12 | config VT |
2 | bool "Virtual terminal" if EXPERT | 13 | bool "Virtual terminal" if EXPERT |
3 | depends on !S390 && !UML | 14 | depends on !S390 && !UML |
@@ -388,3 +399,24 @@ config PPC_EARLY_DEBUG_EHV_BC_HANDLE | |||
388 | If the number you specify is not a valid byte channel handle, then | 399 | If the number you specify is not a valid byte channel handle, then |
389 | there simply will be no early console output. This is true also | 400 | there simply will be no early console output. This is true also |
390 | if you don't boot under a hypervisor at all. | 401 | if you don't boot under a hypervisor at all. |
402 | |||
403 | config GOLDFISH_TTY | ||
404 | tristate "Goldfish TTY Driver" | ||
405 | depends on GOLDFISH | ||
406 | help | ||
407 | Console and system TTY driver for the Goldfish virtual platform. | ||
408 | |||
409 | config DA_TTY | ||
410 | bool "DA TTY" | ||
411 | depends on METAG_DA | ||
412 | select SERIAL_NONSTANDARD | ||
413 | help | ||
414 | This enables a TTY on a Dash channel. | ||
415 | |||
416 | config DA_CONSOLE | ||
417 | bool "DA Console" | ||
418 | depends on DA_TTY | ||
419 | help | ||
420 | This enables a console on a Dash channel. | ||
421 | |||
422 | endif # TTY | ||
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 2953059530e4..6b78399bc7c9 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ | 1 | obj-$(CONFIG_TTY) += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ |
2 | tty_buffer.o tty_port.o tty_mutex.o | 2 | tty_buffer.o tty_port.o tty_mutex.o |
3 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | 3 | obj-$(CONFIG_LEGACY_PTYS) += pty.o |
4 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | 4 | obj-$(CONFIG_UNIX98_PTYS) += pty.o |
@@ -27,5 +27,7 @@ obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o | |||
27 | obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o | 27 | obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o |
28 | obj-$(CONFIG_SYNCLINK) += synclink.o | 28 | obj-$(CONFIG_SYNCLINK) += synclink.o |
29 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o | 29 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o |
30 | obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o | ||
31 | obj-$(CONFIG_DA_TTY) += metag_da.o | ||
30 | 32 | ||
31 | obj-y += ipwireless/ | 33 | obj-y += ipwireless/ |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 9d7d00cdfecb..fc700342d43f 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -251,7 +251,6 @@ static void receive_chars(struct serial_state *info) | |||
251 | { | 251 | { |
252 | int status; | 252 | int status; |
253 | int serdatr; | 253 | int serdatr; |
254 | struct tty_struct *tty = info->tport.tty; | ||
255 | unsigned char ch, flag; | 254 | unsigned char ch, flag; |
256 | struct async_icount *icount; | 255 | struct async_icount *icount; |
257 | int oe = 0; | 256 | int oe = 0; |
@@ -314,7 +313,7 @@ static void receive_chars(struct serial_state *info) | |||
314 | #endif | 313 | #endif |
315 | flag = TTY_BREAK; | 314 | flag = TTY_BREAK; |
316 | if (info->tport.flags & ASYNC_SAK) | 315 | if (info->tport.flags & ASYNC_SAK) |
317 | do_SAK(tty); | 316 | do_SAK(info->tport.tty); |
318 | } else if (status & UART_LSR_PE) | 317 | } else if (status & UART_LSR_PE) |
319 | flag = TTY_PARITY; | 318 | flag = TTY_PARITY; |
320 | else if (status & UART_LSR_FE) | 319 | else if (status & UART_LSR_FE) |
@@ -328,10 +327,10 @@ static void receive_chars(struct serial_state *info) | |||
328 | oe = 1; | 327 | oe = 1; |
329 | } | 328 | } |
330 | } | 329 | } |
331 | tty_insert_flip_char(tty, ch, flag); | 330 | tty_insert_flip_char(&info->tport, ch, flag); |
332 | if (oe == 1) | 331 | if (oe == 1) |
333 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 332 | tty_insert_flip_char(&info->tport, 0, TTY_OVERRUN); |
334 | tty_flip_buffer_push(tty); | 333 | tty_flip_buffer_push(&info->tport); |
335 | out: | 334 | out: |
336 | return; | 335 | return; |
337 | } | 336 | } |
@@ -394,11 +393,6 @@ static void check_modem_status(struct serial_state *info) | |||
394 | icount->dsr++; | 393 | icount->dsr++; |
395 | if (dstatus & SER_DCD) { | 394 | if (dstatus & SER_DCD) { |
396 | icount->dcd++; | 395 | icount->dcd++; |
397 | #ifdef CONFIG_HARD_PPS | ||
398 | if ((port->flags & ASYNC_HARDPPS_CD) && | ||
399 | !(status & SER_DCD)) | ||
400 | hardpps(); | ||
401 | #endif | ||
402 | } | 396 | } |
403 | if (dstatus & SER_CTS) | 397 | if (dstatus & SER_CTS) |
404 | icount->cts++; | 398 | icount->cts++; |
@@ -1099,7 +1093,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
1099 | state->custom_divisor = new_serial.custom_divisor; | 1093 | state->custom_divisor = new_serial.custom_divisor; |
1100 | port->close_delay = new_serial.close_delay * HZ/100; | 1094 | port->close_delay = new_serial.close_delay * HZ/100; |
1101 | port->closing_wait = new_serial.closing_wait * HZ/100; | 1095 | port->closing_wait = new_serial.closing_wait * HZ/100; |
1102 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1096 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1103 | 1097 | ||
1104 | check_and_exit: | 1098 | check_and_exit: |
1105 | if (port->flags & ASYNC_INITIALIZED) { | 1099 | if (port->flags & ASYNC_INITIALIZED) { |
@@ -1528,7 +1522,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp) | |||
1528 | if (serial_paranoia_check(info, tty->name, "rs_open")) | 1522 | if (serial_paranoia_check(info, tty->name, "rs_open")) |
1529 | return -ENODEV; | 1523 | return -ENODEV; |
1530 | 1524 | ||
1531 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1525 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1532 | 1526 | ||
1533 | retval = startup(tty, info); | 1527 | retval = startup(tty, info); |
1534 | if (retval) { | 1528 | if (retval) { |
diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c index 1cfcdbf1d0cc..a93a424873fa 100644 --- a/drivers/tty/bfin_jtag_comm.c +++ b/drivers/tty/bfin_jtag_comm.c | |||
@@ -95,18 +95,16 @@ bfin_jc_emudat_manager(void *arg) | |||
95 | 95 | ||
96 | /* if incoming data is ready, eat it */ | 96 | /* if incoming data is ready, eat it */ |
97 | if (bfin_read_DBGSTAT() & EMUDIF) { | 97 | if (bfin_read_DBGSTAT() & EMUDIF) { |
98 | if (tty != NULL) { | 98 | uint32_t emudat = bfin_read_emudat(); |
99 | uint32_t emudat = bfin_read_emudat(); | 99 | if (inbound_len == 0) { |
100 | if (inbound_len == 0) { | 100 | pr_debug("incoming length: 0x%08x\n", emudat); |
101 | pr_debug("incoming length: 0x%08x\n", emudat); | 101 | inbound_len = emudat; |
102 | inbound_len = emudat; | 102 | } else { |
103 | } else { | 103 | size_t num_chars = (4 <= inbound_len ? 4 : inbound_len); |
104 | size_t num_chars = (4 <= inbound_len ? 4 : inbound_len); | 104 | pr_debug(" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars); |
105 | pr_debug(" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars); | 105 | inbound_len -= num_chars; |
106 | inbound_len -= num_chars; | 106 | tty_insert_flip_string(&port, (unsigned char *)&emudat, num_chars); |
107 | tty_insert_flip_string(tty, (unsigned char *)&emudat, num_chars); | 107 | tty_flip_buffer_push(&port); |
108 | tty_flip_buffer_push(tty); | ||
109 | } | ||
110 | } | 108 | } |
111 | } | 109 | } |
112 | 110 | ||
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index b09c8d1f9a66..345bd0e0884e 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -441,7 +441,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
441 | void __iomem *base_addr) | 441 | void __iomem *base_addr) |
442 | { | 442 | { |
443 | struct cyclades_port *info; | 443 | struct cyclades_port *info; |
444 | struct tty_struct *tty; | 444 | struct tty_port *port; |
445 | int len, index = cinfo->bus_index; | 445 | int len, index = cinfo->bus_index; |
446 | u8 ivr, save_xir, channel, save_car, data, char_count; | 446 | u8 ivr, save_xir, channel, save_car, data, char_count; |
447 | 447 | ||
@@ -452,22 +452,11 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
452 | save_xir = readb(base_addr + (CyRIR << index)); | 452 | save_xir = readb(base_addr + (CyRIR << index)); |
453 | channel = save_xir & CyIRChannel; | 453 | channel = save_xir & CyIRChannel; |
454 | info = &cinfo->ports[channel + chip * 4]; | 454 | info = &cinfo->ports[channel + chip * 4]; |
455 | port = &info->port; | ||
455 | save_car = cyy_readb(info, CyCAR); | 456 | save_car = cyy_readb(info, CyCAR); |
456 | cyy_writeb(info, CyCAR, save_xir); | 457 | cyy_writeb(info, CyCAR, save_xir); |
457 | ivr = cyy_readb(info, CyRIVR) & CyIVRMask; | 458 | ivr = cyy_readb(info, CyRIVR) & CyIVRMask; |
458 | 459 | ||
459 | tty = tty_port_tty_get(&info->port); | ||
460 | /* if there is nowhere to put the data, discard it */ | ||
461 | if (tty == NULL) { | ||
462 | if (ivr == CyIVRRxEx) { /* exception */ | ||
463 | data = cyy_readb(info, CyRDSR); | ||
464 | } else { /* normal character reception */ | ||
465 | char_count = cyy_readb(info, CyRDCR); | ||
466 | while (char_count--) | ||
467 | data = cyy_readb(info, CyRDSR); | ||
468 | } | ||
469 | goto end; | ||
470 | } | ||
471 | /* there is an open port for this data */ | 460 | /* there is an open port for this data */ |
472 | if (ivr == CyIVRRxEx) { /* exception */ | 461 | if (ivr == CyIVRRxEx) { /* exception */ |
473 | data = cyy_readb(info, CyRDSR); | 462 | data = cyy_readb(info, CyRDSR); |
@@ -484,40 +473,45 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
484 | 473 | ||
485 | if (data & info->ignore_status_mask) { | 474 | if (data & info->ignore_status_mask) { |
486 | info->icount.rx++; | 475 | info->icount.rx++; |
487 | tty_kref_put(tty); | ||
488 | return; | 476 | return; |
489 | } | 477 | } |
490 | if (tty_buffer_request_room(tty, 1)) { | 478 | if (tty_buffer_request_room(port, 1)) { |
491 | if (data & info->read_status_mask) { | 479 | if (data & info->read_status_mask) { |
492 | if (data & CyBREAK) { | 480 | if (data & CyBREAK) { |
493 | tty_insert_flip_char(tty, | 481 | tty_insert_flip_char(port, |
494 | cyy_readb(info, CyRDSR), | 482 | cyy_readb(info, CyRDSR), |
495 | TTY_BREAK); | 483 | TTY_BREAK); |
496 | info->icount.rx++; | 484 | info->icount.rx++; |
497 | if (info->port.flags & ASYNC_SAK) | 485 | if (port->flags & ASYNC_SAK) { |
498 | do_SAK(tty); | 486 | struct tty_struct *tty = |
487 | tty_port_tty_get(port); | ||
488 | if (tty) { | ||
489 | do_SAK(tty); | ||
490 | tty_kref_put(tty); | ||
491 | } | ||
492 | } | ||
499 | } else if (data & CyFRAME) { | 493 | } else if (data & CyFRAME) { |
500 | tty_insert_flip_char(tty, | 494 | tty_insert_flip_char(port, |
501 | cyy_readb(info, CyRDSR), | 495 | cyy_readb(info, CyRDSR), |
502 | TTY_FRAME); | 496 | TTY_FRAME); |
503 | info->icount.rx++; | 497 | info->icount.rx++; |
504 | info->idle_stats.frame_errs++; | 498 | info->idle_stats.frame_errs++; |
505 | } else if (data & CyPARITY) { | 499 | } else if (data & CyPARITY) { |
506 | /* Pieces of seven... */ | 500 | /* Pieces of seven... */ |
507 | tty_insert_flip_char(tty, | 501 | tty_insert_flip_char(port, |
508 | cyy_readb(info, CyRDSR), | 502 | cyy_readb(info, CyRDSR), |
509 | TTY_PARITY); | 503 | TTY_PARITY); |
510 | info->icount.rx++; | 504 | info->icount.rx++; |
511 | info->idle_stats.parity_errs++; | 505 | info->idle_stats.parity_errs++; |
512 | } else if (data & CyOVERRUN) { | 506 | } else if (data & CyOVERRUN) { |
513 | tty_insert_flip_char(tty, 0, | 507 | tty_insert_flip_char(port, 0, |
514 | TTY_OVERRUN); | 508 | TTY_OVERRUN); |
515 | info->icount.rx++; | 509 | info->icount.rx++; |
516 | /* If the flip buffer itself is | 510 | /* If the flip buffer itself is |
517 | overflowing, we still lose | 511 | overflowing, we still lose |
518 | the next incoming character. | 512 | the next incoming character. |
519 | */ | 513 | */ |
520 | tty_insert_flip_char(tty, | 514 | tty_insert_flip_char(port, |
521 | cyy_readb(info, CyRDSR), | 515 | cyy_readb(info, CyRDSR), |
522 | TTY_FRAME); | 516 | TTY_FRAME); |
523 | info->icount.rx++; | 517 | info->icount.rx++; |
@@ -527,12 +521,12 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
527 | /* } else if(data & CyTIMEOUT) { */ | 521 | /* } else if(data & CyTIMEOUT) { */ |
528 | /* } else if(data & CySPECHAR) { */ | 522 | /* } else if(data & CySPECHAR) { */ |
529 | } else { | 523 | } else { |
530 | tty_insert_flip_char(tty, 0, | 524 | tty_insert_flip_char(port, 0, |
531 | TTY_NORMAL); | 525 | TTY_NORMAL); |
532 | info->icount.rx++; | 526 | info->icount.rx++; |
533 | } | 527 | } |
534 | } else { | 528 | } else { |
535 | tty_insert_flip_char(tty, 0, TTY_NORMAL); | 529 | tty_insert_flip_char(port, 0, TTY_NORMAL); |
536 | info->icount.rx++; | 530 | info->icount.rx++; |
537 | } | 531 | } |
538 | } else { | 532 | } else { |
@@ -552,10 +546,10 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
552 | info->mon.char_max = char_count; | 546 | info->mon.char_max = char_count; |
553 | info->mon.char_last = char_count; | 547 | info->mon.char_last = char_count; |
554 | #endif | 548 | #endif |
555 | len = tty_buffer_request_room(tty, char_count); | 549 | len = tty_buffer_request_room(port, char_count); |
556 | while (len--) { | 550 | while (len--) { |
557 | data = cyy_readb(info, CyRDSR); | 551 | data = cyy_readb(info, CyRDSR); |
558 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 552 | tty_insert_flip_char(port, data, TTY_NORMAL); |
559 | info->idle_stats.recv_bytes++; | 553 | info->idle_stats.recv_bytes++; |
560 | info->icount.rx++; | 554 | info->icount.rx++; |
561 | #ifdef CY_16Y_HACK | 555 | #ifdef CY_16Y_HACK |
@@ -564,9 +558,8 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
564 | } | 558 | } |
565 | info->idle_stats.recv_idle = jiffies; | 559 | info->idle_stats.recv_idle = jiffies; |
566 | } | 560 | } |
567 | tty_schedule_flip(tty); | 561 | tty_schedule_flip(port); |
568 | tty_kref_put(tty); | 562 | |
569 | end: | ||
570 | /* end of service */ | 563 | /* end of service */ |
571 | cyy_writeb(info, CyRIR, save_xir & 0x3f); | 564 | cyy_writeb(info, CyRIR, save_xir & 0x3f); |
572 | cyy_writeb(info, CyCAR, save_car); | 565 | cyy_writeb(info, CyCAR, save_car); |
@@ -924,10 +917,11 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
924 | return 0; | 917 | return 0; |
925 | } /* cyz_issue_cmd */ | 918 | } /* cyz_issue_cmd */ |
926 | 919 | ||
927 | static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) | 920 | static void cyz_handle_rx(struct cyclades_port *info) |
928 | { | 921 | { |
929 | struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; | 922 | struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; |
930 | struct cyclades_card *cinfo = info->card; | 923 | struct cyclades_card *cinfo = info->card; |
924 | struct tty_port *port = &info->port; | ||
931 | unsigned int char_count; | 925 | unsigned int char_count; |
932 | int len; | 926 | int len; |
933 | #ifdef BLOCKMOVE | 927 | #ifdef BLOCKMOVE |
@@ -946,80 +940,77 @@ static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) | |||
946 | else | 940 | else |
947 | char_count = rx_put - rx_get + rx_bufsize; | 941 | char_count = rx_put - rx_get + rx_bufsize; |
948 | 942 | ||
949 | if (char_count) { | 943 | if (!char_count) |
944 | return; | ||
945 | |||
950 | #ifdef CY_ENABLE_MONITORING | 946 | #ifdef CY_ENABLE_MONITORING |
951 | info->mon.int_count++; | 947 | info->mon.int_count++; |
952 | info->mon.char_count += char_count; | 948 | info->mon.char_count += char_count; |
953 | if (char_count > info->mon.char_max) | 949 | if (char_count > info->mon.char_max) |
954 | info->mon.char_max = char_count; | 950 | info->mon.char_max = char_count; |
955 | info->mon.char_last = char_count; | 951 | info->mon.char_last = char_count; |
956 | #endif | 952 | #endif |
957 | if (tty == NULL) { | 953 | |
958 | /* flush received characters */ | ||
959 | new_rx_get = (new_rx_get + char_count) & | ||
960 | (rx_bufsize - 1); | ||
961 | info->rflush_count++; | ||
962 | } else { | ||
963 | #ifdef BLOCKMOVE | 954 | #ifdef BLOCKMOVE |
964 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) | 955 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) |
965 | for performance, but because of buffer boundaries, there | 956 | for performance, but because of buffer boundaries, there |
966 | may be several steps to the operation */ | 957 | may be several steps to the operation */ |
967 | while (1) { | 958 | while (1) { |
968 | len = tty_prepare_flip_string(tty, &buf, | 959 | len = tty_prepare_flip_string(port, &buf, |
969 | char_count); | 960 | char_count); |
970 | if (!len) | 961 | if (!len) |
971 | break; | 962 | break; |
972 | 963 | ||
973 | len = min_t(unsigned int, min(len, char_count), | 964 | len = min_t(unsigned int, min(len, char_count), |
974 | rx_bufsize - new_rx_get); | 965 | rx_bufsize - new_rx_get); |
975 | 966 | ||
976 | memcpy_fromio(buf, cinfo->base_addr + | 967 | memcpy_fromio(buf, cinfo->base_addr + |
977 | rx_bufaddr + new_rx_get, len); | 968 | rx_bufaddr + new_rx_get, len); |
978 | 969 | ||
979 | new_rx_get = (new_rx_get + len) & | 970 | new_rx_get = (new_rx_get + len) & |
980 | (rx_bufsize - 1); | 971 | (rx_bufsize - 1); |
981 | char_count -= len; | 972 | char_count -= len; |
982 | info->icount.rx += len; | 973 | info->icount.rx += len; |
983 | info->idle_stats.recv_bytes += len; | 974 | info->idle_stats.recv_bytes += len; |
984 | } | 975 | } |
985 | #else | 976 | #else |
986 | len = tty_buffer_request_room(tty, char_count); | 977 | len = tty_buffer_request_room(port, char_count); |
987 | while (len--) { | 978 | while (len--) { |
988 | data = readb(cinfo->base_addr + rx_bufaddr + | 979 | data = readb(cinfo->base_addr + rx_bufaddr + |
989 | new_rx_get); | 980 | new_rx_get); |
990 | new_rx_get = (new_rx_get + 1) & | 981 | new_rx_get = (new_rx_get + 1) & |
991 | (rx_bufsize - 1); | 982 | (rx_bufsize - 1); |
992 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 983 | tty_insert_flip_char(port, data, TTY_NORMAL); |
993 | info->idle_stats.recv_bytes++; | 984 | info->idle_stats.recv_bytes++; |
994 | info->icount.rx++; | 985 | info->icount.rx++; |
995 | } | 986 | } |
996 | #endif | 987 | #endif |
997 | #ifdef CONFIG_CYZ_INTR | 988 | #ifdef CONFIG_CYZ_INTR |
998 | /* Recalculate the number of chars in the RX buffer and issue | 989 | /* Recalculate the number of chars in the RX buffer and issue |
999 | a cmd in case it's higher than the RX high water mark */ | 990 | a cmd in case it's higher than the RX high water mark */ |
1000 | rx_put = readl(&buf_ctrl->rx_put); | 991 | rx_put = readl(&buf_ctrl->rx_put); |
1001 | if (rx_put >= rx_get) | 992 | if (rx_put >= rx_get) |
1002 | char_count = rx_put - rx_get; | 993 | char_count = rx_put - rx_get; |
1003 | else | 994 | else |
1004 | char_count = rx_put - rx_get + rx_bufsize; | 995 | char_count = rx_put - rx_get + rx_bufsize; |
1005 | if (char_count >= readl(&buf_ctrl->rx_threshold) && | 996 | if (char_count >= readl(&buf_ctrl->rx_threshold) && |
1006 | !timer_pending(&cyz_rx_full_timer[ | 997 | !timer_pending(&cyz_rx_full_timer[ |
1007 | info->line])) | 998 | info->line])) |
1008 | mod_timer(&cyz_rx_full_timer[info->line], | 999 | mod_timer(&cyz_rx_full_timer[info->line], |
1009 | jiffies + 1); | 1000 | jiffies + 1); |
1010 | #endif | 1001 | #endif |
1011 | info->idle_stats.recv_idle = jiffies; | 1002 | info->idle_stats.recv_idle = jiffies; |
1012 | tty_schedule_flip(tty); | 1003 | tty_schedule_flip(&info->port); |
1013 | } | 1004 | |
1014 | /* Update rx_get */ | 1005 | /* Update rx_get */ |
1015 | cy_writel(&buf_ctrl->rx_get, new_rx_get); | 1006 | cy_writel(&buf_ctrl->rx_get, new_rx_get); |
1016 | } | ||
1017 | } | 1007 | } |
1018 | 1008 | ||
1019 | static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) | 1009 | static void cyz_handle_tx(struct cyclades_port *info) |
1020 | { | 1010 | { |
1021 | struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; | 1011 | struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; |
1022 | struct cyclades_card *cinfo = info->card; | 1012 | struct cyclades_card *cinfo = info->card; |
1013 | struct tty_struct *tty; | ||
1023 | u8 data; | 1014 | u8 data; |
1024 | unsigned int char_count; | 1015 | unsigned int char_count; |
1025 | #ifdef BLOCKMOVE | 1016 | #ifdef BLOCKMOVE |
@@ -1039,63 +1030,63 @@ static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) | |||
1039 | else | 1030 | else |
1040 | char_count = tx_get - tx_put - 1; | 1031 | char_count = tx_get - tx_put - 1; |
1041 | 1032 | ||
1042 | if (char_count) { | 1033 | if (!char_count) |
1043 | 1034 | return; | |
1044 | if (tty == NULL) | 1035 | |
1045 | goto ztxdone; | 1036 | tty = tty_port_tty_get(&info->port); |
1037 | if (tty == NULL) | ||
1038 | goto ztxdone; | ||
1046 | 1039 | ||
1047 | if (info->x_char) { /* send special char */ | 1040 | if (info->x_char) { /* send special char */ |
1048 | data = info->x_char; | 1041 | data = info->x_char; |
1049 | 1042 | ||
1050 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); | 1043 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); |
1051 | tx_put = (tx_put + 1) & (tx_bufsize - 1); | 1044 | tx_put = (tx_put + 1) & (tx_bufsize - 1); |
1052 | info->x_char = 0; | 1045 | info->x_char = 0; |
1053 | char_count--; | 1046 | char_count--; |
1054 | info->icount.tx++; | 1047 | info->icount.tx++; |
1055 | } | 1048 | } |
1056 | #ifdef BLOCKMOVE | 1049 | #ifdef BLOCKMOVE |
1057 | while (0 < (small_count = min_t(unsigned int, | 1050 | while (0 < (small_count = min_t(unsigned int, |
1058 | tx_bufsize - tx_put, min_t(unsigned int, | 1051 | tx_bufsize - tx_put, min_t(unsigned int, |
1059 | (SERIAL_XMIT_SIZE - info->xmit_tail), | 1052 | (SERIAL_XMIT_SIZE - info->xmit_tail), |
1060 | min_t(unsigned int, info->xmit_cnt, | 1053 | min_t(unsigned int, info->xmit_cnt, |
1061 | char_count))))) { | 1054 | char_count))))) { |
1062 | 1055 | ||
1063 | memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + | 1056 | memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put), |
1064 | tx_put), | 1057 | &info->port.xmit_buf[info->xmit_tail], |
1065 | &info->port.xmit_buf[info->xmit_tail], | 1058 | small_count); |
1066 | small_count); | 1059 | |
1067 | 1060 | tx_put = (tx_put + small_count) & (tx_bufsize - 1); | |
1068 | tx_put = (tx_put + small_count) & (tx_bufsize - 1); | 1061 | char_count -= small_count; |
1069 | char_count -= small_count; | 1062 | info->icount.tx += small_count; |
1070 | info->icount.tx += small_count; | 1063 | info->xmit_cnt -= small_count; |
1071 | info->xmit_cnt -= small_count; | 1064 | info->xmit_tail = (info->xmit_tail + small_count) & |
1072 | info->xmit_tail = (info->xmit_tail + small_count) & | 1065 | (SERIAL_XMIT_SIZE - 1); |
1073 | (SERIAL_XMIT_SIZE - 1); | 1066 | } |
1074 | } | ||
1075 | #else | 1067 | #else |
1076 | while (info->xmit_cnt && char_count) { | 1068 | while (info->xmit_cnt && char_count) { |
1077 | data = info->port.xmit_buf[info->xmit_tail]; | 1069 | data = info->port.xmit_buf[info->xmit_tail]; |
1078 | info->xmit_cnt--; | 1070 | info->xmit_cnt--; |
1079 | info->xmit_tail = (info->xmit_tail + 1) & | 1071 | info->xmit_tail = (info->xmit_tail + 1) & |
1080 | (SERIAL_XMIT_SIZE - 1); | 1072 | (SERIAL_XMIT_SIZE - 1); |
1081 | 1073 | ||
1082 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); | 1074 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); |
1083 | tx_put = (tx_put + 1) & (tx_bufsize - 1); | 1075 | tx_put = (tx_put + 1) & (tx_bufsize - 1); |
1084 | char_count--; | 1076 | char_count--; |
1085 | info->icount.tx++; | 1077 | info->icount.tx++; |
1086 | } | 1078 | } |
1087 | #endif | 1079 | #endif |
1088 | tty_wakeup(tty); | 1080 | tty_wakeup(tty); |
1081 | tty_kref_put(tty); | ||
1089 | ztxdone: | 1082 | ztxdone: |
1090 | /* Update tx_put */ | 1083 | /* Update tx_put */ |
1091 | cy_writel(&buf_ctrl->tx_put, tx_put); | 1084 | cy_writel(&buf_ctrl->tx_put, tx_put); |
1092 | } | ||
1093 | } | 1085 | } |
1094 | 1086 | ||
1095 | static void cyz_handle_cmd(struct cyclades_card *cinfo) | 1087 | static void cyz_handle_cmd(struct cyclades_card *cinfo) |
1096 | { | 1088 | { |
1097 | struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; | 1089 | struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; |
1098 | struct tty_struct *tty; | ||
1099 | struct cyclades_port *info; | 1090 | struct cyclades_port *info; |
1100 | __u32 channel, param, fw_ver; | 1091 | __u32 channel, param, fw_ver; |
1101 | __u8 cmd; | 1092 | __u8 cmd; |
@@ -1108,23 +1099,20 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1108 | special_count = 0; | 1099 | special_count = 0; |
1109 | delta_count = 0; | 1100 | delta_count = 0; |
1110 | info = &cinfo->ports[channel]; | 1101 | info = &cinfo->ports[channel]; |
1111 | tty = tty_port_tty_get(&info->port); | ||
1112 | if (tty == NULL) | ||
1113 | continue; | ||
1114 | 1102 | ||
1115 | switch (cmd) { | 1103 | switch (cmd) { |
1116 | case C_CM_PR_ERROR: | 1104 | case C_CM_PR_ERROR: |
1117 | tty_insert_flip_char(tty, 0, TTY_PARITY); | 1105 | tty_insert_flip_char(&info->port, 0, TTY_PARITY); |
1118 | info->icount.rx++; | 1106 | info->icount.rx++; |
1119 | special_count++; | 1107 | special_count++; |
1120 | break; | 1108 | break; |
1121 | case C_CM_FR_ERROR: | 1109 | case C_CM_FR_ERROR: |
1122 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 1110 | tty_insert_flip_char(&info->port, 0, TTY_FRAME); |
1123 | info->icount.rx++; | 1111 | info->icount.rx++; |
1124 | special_count++; | 1112 | special_count++; |
1125 | break; | 1113 | break; |
1126 | case C_CM_RXBRK: | 1114 | case C_CM_RXBRK: |
1127 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1115 | tty_insert_flip_char(&info->port, 0, TTY_BREAK); |
1128 | info->icount.rx++; | 1116 | info->icount.rx++; |
1129 | special_count++; | 1117 | special_count++; |
1130 | break; | 1118 | break; |
@@ -1136,8 +1124,14 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1136 | readl(&info->u.cyz.ch_ctrl->rs_status); | 1124 | readl(&info->u.cyz.ch_ctrl->rs_status); |
1137 | if (dcd & C_RS_DCD) | 1125 | if (dcd & C_RS_DCD) |
1138 | wake_up_interruptible(&info->port.open_wait); | 1126 | wake_up_interruptible(&info->port.open_wait); |
1139 | else | 1127 | else { |
1140 | tty_hangup(tty); | 1128 | struct tty_struct *tty; |
1129 | tty = tty_port_tty_get(&info->port); | ||
1130 | if (tty) { | ||
1131 | tty_hangup(tty); | ||
1132 | tty_kref_put(tty); | ||
1133 | } | ||
1134 | } | ||
1141 | } | 1135 | } |
1142 | break; | 1136 | break; |
1143 | case C_CM_MCTS: | 1137 | case C_CM_MCTS: |
@@ -1166,7 +1160,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1166 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " | 1160 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " |
1167 | "port %ld\n", info->card, channel); | 1161 | "port %ld\n", info->card, channel); |
1168 | #endif | 1162 | #endif |
1169 | cyz_handle_rx(info, tty); | 1163 | cyz_handle_rx(info); |
1170 | break; | 1164 | break; |
1171 | case C_CM_TXBEMPTY: | 1165 | case C_CM_TXBEMPTY: |
1172 | case C_CM_TXLOWWM: | 1166 | case C_CM_TXLOWWM: |
@@ -1176,7 +1170,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1176 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " | 1170 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " |
1177 | "port %ld\n", info->card, channel); | 1171 | "port %ld\n", info->card, channel); |
1178 | #endif | 1172 | #endif |
1179 | cyz_handle_tx(info, tty); | 1173 | cyz_handle_tx(info); |
1180 | break; | 1174 | break; |
1181 | #endif /* CONFIG_CYZ_INTR */ | 1175 | #endif /* CONFIG_CYZ_INTR */ |
1182 | case C_CM_FATAL: | 1176 | case C_CM_FATAL: |
@@ -1188,8 +1182,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1188 | if (delta_count) | 1182 | if (delta_count) |
1189 | wake_up_interruptible(&info->port.delta_msr_wait); | 1183 | wake_up_interruptible(&info->port.delta_msr_wait); |
1190 | if (special_count) | 1184 | if (special_count) |
1191 | tty_schedule_flip(tty); | 1185 | tty_schedule_flip(&info->port); |
1192 | tty_kref_put(tty); | ||
1193 | } | 1186 | } |
1194 | } | 1187 | } |
1195 | 1188 | ||
@@ -1255,17 +1248,11 @@ static void cyz_poll(unsigned long arg) | |||
1255 | cyz_handle_cmd(cinfo); | 1248 | cyz_handle_cmd(cinfo); |
1256 | 1249 | ||
1257 | for (port = 0; port < cinfo->nports; port++) { | 1250 | for (port = 0; port < cinfo->nports; port++) { |
1258 | struct tty_struct *tty; | ||
1259 | |||
1260 | info = &cinfo->ports[port]; | 1251 | info = &cinfo->ports[port]; |
1261 | tty = tty_port_tty_get(&info->port); | ||
1262 | /* OK to pass NULL to the handle functions below. | ||
1263 | They need to drop the data in that case. */ | ||
1264 | 1252 | ||
1265 | if (!info->throttle) | 1253 | if (!info->throttle) |
1266 | cyz_handle_rx(info, tty); | 1254 | cyz_handle_rx(info); |
1267 | cyz_handle_tx(info, tty); | 1255 | cyz_handle_tx(info); |
1268 | tty_kref_put(tty); | ||
1269 | } | 1256 | } |
1270 | /* poll every 'cyz_polling_cycle' period */ | 1257 | /* poll every 'cyz_polling_cycle' period */ |
1271 | expires = jiffies + cyz_polling_cycle; | 1258 | expires = jiffies + cyz_polling_cycle; |
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index c117d775a22f..ed92622b8949 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
@@ -371,22 +371,17 @@ console_initcall(ehv_bc_console_init); | |||
371 | static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) | 371 | static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) |
372 | { | 372 | { |
373 | struct ehv_bc_data *bc = data; | 373 | struct ehv_bc_data *bc = data; |
374 | struct tty_struct *ttys = tty_port_tty_get(&bc->port); | ||
375 | unsigned int rx_count, tx_count, len; | 374 | unsigned int rx_count, tx_count, len; |
376 | int count; | 375 | int count; |
377 | char buffer[EV_BYTE_CHANNEL_MAX_BYTES]; | 376 | char buffer[EV_BYTE_CHANNEL_MAX_BYTES]; |
378 | int ret; | 377 | int ret; |
379 | 378 | ||
380 | /* ttys could be NULL during a hangup */ | ||
381 | if (!ttys) | ||
382 | return IRQ_HANDLED; | ||
383 | |||
384 | /* Find out how much data needs to be read, and then ask the TTY layer | 379 | /* Find out how much data needs to be read, and then ask the TTY layer |
385 | * if it can handle that much. We want to ensure that every byte we | 380 | * if it can handle that much. We want to ensure that every byte we |
386 | * read from the byte channel will be accepted by the TTY layer. | 381 | * read from the byte channel will be accepted by the TTY layer. |
387 | */ | 382 | */ |
388 | ev_byte_channel_poll(bc->handle, &rx_count, &tx_count); | 383 | ev_byte_channel_poll(bc->handle, &rx_count, &tx_count); |
389 | count = tty_buffer_request_room(ttys, rx_count); | 384 | count = tty_buffer_request_room(&bc->port, rx_count); |
390 | 385 | ||
391 | /* 'count' is the maximum amount of data the TTY layer can accept at | 386 | /* 'count' is the maximum amount of data the TTY layer can accept at |
392 | * this time. However, during testing, I was never able to get 'count' | 387 | * this time. However, during testing, I was never able to get 'count' |
@@ -407,7 +402,7 @@ static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) | |||
407 | */ | 402 | */ |
408 | 403 | ||
409 | /* Pass the received data to the tty layer. */ | 404 | /* Pass the received data to the tty layer. */ |
410 | ret = tty_insert_flip_string(ttys, buffer, len); | 405 | ret = tty_insert_flip_string(&bc->port, buffer, len); |
411 | 406 | ||
412 | /* 'ret' is the number of bytes that the TTY layer accepted. | 407 | /* 'ret' is the number of bytes that the TTY layer accepted. |
413 | * If it's not equal to 'len', then it means the buffer is | 408 | * If it's not equal to 'len', then it means the buffer is |
@@ -422,9 +417,7 @@ static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) | |||
422 | } | 417 | } |
423 | 418 | ||
424 | /* Tell the tty layer that we're done. */ | 419 | /* Tell the tty layer that we're done. */ |
425 | tty_flip_buffer_push(ttys); | 420 | tty_flip_buffer_push(&bc->port); |
426 | |||
427 | tty_kref_put(ttys); | ||
428 | 421 | ||
429 | return IRQ_HANDLED; | 422 | return IRQ_HANDLED; |
430 | } | 423 | } |
diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c new file mode 100644 index 000000000000..f17d2e4ee2ca --- /dev/null +++ b/drivers/tty/goldfish.c | |||
@@ -0,0 +1,328 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Google, Inc. | ||
3 | * Copyright (C) 2012 Intel, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/console.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/tty.h> | ||
21 | #include <linux/tty_flip.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/module.h> | ||
25 | |||
26 | enum { | ||
27 | GOLDFISH_TTY_PUT_CHAR = 0x00, | ||
28 | GOLDFISH_TTY_BYTES_READY = 0x04, | ||
29 | GOLDFISH_TTY_CMD = 0x08, | ||
30 | |||
31 | GOLDFISH_TTY_DATA_PTR = 0x10, | ||
32 | GOLDFISH_TTY_DATA_LEN = 0x14, | ||
33 | |||
34 | GOLDFISH_TTY_CMD_INT_DISABLE = 0, | ||
35 | GOLDFISH_TTY_CMD_INT_ENABLE = 1, | ||
36 | GOLDFISH_TTY_CMD_WRITE_BUFFER = 2, | ||
37 | GOLDFISH_TTY_CMD_READ_BUFFER = 3, | ||
38 | }; | ||
39 | |||
40 | struct goldfish_tty { | ||
41 | struct tty_port port; | ||
42 | spinlock_t lock; | ||
43 | void __iomem *base; | ||
44 | u32 irq; | ||
45 | int opencount; | ||
46 | struct console console; | ||
47 | }; | ||
48 | |||
49 | static DEFINE_MUTEX(goldfish_tty_lock); | ||
50 | static struct tty_driver *goldfish_tty_driver; | ||
51 | static u32 goldfish_tty_line_count = 8; | ||
52 | static u32 goldfish_tty_current_line_count; | ||
53 | static struct goldfish_tty *goldfish_ttys; | ||
54 | |||
55 | static void goldfish_tty_do_write(int line, const char *buf, unsigned count) | ||
56 | { | ||
57 | unsigned long irq_flags; | ||
58 | struct goldfish_tty *qtty = &goldfish_ttys[line]; | ||
59 | void __iomem *base = qtty->base; | ||
60 | spin_lock_irqsave(&qtty->lock, irq_flags); | ||
61 | writel((u32)buf, base + GOLDFISH_TTY_DATA_PTR); | ||
62 | writel(count, base + GOLDFISH_TTY_DATA_LEN); | ||
63 | writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, base + GOLDFISH_TTY_CMD); | ||
64 | spin_unlock_irqrestore(&qtty->lock, irq_flags); | ||
65 | } | ||
66 | |||
67 | static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) | ||
68 | { | ||
69 | struct platform_device *pdev = dev_id; | ||
70 | struct goldfish_tty *qtty = &goldfish_ttys[pdev->id]; | ||
71 | void __iomem *base = qtty->base; | ||
72 | unsigned long irq_flags; | ||
73 | unsigned char *buf; | ||
74 | u32 count; | ||
75 | |||
76 | count = readl(base + GOLDFISH_TTY_BYTES_READY); | ||
77 | if(count == 0) | ||
78 | return IRQ_NONE; | ||
79 | |||
80 | count = tty_prepare_flip_string(&qtty->port, &buf, count); | ||
81 | spin_lock_irqsave(&qtty->lock, irq_flags); | ||
82 | writel((u32)buf, base + GOLDFISH_TTY_DATA_PTR); | ||
83 | writel(count, base + GOLDFISH_TTY_DATA_LEN); | ||
84 | writel(GOLDFISH_TTY_CMD_READ_BUFFER, base + GOLDFISH_TTY_CMD); | ||
85 | spin_unlock_irqrestore(&qtty->lock, irq_flags); | ||
86 | tty_schedule_flip(&qtty->port); | ||
87 | return IRQ_HANDLED; | ||
88 | } | ||
89 | |||
90 | static int goldfish_tty_activate(struct tty_port *port, struct tty_struct *tty) | ||
91 | { | ||
92 | struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); | ||
93 | writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_CMD); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static void goldfish_tty_shutdown(struct tty_port *port) | ||
98 | { | ||
99 | struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); | ||
100 | writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_CMD); | ||
101 | } | ||
102 | |||
103 | static int goldfish_tty_open(struct tty_struct * tty, struct file * filp) | ||
104 | { | ||
105 | struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; | ||
106 | return tty_port_open(&qtty->port, tty, filp); | ||
107 | } | ||
108 | |||
109 | static void goldfish_tty_close(struct tty_struct * tty, struct file * filp) | ||
110 | { | ||
111 | tty_port_close(tty->port, tty, filp); | ||
112 | } | ||
113 | |||
114 | static void goldfish_tty_hangup(struct tty_struct *tty) | ||
115 | { | ||
116 | tty_port_hangup(tty->port); | ||
117 | } | ||
118 | |||
119 | static int goldfish_tty_write(struct tty_struct * tty, const unsigned char *buf, int count) | ||
120 | { | ||
121 | goldfish_tty_do_write(tty->index, buf, count); | ||
122 | return count; | ||
123 | } | ||
124 | |||
125 | static int goldfish_tty_write_room(struct tty_struct *tty) | ||
126 | { | ||
127 | return 0x10000; | ||
128 | } | ||
129 | |||
130 | static int goldfish_tty_chars_in_buffer(struct tty_struct *tty) | ||
131 | { | ||
132 | struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; | ||
133 | void __iomem *base = qtty->base; | ||
134 | return readl(base + GOLDFISH_TTY_BYTES_READY); | ||
135 | } | ||
136 | |||
137 | static void goldfish_tty_console_write(struct console *co, const char *b, unsigned count) | ||
138 | { | ||
139 | goldfish_tty_do_write(co->index, b, count); | ||
140 | } | ||
141 | |||
142 | static struct tty_driver *goldfish_tty_console_device(struct console *c, int *index) | ||
143 | { | ||
144 | *index = c->index; | ||
145 | return goldfish_tty_driver; | ||
146 | } | ||
147 | |||
148 | static int goldfish_tty_console_setup(struct console *co, char *options) | ||
149 | { | ||
150 | if((unsigned)co->index > goldfish_tty_line_count) | ||
151 | return -ENODEV; | ||
152 | if(goldfish_ttys[co->index].base == 0) | ||
153 | return -ENODEV; | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static struct tty_port_operations goldfish_port_ops = { | ||
158 | .activate = goldfish_tty_activate, | ||
159 | .shutdown = goldfish_tty_shutdown | ||
160 | }; | ||
161 | |||
162 | static struct tty_operations goldfish_tty_ops = { | ||
163 | .open = goldfish_tty_open, | ||
164 | .close = goldfish_tty_close, | ||
165 | .hangup = goldfish_tty_hangup, | ||
166 | .write = goldfish_tty_write, | ||
167 | .write_room = goldfish_tty_write_room, | ||
168 | .chars_in_buffer = goldfish_tty_chars_in_buffer, | ||
169 | }; | ||
170 | |||
171 | static int goldfish_tty_create_driver(void) | ||
172 | { | ||
173 | int ret; | ||
174 | struct tty_driver *tty; | ||
175 | |||
176 | goldfish_ttys = kzalloc(sizeof(*goldfish_ttys) * goldfish_tty_line_count, GFP_KERNEL); | ||
177 | if(goldfish_ttys == NULL) { | ||
178 | ret = -ENOMEM; | ||
179 | goto err_alloc_goldfish_ttys_failed; | ||
180 | } | ||
181 | tty = alloc_tty_driver(goldfish_tty_line_count); | ||
182 | if(tty == NULL) { | ||
183 | ret = -ENOMEM; | ||
184 | goto err_alloc_tty_driver_failed; | ||
185 | } | ||
186 | tty->driver_name = "goldfish"; | ||
187 | tty->name = "ttyGF"; | ||
188 | tty->type = TTY_DRIVER_TYPE_SERIAL; | ||
189 | tty->subtype = SERIAL_TYPE_NORMAL; | ||
190 | tty->init_termios = tty_std_termios; | ||
191 | tty->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
192 | tty_set_operations(tty, &goldfish_tty_ops); | ||
193 | ret = tty_register_driver(tty); | ||
194 | if(ret) | ||
195 | goto err_tty_register_driver_failed; | ||
196 | |||
197 | goldfish_tty_driver = tty; | ||
198 | return 0; | ||
199 | |||
200 | err_tty_register_driver_failed: | ||
201 | put_tty_driver(tty); | ||
202 | err_alloc_tty_driver_failed: | ||
203 | kfree(goldfish_ttys); | ||
204 | goldfish_ttys = NULL; | ||
205 | err_alloc_goldfish_ttys_failed: | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static void goldfish_tty_delete_driver(void) | ||
210 | { | ||
211 | tty_unregister_driver(goldfish_tty_driver); | ||
212 | put_tty_driver(goldfish_tty_driver); | ||
213 | goldfish_tty_driver = NULL; | ||
214 | kfree(goldfish_ttys); | ||
215 | goldfish_ttys = NULL; | ||
216 | } | ||
217 | |||
218 | static int goldfish_tty_probe(struct platform_device *pdev) | ||
219 | { | ||
220 | struct goldfish_tty *qtty; | ||
221 | int ret = -EINVAL; | ||
222 | int i; | ||
223 | struct resource *r; | ||
224 | struct device *ttydev; | ||
225 | void __iomem *base; | ||
226 | u32 irq; | ||
227 | |||
228 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
229 | if(r == NULL) | ||
230 | return -EINVAL; | ||
231 | |||
232 | base = ioremap(r->start, 0x1000); | ||
233 | if (base == NULL) | ||
234 | pr_err("goldfish_tty: unable to remap base\n"); | ||
235 | |||
236 | r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
237 | if(r == NULL) | ||
238 | goto err_unmap; | ||
239 | |||
240 | irq = r->start; | ||
241 | |||
242 | if(pdev->id >= goldfish_tty_line_count) | ||
243 | goto err_unmap; | ||
244 | |||
245 | mutex_lock(&goldfish_tty_lock); | ||
246 | if(goldfish_tty_current_line_count == 0) { | ||
247 | ret = goldfish_tty_create_driver(); | ||
248 | if(ret) | ||
249 | goto err_create_driver_failed; | ||
250 | } | ||
251 | goldfish_tty_current_line_count++; | ||
252 | |||
253 | qtty = &goldfish_ttys[pdev->id]; | ||
254 | spin_lock_init(&qtty->lock); | ||
255 | tty_port_init(&qtty->port); | ||
256 | qtty->port.ops = &goldfish_port_ops; | ||
257 | qtty->base = base; | ||
258 | qtty->irq = irq; | ||
259 | |||
260 | writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_CMD); | ||
261 | |||
262 | ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED, "goldfish_tty", pdev); | ||
263 | if(ret) | ||
264 | goto err_request_irq_failed; | ||
265 | |||
266 | |||
267 | ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver, | ||
268 | pdev->id, &pdev->dev); | ||
269 | if(IS_ERR(ttydev)) { | ||
270 | ret = PTR_ERR(ttydev); | ||
271 | goto err_tty_register_device_failed; | ||
272 | } | ||
273 | |||
274 | strcpy(qtty->console.name, "ttyGF"); | ||
275 | qtty->console.write = goldfish_tty_console_write; | ||
276 | qtty->console.device = goldfish_tty_console_device; | ||
277 | qtty->console.setup = goldfish_tty_console_setup; | ||
278 | qtty->console.flags = CON_PRINTBUFFER; | ||
279 | qtty->console.index = pdev->id; | ||
280 | register_console(&qtty->console); | ||
281 | |||
282 | mutex_unlock(&goldfish_tty_lock); | ||
283 | return 0; | ||
284 | |||
285 | tty_unregister_device(goldfish_tty_driver, i); | ||
286 | err_tty_register_device_failed: | ||
287 | free_irq(irq, pdev); | ||
288 | err_request_irq_failed: | ||
289 | goldfish_tty_current_line_count--; | ||
290 | if(goldfish_tty_current_line_count == 0) | ||
291 | goldfish_tty_delete_driver(); | ||
292 | err_create_driver_failed: | ||
293 | mutex_unlock(&goldfish_tty_lock); | ||
294 | err_unmap: | ||
295 | iounmap(base); | ||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | static int goldfish_tty_remove(struct platform_device *pdev) | ||
300 | { | ||
301 | struct goldfish_tty *qtty; | ||
302 | |||
303 | mutex_lock(&goldfish_tty_lock); | ||
304 | |||
305 | qtty = &goldfish_ttys[pdev->id]; | ||
306 | unregister_console(&qtty->console); | ||
307 | tty_unregister_device(goldfish_tty_driver, pdev->id); | ||
308 | iounmap(qtty->base); | ||
309 | qtty->base = 0; | ||
310 | free_irq(qtty->irq, pdev); | ||
311 | goldfish_tty_current_line_count--; | ||
312 | if(goldfish_tty_current_line_count == 0) | ||
313 | goldfish_tty_delete_driver(); | ||
314 | mutex_unlock(&goldfish_tty_lock); | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static struct platform_driver goldfish_tty_platform_driver = { | ||
319 | .probe = goldfish_tty_probe, | ||
320 | .remove = goldfish_tty_remove, | ||
321 | .driver = { | ||
322 | .name = "goldfish_tty" | ||
323 | } | ||
324 | }; | ||
325 | |||
326 | module_platform_driver(goldfish_tty_platform_driver); | ||
327 | |||
328 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index f47b734c6a7a..8902f9b4df71 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig | |||
@@ -1,3 +1,5 @@ | |||
1 | if TTY | ||
2 | |||
1 | config HVC_DRIVER | 3 | config HVC_DRIVER |
2 | bool | 4 | bool |
3 | help | 5 | help |
@@ -119,3 +121,4 @@ config HVCS | |||
119 | which will also be compiled when this driver is built as a | 121 | which will also be compiled when this driver is built as a |
120 | module. | 122 | module. |
121 | 123 | ||
124 | endif # TTY | ||
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 13ee53bd0bf6..eb255e807c06 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
@@ -629,7 +629,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
629 | 629 | ||
630 | /* Read data if any */ | 630 | /* Read data if any */ |
631 | for (;;) { | 631 | for (;;) { |
632 | int count = tty_buffer_request_room(tty, N_INBUF); | 632 | int count = tty_buffer_request_room(&hp->port, N_INBUF); |
633 | 633 | ||
634 | /* If flip is full, just reschedule a later read */ | 634 | /* If flip is full, just reschedule a later read */ |
635 | if (count == 0) { | 635 | if (count == 0) { |
@@ -672,7 +672,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
672 | } | 672 | } |
673 | } | 673 | } |
674 | #endif /* CONFIG_MAGIC_SYSRQ */ | 674 | #endif /* CONFIG_MAGIC_SYSRQ */ |
675 | tty_insert_flip_char(tty, buf[i], 0); | 675 | tty_insert_flip_char(&hp->port, buf[i], 0); |
676 | } | 676 | } |
677 | 677 | ||
678 | read_total += n; | 678 | read_total += n; |
@@ -691,7 +691,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
691 | a minimum for performance. */ | 691 | a minimum for performance. */ |
692 | timeout = MIN_TIMEOUT; | 692 | timeout = MIN_TIMEOUT; |
693 | 693 | ||
694 | tty_flip_buffer_push(tty); | 694 | tty_flip_buffer_push(&hp->port); |
695 | } | 695 | } |
696 | tty_kref_put(tty); | 696 | tty_kref_put(tty); |
697 | 697 | ||
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 877635733952..1956593ee89d 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
@@ -609,11 +609,11 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
609 | /* remove the read masks */ | 609 | /* remove the read masks */ |
610 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); | 610 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); |
611 | 611 | ||
612 | if (tty_buffer_request_room(tty, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) { | 612 | if (tty_buffer_request_room(&hvcsd->port, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) { |
613 | got = hvc_get_chars(unit_address, | 613 | got = hvc_get_chars(unit_address, |
614 | &buf[0], | 614 | &buf[0], |
615 | HVCS_BUFF_LEN); | 615 | HVCS_BUFF_LEN); |
616 | tty_insert_flip_string(tty, buf, got); | 616 | tty_insert_flip_string(&hvcsd->port, buf, got); |
617 | } | 617 | } |
618 | 618 | ||
619 | /* Give the TTY time to process the data we just sent. */ | 619 | /* Give the TTY time to process the data we just sent. */ |
@@ -623,7 +623,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
623 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 623 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
624 | /* This is synch because tty->low_latency == 1 */ | 624 | /* This is synch because tty->low_latency == 1 */ |
625 | if(got) | 625 | if(got) |
626 | tty_flip_buffer_push(tty); | 626 | tty_flip_buffer_push(&hvcsd->port); |
627 | 627 | ||
628 | if (!got) { | 628 | if (!got) { |
629 | /* Do this _after_ the flip_buffer_push */ | 629 | /* Do this _after_ the flip_buffer_push */ |
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 68357a6e4de9..ef95a154854a 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c | |||
@@ -329,8 +329,7 @@ static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet) | |||
329 | } | 329 | } |
330 | } | 330 | } |
331 | 331 | ||
332 | static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty, | 332 | static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) |
333 | const char *buf, int len) | ||
334 | { | 333 | { |
335 | int i; | 334 | int i; |
336 | 335 | ||
@@ -346,7 +345,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty, | |||
346 | continue; | 345 | continue; |
347 | } | 346 | } |
348 | #endif /* CONFIG_MAGIC_SYSRQ */ | 347 | #endif /* CONFIG_MAGIC_SYSRQ */ |
349 | tty_insert_flip_char(tty, c, 0); | 348 | tty_insert_flip_char(&hp->port, c, 0); |
350 | } | 349 | } |
351 | } | 350 | } |
352 | 351 | ||
@@ -359,8 +358,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty, | |||
359 | * revisited. | 358 | * revisited. |
360 | */ | 359 | */ |
361 | #define TTY_THRESHOLD_THROTTLE 128 | 360 | #define TTY_THRESHOLD_THROTTLE 128 |
362 | static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty, | 361 | static bool hvsi_recv_data(struct hvsi_struct *hp, const uint8_t *packet) |
363 | const uint8_t *packet) | ||
364 | { | 362 | { |
365 | const struct hvsi_header *header = (const struct hvsi_header *)packet; | 363 | const struct hvsi_header *header = (const struct hvsi_header *)packet; |
366 | const uint8_t *data = packet + sizeof(struct hvsi_header); | 364 | const uint8_t *data = packet + sizeof(struct hvsi_header); |
@@ -377,7 +375,7 @@ static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty, | |||
377 | datalen = TTY_THRESHOLD_THROTTLE; | 375 | datalen = TTY_THRESHOLD_THROTTLE; |
378 | } | 376 | } |
379 | 377 | ||
380 | hvsi_insert_chars(hp, tty, data, datalen); | 378 | hvsi_insert_chars(hp, data, datalen); |
381 | 379 | ||
382 | if (overflow > 0) { | 380 | if (overflow > 0) { |
383 | /* | 381 | /* |
@@ -438,9 +436,7 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty, | |||
438 | case VS_DATA_PACKET_HEADER: | 436 | case VS_DATA_PACKET_HEADER: |
439 | if (!is_open(hp)) | 437 | if (!is_open(hp)) |
440 | break; | 438 | break; |
441 | if (tty == NULL) | 439 | flip = hvsi_recv_data(hp, packet); |
442 | break; /* no tty buffer to put data in */ | ||
443 | flip = hvsi_recv_data(hp, tty, packet); | ||
444 | break; | 440 | break; |
445 | case VS_CONTROL_PACKET_HEADER: | 441 | case VS_CONTROL_PACKET_HEADER: |
446 | hvsi_recv_control(hp, packet, tty, handshake); | 442 | hvsi_recv_control(hp, packet, tty, handshake); |
@@ -469,17 +465,17 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty, | |||
469 | compact_inbuf(hp, packet); | 465 | compact_inbuf(hp, packet); |
470 | 466 | ||
471 | if (flip) | 467 | if (flip) |
472 | tty_flip_buffer_push(tty); | 468 | tty_flip_buffer_push(&hp->port); |
473 | 469 | ||
474 | return 1; | 470 | return 1; |
475 | } | 471 | } |
476 | 472 | ||
477 | static void hvsi_send_overflow(struct hvsi_struct *hp, struct tty_struct *tty) | 473 | static void hvsi_send_overflow(struct hvsi_struct *hp) |
478 | { | 474 | { |
479 | pr_debug("%s: delivering %i bytes overflow\n", __func__, | 475 | pr_debug("%s: delivering %i bytes overflow\n", __func__, |
480 | hp->n_throttle); | 476 | hp->n_throttle); |
481 | 477 | ||
482 | hvsi_insert_chars(hp, tty, hp->throttle_buf, hp->n_throttle); | 478 | hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle); |
483 | hp->n_throttle = 0; | 479 | hp->n_throttle = 0; |
484 | } | 480 | } |
485 | 481 | ||
@@ -514,8 +510,8 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg) | |||
514 | if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) { | 510 | if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) { |
515 | /* we weren't hung up and we weren't throttled, so we can | 511 | /* we weren't hung up and we weren't throttled, so we can |
516 | * deliver the rest now */ | 512 | * deliver the rest now */ |
517 | hvsi_send_overflow(hp, tty); | 513 | hvsi_send_overflow(hp); |
518 | tty_flip_buffer_push(tty); | 514 | tty_flip_buffer_push(&hp->port); |
519 | } | 515 | } |
520 | spin_unlock_irqrestore(&hp->lock, flags); | 516 | spin_unlock_irqrestore(&hp->lock, flags); |
521 | 517 | ||
@@ -1001,8 +997,8 @@ static void hvsi_unthrottle(struct tty_struct *tty) | |||
1001 | 997 | ||
1002 | spin_lock_irqsave(&hp->lock, flags); | 998 | spin_lock_irqsave(&hp->lock, flags); |
1003 | if (hp->n_throttle) { | 999 | if (hp->n_throttle) { |
1004 | hvsi_send_overflow(hp, tty); | 1000 | hvsi_send_overflow(hp); |
1005 | tty_flip_buffer_push(tty); | 1001 | tty_flip_buffer_push(&hp->port); |
1006 | } | 1002 | } |
1007 | spin_unlock_irqrestore(&hp->lock, flags); | 1003 | spin_unlock_irqrestore(&hp->lock, flags); |
1008 | 1004 | ||
@@ -1187,9 +1183,7 @@ static int __init hvsi_console_init(void) | |||
1187 | hvsi_wait = poll_for_state; /* no irqs yet; must poll */ | 1183 | hvsi_wait = poll_for_state; /* no irqs yet; must poll */ |
1188 | 1184 | ||
1189 | /* search device tree for vty nodes */ | 1185 | /* search device tree for vty nodes */ |
1190 | for (vty = of_find_compatible_node(NULL, "serial", "hvterm-protocol"); | 1186 | for_each_compatible_node(vty, "serial", "hvterm-protocol") { |
1191 | vty != NULL; | ||
1192 | vty = of_find_compatible_node(vty, "serial", "hvterm-protocol")) { | ||
1193 | struct hvsi_struct *hp; | 1187 | struct hvsi_struct *hp; |
1194 | const uint32_t *vtermno, *irq; | 1188 | const uint32_t *vtermno, *irq; |
1195 | 1189 | ||
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 2cde13ddf9fc..8fd72ff9436e 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c | |||
@@ -106,7 +106,7 @@ static int ipw_open(struct tty_struct *linux_tty, struct file *filp) | |||
106 | 106 | ||
107 | tty->port.tty = linux_tty; | 107 | tty->port.tty = linux_tty; |
108 | linux_tty->driver_data = tty; | 108 | linux_tty->driver_data = tty; |
109 | linux_tty->low_latency = 1; | 109 | tty->port.low_latency = 1; |
110 | 110 | ||
111 | if (tty->tty_type == TTYTYPE_MODEM) | 111 | if (tty->tty_type == TTYTYPE_MODEM) |
112 | ipwireless_ppp_open(tty->network); | 112 | ipwireless_ppp_open(tty->network); |
@@ -160,15 +160,9 @@ static void ipw_close(struct tty_struct *linux_tty, struct file *filp) | |||
160 | void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, | 160 | void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, |
161 | unsigned int length) | 161 | unsigned int length) |
162 | { | 162 | { |
163 | struct tty_struct *linux_tty; | ||
164 | int work = 0; | 163 | int work = 0; |
165 | 164 | ||
166 | mutex_lock(&tty->ipw_tty_mutex); | 165 | mutex_lock(&tty->ipw_tty_mutex); |
167 | linux_tty = tty->port.tty; | ||
168 | if (linux_tty == NULL) { | ||
169 | mutex_unlock(&tty->ipw_tty_mutex); | ||
170 | return; | ||
171 | } | ||
172 | 166 | ||
173 | if (!tty->port.count) { | 167 | if (!tty->port.count) { |
174 | mutex_unlock(&tty->ipw_tty_mutex); | 168 | mutex_unlock(&tty->ipw_tty_mutex); |
@@ -176,7 +170,7 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, | |||
176 | } | 170 | } |
177 | mutex_unlock(&tty->ipw_tty_mutex); | 171 | mutex_unlock(&tty->ipw_tty_mutex); |
178 | 172 | ||
179 | work = tty_insert_flip_string(linux_tty, data, length); | 173 | work = tty_insert_flip_string(&tty->port, data, length); |
180 | 174 | ||
181 | if (work != length) | 175 | if (work != length) |
182 | printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME | 176 | printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME |
@@ -187,7 +181,7 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, | |||
187 | * This may sleep if ->low_latency is set | 181 | * This may sleep if ->low_latency is set |
188 | */ | 182 | */ |
189 | if (work) | 183 | if (work) |
190 | tty_flip_buffer_push(linux_tty); | 184 | tty_flip_buffer_push(&tty->port); |
191 | } | 185 | } |
192 | 186 | ||
193 | static void ipw_write_packet_sent_callback(void *callback_data, | 187 | static void ipw_write_packet_sent_callback(void *callback_data, |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 3205b2e9090b..858291ca889c 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
@@ -634,10 +634,10 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
634 | break; | 634 | break; |
635 | 635 | ||
636 | case 1: /* Received Break !!! */ | 636 | case 1: /* Received Break !!! */ |
637 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 637 | tty_insert_flip_char(&port->port, 0, TTY_BREAK); |
638 | if (port->port.flags & ASYNC_SAK) | 638 | if (port->port.flags & ASYNC_SAK) |
639 | do_SAK(tty); | 639 | do_SAK(tty); |
640 | tty_flip_buffer_push(tty); | 640 | tty_flip_buffer_push(&port->port); |
641 | break; | 641 | break; |
642 | 642 | ||
643 | case 2: /* Statistics */ | 643 | case 2: /* Statistics */ |
@@ -650,15 +650,15 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
650 | break; | 650 | break; |
651 | } | 651 | } |
652 | } else { /* Data Packet */ | 652 | } else { /* Data Packet */ |
653 | 653 | count = tty_prepare_flip_string(&port->port, &rp, | |
654 | count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); | 654 | byte_count & ~1); |
655 | pr_debug("%s: Can rx %d of %d bytes.\n", | 655 | pr_debug("%s: Can rx %d of %d bytes.\n", |
656 | __func__, count, byte_count); | 656 | __func__, count, byte_count); |
657 | word_count = count >> 1; | 657 | word_count = count >> 1; |
658 | insw(base, rp, word_count); | 658 | insw(base, rp, word_count); |
659 | byte_count -= (word_count << 1); | 659 | byte_count -= (word_count << 1); |
660 | if (count & 0x0001) { | 660 | if (count & 0x0001) { |
661 | tty_insert_flip_char(tty, inw(base) & 0xff, | 661 | tty_insert_flip_char(&port->port, inw(base) & 0xff, |
662 | TTY_NORMAL); | 662 | TTY_NORMAL); |
663 | byte_count -= 2; | 663 | byte_count -= 2; |
664 | } | 664 | } |
@@ -671,7 +671,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
671 | byte_count -= 2; | 671 | byte_count -= 2; |
672 | } | 672 | } |
673 | } | 673 | } |
674 | tty_flip_buffer_push(tty); | 674 | tty_flip_buffer_push(&port->port); |
675 | } | 675 | } |
676 | outw(0x0000, base+0x04); /* enable interrupts */ | 676 | outw(0x0000, base+0x04); /* enable interrupts */ |
677 | spin_unlock(&card->card_lock); | 677 | spin_unlock(&card->card_lock); |
diff --git a/drivers/tty/metag_da.c b/drivers/tty/metag_da.c new file mode 100644 index 000000000000..0e888621f484 --- /dev/null +++ b/drivers/tty/metag_da.c | |||
@@ -0,0 +1,677 @@ | |||
1 | /* | ||
2 | * dashtty.c - tty driver for Dash channels interface. | ||
3 | * | ||
4 | * Copyright (C) 2007,2008,2012 Imagination Technologies | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive | ||
8 | * for more details. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/atomic.h> | ||
13 | #include <linux/completion.h> | ||
14 | #include <linux/console.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/export.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/kthread.h> | ||
20 | #include <linux/mutex.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/serial.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/timer.h> | ||
27 | #include <linux/tty.h> | ||
28 | #include <linux/tty_driver.h> | ||
29 | #include <linux/tty_flip.h> | ||
30 | #include <linux/uaccess.h> | ||
31 | |||
32 | #include <asm/da.h> | ||
33 | |||
34 | /* Channel error codes */ | ||
35 | #define CONAOK 0 | ||
36 | #define CONERR 1 | ||
37 | #define CONBAD 2 | ||
38 | #define CONPRM 3 | ||
39 | #define CONADR 4 | ||
40 | #define CONCNT 5 | ||
41 | #define CONCBF 6 | ||
42 | #define CONCBE 7 | ||
43 | #define CONBSY 8 | ||
44 | |||
45 | /* Default channel for the console */ | ||
46 | #define CONSOLE_CHANNEL 1 | ||
47 | |||
48 | #define NUM_TTY_CHANNELS 6 | ||
49 | |||
50 | /* Auto allocate */ | ||
51 | #define DA_TTY_MAJOR 0 | ||
52 | |||
53 | /* A speedy poll rate helps the userland debug process connection response. | ||
54 | * But, if you set it too high then no other userland processes get much | ||
55 | * of a look in. | ||
56 | */ | ||
57 | #define DA_TTY_POLL (HZ / 50) | ||
58 | |||
59 | /* | ||
60 | * A short put delay improves latency but has a high throughput overhead | ||
61 | */ | ||
62 | #define DA_TTY_PUT_DELAY (HZ / 100) | ||
63 | |||
64 | static atomic_t num_channels_need_poll = ATOMIC_INIT(0); | ||
65 | |||
66 | static struct timer_list poll_timer; | ||
67 | |||
68 | static struct tty_driver *channel_driver; | ||
69 | |||
70 | static struct timer_list put_timer; | ||
71 | static struct task_struct *dashtty_thread; | ||
72 | |||
73 | #define RX_BUF_SIZE 1024 | ||
74 | |||
75 | enum { | ||
76 | INCHR = 1, | ||
77 | OUTCHR, | ||
78 | RDBUF, | ||
79 | WRBUF, | ||
80 | RDSTAT | ||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * struct dashtty_port - Wrapper struct for dashtty tty_port. | ||
85 | * @port: TTY port data | ||
86 | * @rx_lock: Lock for rx_buf. | ||
87 | * This protects between the poll timer and user context. | ||
88 | * It's also held during read SWITCH operations. | ||
89 | * @rx_buf: Read buffer | ||
90 | * @xmit_lock: Lock for xmit_*, and port.xmit_buf. | ||
91 | * This protects between user context and kernel thread. | ||
92 | * It's also held during write SWITCH operations. | ||
93 | * @xmit_cnt: Size of xmit buffer contents | ||
94 | * @xmit_head: Head of xmit buffer where data is written | ||
95 | * @xmit_tail: Tail of xmit buffer where data is read | ||
96 | * @xmit_empty: Completion for xmit buffer being empty | ||
97 | */ | ||
98 | struct dashtty_port { | ||
99 | struct tty_port port; | ||
100 | spinlock_t rx_lock; | ||
101 | void *rx_buf; | ||
102 | struct mutex xmit_lock; | ||
103 | unsigned int xmit_cnt; | ||
104 | unsigned int xmit_head; | ||
105 | unsigned int xmit_tail; | ||
106 | struct completion xmit_empty; | ||
107 | }; | ||
108 | |||
109 | static struct dashtty_port dashtty_ports[NUM_TTY_CHANNELS]; | ||
110 | |||
111 | static atomic_t dashtty_xmit_cnt = ATOMIC_INIT(0); | ||
112 | static wait_queue_head_t dashtty_waitqueue; | ||
113 | |||
114 | /* | ||
115 | * Low-level DA channel access routines | ||
116 | */ | ||
117 | static int chancall(int in_bios_function, int in_channel, | ||
118 | int in_arg2, void *in_arg3, | ||
119 | void *in_arg4) | ||
120 | { | ||
121 | register int bios_function asm("D1Ar1") = in_bios_function; | ||
122 | register int channel asm("D0Ar2") = in_channel; | ||
123 | register int arg2 asm("D1Ar3") = in_arg2; | ||
124 | register void *arg3 asm("D0Ar4") = in_arg3; | ||
125 | register void *arg4 asm("D1Ar5") = in_arg4; | ||
126 | register int bios_call asm("D0Ar6") = 3; | ||
127 | register int result asm("D0Re0"); | ||
128 | |||
129 | asm volatile ( | ||
130 | "MSETL [A0StP++], %6,%4,%2\n\t" | ||
131 | "ADD A0StP, A0StP, #8\n\t" | ||
132 | "SWITCH #0x0C30208\n\t" | ||
133 | "GETD %0, [A0StP+#-8]\n\t" | ||
134 | "SUB A0StP, A0StP, #(4*6)+8\n\t" | ||
135 | : "=d" (result) /* outs */ | ||
136 | : "d" (bios_function), | ||
137 | "d" (channel), | ||
138 | "d" (arg2), | ||
139 | "d" (arg3), | ||
140 | "d" (arg4), | ||
141 | "d" (bios_call) /* ins */ | ||
142 | : "memory"); | ||
143 | |||
144 | return result; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Attempts to fetch count bytes from channel and returns actual count. | ||
149 | */ | ||
150 | static int fetch_data(unsigned int channel) | ||
151 | { | ||
152 | struct dashtty_port *dport = &dashtty_ports[channel]; | ||
153 | int received = 0; | ||
154 | |||
155 | spin_lock_bh(&dport->rx_lock); | ||
156 | /* check the port isn't being shut down */ | ||
157 | if (!dport->rx_buf) | ||
158 | goto unlock; | ||
159 | if (chancall(RDBUF, channel, RX_BUF_SIZE, | ||
160 | (void *)dport->rx_buf, &received) == CONAOK) { | ||
161 | if (received) { | ||
162 | int space; | ||
163 | unsigned char *cbuf; | ||
164 | |||
165 | space = tty_prepare_flip_string(&dport->port, &cbuf, | ||
166 | received); | ||
167 | |||
168 | if (space <= 0) | ||
169 | goto unlock; | ||
170 | |||
171 | memcpy(cbuf, dport->rx_buf, space); | ||
172 | tty_flip_buffer_push(&dport->port); | ||
173 | } | ||
174 | } | ||
175 | unlock: | ||
176 | spin_unlock_bh(&dport->rx_lock); | ||
177 | |||
178 | return received; | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * find_channel_to_poll() - Returns number of the next channel to poll. | ||
183 | * Returns: The number of the next channel to poll, or -1 if none need | ||
184 | * polling. | ||
185 | */ | ||
186 | static int find_channel_to_poll(void) | ||
187 | { | ||
188 | static int last_polled_channel; | ||
189 | int last = last_polled_channel; | ||
190 | int chan; | ||
191 | struct dashtty_port *dport; | ||
192 | |||
193 | for (chan = last + 1; ; ++chan) { | ||
194 | if (chan >= NUM_TTY_CHANNELS) | ||
195 | chan = 0; | ||
196 | |||
197 | dport = &dashtty_ports[chan]; | ||
198 | if (dport->rx_buf) { | ||
199 | last_polled_channel = chan; | ||
200 | return chan; | ||
201 | } | ||
202 | |||
203 | if (chan == last) | ||
204 | break; | ||
205 | } | ||
206 | return -1; | ||
207 | } | ||
208 | |||
209 | /** | ||
210 | * put_channel_data() - Write out a block of channel data. | ||
211 | * @chan: DA channel number. | ||
212 | * | ||
213 | * Write a single block of data out to the debug adapter. If the circular buffer | ||
214 | * is wrapped then only the first block is written. | ||
215 | * | ||
216 | * Returns: 1 if the remote buffer was too full to accept data. | ||
217 | * 0 otherwise. | ||
218 | */ | ||
219 | static int put_channel_data(unsigned int chan) | ||
220 | { | ||
221 | struct dashtty_port *dport; | ||
222 | struct tty_struct *tty; | ||
223 | int number_written; | ||
224 | unsigned int count = 0; | ||
225 | |||
226 | dport = &dashtty_ports[chan]; | ||
227 | mutex_lock(&dport->xmit_lock); | ||
228 | if (dport->xmit_cnt) { | ||
229 | count = min((unsigned int)(SERIAL_XMIT_SIZE - dport->xmit_tail), | ||
230 | dport->xmit_cnt); | ||
231 | chancall(WRBUF, chan, count, | ||
232 | dport->port.xmit_buf + dport->xmit_tail, | ||
233 | &number_written); | ||
234 | dport->xmit_cnt -= number_written; | ||
235 | if (!dport->xmit_cnt) { | ||
236 | /* reset pointers to avoid wraps */ | ||
237 | dport->xmit_head = 0; | ||
238 | dport->xmit_tail = 0; | ||
239 | complete(&dport->xmit_empty); | ||
240 | } else { | ||
241 | dport->xmit_tail += number_written; | ||
242 | if (dport->xmit_tail >= SERIAL_XMIT_SIZE) | ||
243 | dport->xmit_tail -= SERIAL_XMIT_SIZE; | ||
244 | } | ||
245 | atomic_sub(number_written, &dashtty_xmit_cnt); | ||
246 | } | ||
247 | mutex_unlock(&dport->xmit_lock); | ||
248 | |||
249 | /* if we've made more data available, wake up tty */ | ||
250 | if (count && number_written) { | ||
251 | tty = tty_port_tty_get(&dport->port); | ||
252 | if (tty) { | ||
253 | tty_wakeup(tty); | ||
254 | tty_kref_put(tty); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | /* did the write fail? */ | ||
259 | return count && !number_written; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * put_data() - Kernel thread to write out blocks of channel data to DA. | ||
264 | * @arg: Unused. | ||
265 | * | ||
266 | * This kernel thread runs while @dashtty_xmit_cnt != 0, and loops over the | ||
267 | * channels to write out any buffered data. If any of the channels stall due to | ||
268 | * the remote buffer being full, a hold off happens to allow the debugger to | ||
269 | * drain the buffer. | ||
270 | */ | ||
271 | static int put_data(void *arg) | ||
272 | { | ||
273 | unsigned int chan, stall; | ||
274 | |||
275 | __set_current_state(TASK_RUNNING); | ||
276 | while (!kthread_should_stop()) { | ||
277 | /* | ||
278 | * For each channel see if there's anything to transmit in the | ||
279 | * port's xmit_buf. | ||
280 | */ | ||
281 | stall = 0; | ||
282 | for (chan = 0; chan < NUM_TTY_CHANNELS; ++chan) | ||
283 | stall += put_channel_data(chan); | ||
284 | |||
285 | /* | ||
286 | * If some of the buffers are full, hold off for a short while | ||
287 | * to allow them to empty. | ||
288 | */ | ||
289 | if (stall) | ||
290 | msleep(25); | ||
291 | |||
292 | wait_event_interruptible(dashtty_waitqueue, | ||
293 | atomic_read(&dashtty_xmit_cnt)); | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * This gets called every DA_TTY_POLL and polls the channels for data | ||
301 | */ | ||
302 | static void dashtty_timer(unsigned long ignored) | ||
303 | { | ||
304 | int channel; | ||
305 | |||
306 | /* If there are no ports open do nothing and don't poll again. */ | ||
307 | if (!atomic_read(&num_channels_need_poll)) | ||
308 | return; | ||
309 | |||
310 | channel = find_channel_to_poll(); | ||
311 | |||
312 | /* Did we find a channel to poll? */ | ||
313 | if (channel >= 0) | ||
314 | fetch_data(channel); | ||
315 | |||
316 | mod_timer_pinned(&poll_timer, jiffies + DA_TTY_POLL); | ||
317 | } | ||
318 | |||
319 | static void add_poll_timer(struct timer_list *poll_timer) | ||
320 | { | ||
321 | setup_timer(poll_timer, dashtty_timer, 0); | ||
322 | poll_timer->expires = jiffies + DA_TTY_POLL; | ||
323 | |||
324 | /* | ||
325 | * Always attach the timer to the boot CPU. The DA channels are per-CPU | ||
326 | * so all polling should be from a single CPU. | ||
327 | */ | ||
328 | add_timer_on(poll_timer, 0); | ||
329 | } | ||
330 | |||
331 | static int dashtty_port_activate(struct tty_port *port, struct tty_struct *tty) | ||
332 | { | ||
333 | struct dashtty_port *dport = container_of(port, struct dashtty_port, | ||
334 | port); | ||
335 | void *rx_buf; | ||
336 | |||
337 | /* Allocate the buffer we use for writing data */ | ||
338 | if (tty_port_alloc_xmit_buf(port) < 0) | ||
339 | goto err; | ||
340 | |||
341 | /* Allocate the buffer we use for reading data */ | ||
342 | rx_buf = kzalloc(RX_BUF_SIZE, GFP_KERNEL); | ||
343 | if (!rx_buf) | ||
344 | goto err_free_xmit; | ||
345 | |||
346 | spin_lock_bh(&dport->rx_lock); | ||
347 | dport->rx_buf = rx_buf; | ||
348 | spin_unlock_bh(&dport->rx_lock); | ||
349 | |||
350 | /* | ||
351 | * Don't add the poll timer if we're opening a console. This | ||
352 | * avoids the overhead of polling the Dash but means it is not | ||
353 | * possible to have a login on /dev/console. | ||
354 | * | ||
355 | */ | ||
356 | if (dport != &dashtty_ports[CONSOLE_CHANNEL]) | ||
357 | if (atomic_inc_return(&num_channels_need_poll) == 1) | ||
358 | add_poll_timer(&poll_timer); | ||
359 | |||
360 | return 0; | ||
361 | err_free_xmit: | ||
362 | tty_port_free_xmit_buf(port); | ||
363 | err: | ||
364 | return -ENOMEM; | ||
365 | } | ||
366 | |||
367 | static void dashtty_port_shutdown(struct tty_port *port) | ||
368 | { | ||
369 | struct dashtty_port *dport = container_of(port, struct dashtty_port, | ||
370 | port); | ||
371 | void *rx_buf; | ||
372 | unsigned int count; | ||
373 | |||
374 | /* stop reading */ | ||
375 | if (dport != &dashtty_ports[CONSOLE_CHANNEL]) | ||
376 | if (atomic_dec_and_test(&num_channels_need_poll)) | ||
377 | del_timer_sync(&poll_timer); | ||
378 | |||
379 | mutex_lock(&dport->xmit_lock); | ||
380 | count = dport->xmit_cnt; | ||
381 | mutex_unlock(&dport->xmit_lock); | ||
382 | if (count) { | ||
383 | /* | ||
384 | * There's still data to write out, so wake and wait for the | ||
385 | * writer thread to drain the buffer. | ||
386 | */ | ||
387 | del_timer(&put_timer); | ||
388 | wake_up_interruptible(&dashtty_waitqueue); | ||
389 | wait_for_completion(&dport->xmit_empty); | ||
390 | } | ||
391 | |||
392 | /* Null the read buffer (timer could still be running!) */ | ||
393 | spin_lock_bh(&dport->rx_lock); | ||
394 | rx_buf = dport->rx_buf; | ||
395 | dport->rx_buf = NULL; | ||
396 | spin_unlock_bh(&dport->rx_lock); | ||
397 | /* Free the read buffer */ | ||
398 | kfree(rx_buf); | ||
399 | |||
400 | /* Free the write buffer */ | ||
401 | tty_port_free_xmit_buf(port); | ||
402 | } | ||
403 | |||
404 | static const struct tty_port_operations dashtty_port_ops = { | ||
405 | .activate = dashtty_port_activate, | ||
406 | .shutdown = dashtty_port_shutdown, | ||
407 | }; | ||
408 | |||
409 | static int dashtty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
410 | { | ||
411 | return tty_port_install(&dashtty_ports[tty->index].port, driver, tty); | ||
412 | } | ||
413 | |||
414 | static int dashtty_open(struct tty_struct *tty, struct file *filp) | ||
415 | { | ||
416 | return tty_port_open(tty->port, tty, filp); | ||
417 | } | ||
418 | |||
419 | static void dashtty_close(struct tty_struct *tty, struct file *filp) | ||
420 | { | ||
421 | return tty_port_close(tty->port, tty, filp); | ||
422 | } | ||
423 | |||
424 | static void dashtty_hangup(struct tty_struct *tty) | ||
425 | { | ||
426 | int channel; | ||
427 | struct dashtty_port *dport; | ||
428 | |||
429 | channel = tty->index; | ||
430 | dport = &dashtty_ports[channel]; | ||
431 | |||
432 | /* drop any data in the xmit buffer */ | ||
433 | mutex_lock(&dport->xmit_lock); | ||
434 | if (dport->xmit_cnt) { | ||
435 | atomic_sub(dport->xmit_cnt, &dashtty_xmit_cnt); | ||
436 | dport->xmit_cnt = 0; | ||
437 | dport->xmit_head = 0; | ||
438 | dport->xmit_tail = 0; | ||
439 | complete(&dport->xmit_empty); | ||
440 | } | ||
441 | mutex_unlock(&dport->xmit_lock); | ||
442 | |||
443 | tty_port_hangup(tty->port); | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * dashtty_put_timer() - Delayed wake up of kernel thread. | ||
448 | * @ignored: unused | ||
449 | * | ||
450 | * This timer function wakes up the kernel thread if any data exists in the | ||
451 | * buffers. It is used to delay the expensive writeout until the writer has | ||
452 | * stopped writing. | ||
453 | */ | ||
454 | static void dashtty_put_timer(unsigned long ignored) | ||
455 | { | ||
456 | if (atomic_read(&dashtty_xmit_cnt)) | ||
457 | wake_up_interruptible(&dashtty_waitqueue); | ||
458 | } | ||
459 | |||
460 | static int dashtty_write(struct tty_struct *tty, const unsigned char *buf, | ||
461 | int total) | ||
462 | { | ||
463 | int channel, count, block; | ||
464 | struct dashtty_port *dport; | ||
465 | |||
466 | /* Determine the channel */ | ||
467 | channel = tty->index; | ||
468 | dport = &dashtty_ports[channel]; | ||
469 | |||
470 | /* | ||
471 | * Write to output buffer. | ||
472 | * | ||
473 | * The reason that we asynchronously write the buffer is because if we | ||
474 | * were to write the buffer synchronously then because DA channels are | ||
475 | * per-CPU the buffer would be written to the channel of whatever CPU | ||
476 | * we're running on. | ||
477 | * | ||
478 | * What we actually want to happen is have all input and output done on | ||
479 | * one CPU. | ||
480 | */ | ||
481 | mutex_lock(&dport->xmit_lock); | ||
482 | /* work out how many bytes we can write to the xmit buffer */ | ||
483 | total = min(total, (int)(SERIAL_XMIT_SIZE - dport->xmit_cnt)); | ||
484 | atomic_add(total, &dashtty_xmit_cnt); | ||
485 | dport->xmit_cnt += total; | ||
486 | /* write the actual bytes (may need splitting if it wraps) */ | ||
487 | for (count = total; count; count -= block) { | ||
488 | block = min(count, (int)(SERIAL_XMIT_SIZE - dport->xmit_head)); | ||
489 | memcpy(dport->port.xmit_buf + dport->xmit_head, buf, block); | ||
490 | dport->xmit_head += block; | ||
491 | if (dport->xmit_head >= SERIAL_XMIT_SIZE) | ||
492 | dport->xmit_head -= SERIAL_XMIT_SIZE; | ||
493 | buf += block; | ||
494 | } | ||
495 | count = dport->xmit_cnt; | ||
496 | /* xmit buffer no longer empty? */ | ||
497 | if (count) | ||
498 | INIT_COMPLETION(dport->xmit_empty); | ||
499 | mutex_unlock(&dport->xmit_lock); | ||
500 | |||
501 | if (total) { | ||
502 | /* | ||
503 | * If the buffer is full, wake up the kthread, otherwise allow | ||
504 | * some more time for the buffer to fill up a bit before waking | ||
505 | * it. | ||
506 | */ | ||
507 | if (count == SERIAL_XMIT_SIZE) { | ||
508 | del_timer(&put_timer); | ||
509 | wake_up_interruptible(&dashtty_waitqueue); | ||
510 | } else { | ||
511 | mod_timer(&put_timer, jiffies + DA_TTY_PUT_DELAY); | ||
512 | } | ||
513 | } | ||
514 | return total; | ||
515 | } | ||
516 | |||
517 | static int dashtty_write_room(struct tty_struct *tty) | ||
518 | { | ||
519 | struct dashtty_port *dport; | ||
520 | int channel; | ||
521 | int room; | ||
522 | |||
523 | channel = tty->index; | ||
524 | dport = &dashtty_ports[channel]; | ||
525 | |||
526 | /* report the space in the xmit buffer */ | ||
527 | mutex_lock(&dport->xmit_lock); | ||
528 | room = SERIAL_XMIT_SIZE - dport->xmit_cnt; | ||
529 | mutex_unlock(&dport->xmit_lock); | ||
530 | |||
531 | return room; | ||
532 | } | ||
533 | |||
534 | static int dashtty_chars_in_buffer(struct tty_struct *tty) | ||
535 | { | ||
536 | struct dashtty_port *dport; | ||
537 | int channel; | ||
538 | int chars; | ||
539 | |||
540 | channel = tty->index; | ||
541 | dport = &dashtty_ports[channel]; | ||
542 | |||
543 | /* report the number of bytes in the xmit buffer */ | ||
544 | mutex_lock(&dport->xmit_lock); | ||
545 | chars = dport->xmit_cnt; | ||
546 | mutex_unlock(&dport->xmit_lock); | ||
547 | |||
548 | return chars; | ||
549 | } | ||
550 | |||
551 | static const struct tty_operations dashtty_ops = { | ||
552 | .install = dashtty_install, | ||
553 | .open = dashtty_open, | ||
554 | .close = dashtty_close, | ||
555 | .hangup = dashtty_hangup, | ||
556 | .write = dashtty_write, | ||
557 | .write_room = dashtty_write_room, | ||
558 | .chars_in_buffer = dashtty_chars_in_buffer, | ||
559 | }; | ||
560 | |||
561 | static int __init dashtty_init(void) | ||
562 | { | ||
563 | int ret; | ||
564 | int nport; | ||
565 | struct dashtty_port *dport; | ||
566 | |||
567 | if (!metag_da_enabled()) | ||
568 | return -ENODEV; | ||
569 | |||
570 | channel_driver = tty_alloc_driver(NUM_TTY_CHANNELS, | ||
571 | TTY_DRIVER_REAL_RAW); | ||
572 | if (IS_ERR(channel_driver)) | ||
573 | return PTR_ERR(channel_driver); | ||
574 | |||
575 | channel_driver->driver_name = "metag_da"; | ||
576 | channel_driver->name = "ttyDA"; | ||
577 | channel_driver->major = DA_TTY_MAJOR; | ||
578 | channel_driver->minor_start = 0; | ||
579 | channel_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
580 | channel_driver->subtype = SERIAL_TYPE_NORMAL; | ||
581 | channel_driver->init_termios = tty_std_termios; | ||
582 | channel_driver->init_termios.c_cflag |= CLOCAL; | ||
583 | |||
584 | tty_set_operations(channel_driver, &dashtty_ops); | ||
585 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
586 | dport = &dashtty_ports[nport]; | ||
587 | tty_port_init(&dport->port); | ||
588 | dport->port.ops = &dashtty_port_ops; | ||
589 | spin_lock_init(&dport->rx_lock); | ||
590 | mutex_init(&dport->xmit_lock); | ||
591 | /* the xmit buffer starts empty, i.e. completely written */ | ||
592 | init_completion(&dport->xmit_empty); | ||
593 | complete(&dport->xmit_empty); | ||
594 | } | ||
595 | |||
596 | setup_timer(&put_timer, dashtty_put_timer, 0); | ||
597 | |||
598 | init_waitqueue_head(&dashtty_waitqueue); | ||
599 | dashtty_thread = kthread_create(put_data, NULL, "ttyDA"); | ||
600 | if (IS_ERR(dashtty_thread)) { | ||
601 | pr_err("Couldn't create dashtty thread\n"); | ||
602 | ret = PTR_ERR(dashtty_thread); | ||
603 | goto err_destroy_ports; | ||
604 | } | ||
605 | /* | ||
606 | * Bind the writer thread to the boot CPU so it can't migrate. | ||
607 | * DA channels are per-CPU and we want all channel I/O to be on a single | ||
608 | * predictable CPU. | ||
609 | */ | ||
610 | kthread_bind(dashtty_thread, 0); | ||
611 | wake_up_process(dashtty_thread); | ||
612 | |||
613 | ret = tty_register_driver(channel_driver); | ||
614 | |||
615 | if (ret < 0) { | ||
616 | pr_err("Couldn't install dashtty driver: err %d\n", | ||
617 | ret); | ||
618 | goto err_stop_kthread; | ||
619 | } | ||
620 | |||
621 | return 0; | ||
622 | |||
623 | err_stop_kthread: | ||
624 | kthread_stop(dashtty_thread); | ||
625 | err_destroy_ports: | ||
626 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
627 | dport = &dashtty_ports[nport]; | ||
628 | tty_port_destroy(&dport->port); | ||
629 | } | ||
630 | put_tty_driver(channel_driver); | ||
631 | return ret; | ||
632 | } | ||
633 | |||
634 | static void dashtty_exit(void) | ||
635 | { | ||
636 | int nport; | ||
637 | struct dashtty_port *dport; | ||
638 | |||
639 | del_timer_sync(&put_timer); | ||
640 | kthread_stop(dashtty_thread); | ||
641 | del_timer_sync(&poll_timer); | ||
642 | tty_unregister_driver(channel_driver); | ||
643 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
644 | dport = &dashtty_ports[nport]; | ||
645 | tty_port_destroy(&dport->port); | ||
646 | } | ||
647 | put_tty_driver(channel_driver); | ||
648 | } | ||
649 | |||
650 | module_init(dashtty_init); | ||
651 | module_exit(dashtty_exit); | ||
652 | |||
653 | #ifdef CONFIG_DA_CONSOLE | ||
654 | |||
655 | static void dash_console_write(struct console *co, const char *s, | ||
656 | unsigned int count) | ||
657 | { | ||
658 | int actually_written; | ||
659 | |||
660 | chancall(WRBUF, CONSOLE_CHANNEL, count, (void *)s, &actually_written); | ||
661 | } | ||
662 | |||
663 | static struct tty_driver *dash_console_device(struct console *c, int *index) | ||
664 | { | ||
665 | *index = c->index; | ||
666 | return channel_driver; | ||
667 | } | ||
668 | |||
669 | struct console dash_console = { | ||
670 | .name = "ttyDA", | ||
671 | .write = dash_console_write, | ||
672 | .device = dash_console_device, | ||
673 | .flags = CON_PRINTBUFFER, | ||
674 | .index = 1, | ||
675 | }; | ||
676 | |||
677 | #endif | ||
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index f9d28503bdec..adeac255e526 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
@@ -1405,7 +1405,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1405 | if (inited && !test_bit(TTY_THROTTLED, &tty->flags) && | 1405 | if (inited && !test_bit(TTY_THROTTLED, &tty->flags) && |
1406 | MoxaPortRxQueue(p) > 0) { /* RX */ | 1406 | MoxaPortRxQueue(p) > 0) { /* RX */ |
1407 | MoxaPortReadData(p); | 1407 | MoxaPortReadData(p); |
1408 | tty_schedule_flip(tty); | 1408 | tty_schedule_flip(&p->port); |
1409 | } | 1409 | } |
1410 | } else { | 1410 | } else { |
1411 | clear_bit(EMPTYWAIT, &p->statusflags); | 1411 | clear_bit(EMPTYWAIT, &p->statusflags); |
@@ -1429,8 +1429,8 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1429 | goto put; | 1429 | goto put; |
1430 | 1430 | ||
1431 | if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ | 1431 | if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ |
1432 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1432 | tty_insert_flip_char(&p->port, 0, TTY_BREAK); |
1433 | tty_schedule_flip(tty); | 1433 | tty_schedule_flip(&p->port); |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | if (intr & IntrLine) | 1436 | if (intr & IntrLine) |
@@ -1966,7 +1966,7 @@ static int MoxaPortReadData(struct moxa_port *port) | |||
1966 | ofs = baseAddr + DynPage_addr + bufhead + head; | 1966 | ofs = baseAddr + DynPage_addr + bufhead + head; |
1967 | len = (tail >= head) ? (tail - head) : | 1967 | len = (tail >= head) ? (tail - head) : |
1968 | (rx_mask + 1 - head); | 1968 | (rx_mask + 1 - head); |
1969 | len = tty_prepare_flip_string(tty, &dst, | 1969 | len = tty_prepare_flip_string(&port->port, &dst, |
1970 | min(len, count)); | 1970 | min(len, count)); |
1971 | memcpy_fromio(dst, ofs, len); | 1971 | memcpy_fromio(dst, ofs, len); |
1972 | head = (head + len) & rx_mask; | 1972 | head = (head + len) & rx_mask; |
@@ -1978,7 +1978,7 @@ static int MoxaPortReadData(struct moxa_port *port) | |||
1978 | while (count > 0) { | 1978 | while (count > 0) { |
1979 | writew(pageno, baseAddr + Control_reg); | 1979 | writew(pageno, baseAddr + Control_reg); |
1980 | ofs = baseAddr + DynPage_addr + pageofs; | 1980 | ofs = baseAddr + DynPage_addr + pageofs; |
1981 | len = tty_prepare_flip_string(tty, &dst, | 1981 | len = tty_prepare_flip_string(&port->port, &dst, |
1982 | min(Page_size - pageofs, count)); | 1982 | min(Page_size - pageofs, count)); |
1983 | memcpy_fromio(dst, ofs, len); | 1983 | memcpy_fromio(dst, ofs, len); |
1984 | 1984 | ||
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 40113868bec2..484b6a3c9b03 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -1264,7 +1264,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1264 | (new_serial.flags & ASYNC_FLAGS)); | 1264 | (new_serial.flags & ASYNC_FLAGS)); |
1265 | port->close_delay = new_serial.close_delay * HZ / 100; | 1265 | port->close_delay = new_serial.close_delay * HZ / 100; |
1266 | port->closing_wait = new_serial.closing_wait * HZ / 100; | 1266 | port->closing_wait = new_serial.closing_wait * HZ / 100; |
1267 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1267 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1268 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && | 1268 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && |
1269 | (new_serial.baud_base != info->baud_base || | 1269 | (new_serial.baud_base != info->baud_base || |
1270 | new_serial.custom_divisor != | 1270 | new_serial.custom_divisor != |
@@ -2079,7 +2079,7 @@ static void mxser_receive_chars(struct tty_struct *tty, | |||
2079 | } | 2079 | } |
2080 | while (gdl--) { | 2080 | while (gdl--) { |
2081 | ch = inb(port->ioaddr + UART_RX); | 2081 | ch = inb(port->ioaddr + UART_RX); |
2082 | tty_insert_flip_char(tty, ch, 0); | 2082 | tty_insert_flip_char(&port->port, ch, 0); |
2083 | cnt++; | 2083 | cnt++; |
2084 | } | 2084 | } |
2085 | goto end_intr; | 2085 | goto end_intr; |
@@ -2118,7 +2118,7 @@ intr_old: | |||
2118 | } else | 2118 | } else |
2119 | flag = TTY_BREAK; | 2119 | flag = TTY_BREAK; |
2120 | } | 2120 | } |
2121 | tty_insert_flip_char(tty, ch, flag); | 2121 | tty_insert_flip_char(&port->port, ch, flag); |
2122 | cnt++; | 2122 | cnt++; |
2123 | if (cnt >= recv_room) { | 2123 | if (cnt >= recv_room) { |
2124 | if (!port->ldisc_stop_rx) | 2124 | if (!port->ldisc_stop_rx) |
@@ -2145,7 +2145,7 @@ end_intr: | |||
2145 | * recursive locking. | 2145 | * recursive locking. |
2146 | */ | 2146 | */ |
2147 | spin_unlock(&port->slock); | 2147 | spin_unlock(&port->slock); |
2148 | tty_flip_buffer_push(tty); | 2148 | tty_flip_buffer_push(&port->port); |
2149 | spin_lock(&port->slock); | 2149 | spin_lock(&port->slock); |
2150 | } | 2150 | } |
2151 | 2151 | ||
@@ -2364,7 +2364,6 @@ static void mxser_release_vector(struct mxser_board *brd) | |||
2364 | 2364 | ||
2365 | static void mxser_release_ISA_res(struct mxser_board *brd) | 2365 | static void mxser_release_ISA_res(struct mxser_board *brd) |
2366 | { | 2366 | { |
2367 | free_irq(brd->irq, brd); | ||
2368 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | 2367 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); |
2369 | mxser_release_vector(brd); | 2368 | mxser_release_vector(brd); |
2370 | } | 2369 | } |
@@ -2430,6 +2429,7 @@ static void mxser_board_remove(struct mxser_board *brd) | |||
2430 | tty_unregister_device(mxvar_sdriver, brd->idx + i); | 2429 | tty_unregister_device(mxvar_sdriver, brd->idx + i); |
2431 | tty_port_destroy(&brd->ports[i].port); | 2430 | tty_port_destroy(&brd->ports[i].port); |
2432 | } | 2431 | } |
2432 | free_irq(brd->irq, brd); | ||
2433 | } | 2433 | } |
2434 | 2434 | ||
2435 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | 2435 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) |
@@ -2554,6 +2554,7 @@ static int mxser_probe(struct pci_dev *pdev, | |||
2554 | struct mxser_board *brd; | 2554 | struct mxser_board *brd; |
2555 | unsigned int i, j; | 2555 | unsigned int i, j; |
2556 | unsigned long ioaddress; | 2556 | unsigned long ioaddress; |
2557 | struct device *tty_dev; | ||
2557 | int retval = -EINVAL; | 2558 | int retval = -EINVAL; |
2558 | 2559 | ||
2559 | for (i = 0; i < MXSER_BOARDS; i++) | 2560 | for (i = 0; i < MXSER_BOARDS; i++) |
@@ -2637,13 +2638,25 @@ static int mxser_probe(struct pci_dev *pdev, | |||
2637 | if (retval) | 2638 | if (retval) |
2638 | goto err_rel3; | 2639 | goto err_rel3; |
2639 | 2640 | ||
2640 | for (i = 0; i < brd->info->nports; i++) | 2641 | for (i = 0; i < brd->info->nports; i++) { |
2641 | tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, | 2642 | tty_dev = tty_port_register_device(&brd->ports[i].port, |
2642 | brd->idx + i, &pdev->dev); | 2643 | mxvar_sdriver, brd->idx + i, &pdev->dev); |
2644 | if (IS_ERR(tty_dev)) { | ||
2645 | retval = PTR_ERR(tty_dev); | ||
2646 | for (i--; i >= 0; i--) | ||
2647 | tty_unregister_device(mxvar_sdriver, | ||
2648 | brd->idx + i); | ||
2649 | goto err_relbrd; | ||
2650 | } | ||
2651 | } | ||
2643 | 2652 | ||
2644 | pci_set_drvdata(pdev, brd); | 2653 | pci_set_drvdata(pdev, brd); |
2645 | 2654 | ||
2646 | return 0; | 2655 | return 0; |
2656 | err_relbrd: | ||
2657 | for (i = 0; i < brd->info->nports; i++) | ||
2658 | tty_port_destroy(&brd->ports[i].port); | ||
2659 | free_irq(brd->irq, brd); | ||
2647 | err_rel3: | 2660 | err_rel3: |
2648 | pci_release_region(pdev, 3); | 2661 | pci_release_region(pdev, 3); |
2649 | err_zero: | 2662 | err_zero: |
@@ -2665,7 +2678,6 @@ static void mxser_remove(struct pci_dev *pdev) | |||
2665 | 2678 | ||
2666 | mxser_board_remove(brd); | 2679 | mxser_board_remove(brd); |
2667 | 2680 | ||
2668 | free_irq(pdev->irq, brd); | ||
2669 | pci_release_region(pdev, 2); | 2681 | pci_release_region(pdev, 2); |
2670 | pci_release_region(pdev, 3); | 2682 | pci_release_region(pdev, 3); |
2671 | pci_disable_device(pdev); | 2683 | pci_disable_device(pdev); |
@@ -2683,6 +2695,7 @@ static struct pci_driver mxser_driver = { | |||
2683 | static int __init mxser_module_init(void) | 2695 | static int __init mxser_module_init(void) |
2684 | { | 2696 | { |
2685 | struct mxser_board *brd; | 2697 | struct mxser_board *brd; |
2698 | struct device *tty_dev; | ||
2686 | unsigned int b, i, m; | 2699 | unsigned int b, i, m; |
2687 | int retval; | 2700 | int retval; |
2688 | 2701 | ||
@@ -2728,14 +2741,29 @@ static int __init mxser_module_init(void) | |||
2728 | 2741 | ||
2729 | /* mxser_initbrd will hook ISR. */ | 2742 | /* mxser_initbrd will hook ISR. */ |
2730 | if (mxser_initbrd(brd, NULL) < 0) { | 2743 | if (mxser_initbrd(brd, NULL) < 0) { |
2744 | mxser_release_ISA_res(brd); | ||
2731 | brd->info = NULL; | 2745 | brd->info = NULL; |
2732 | continue; | 2746 | continue; |
2733 | } | 2747 | } |
2734 | 2748 | ||
2735 | brd->idx = m * MXSER_PORTS_PER_BOARD; | 2749 | brd->idx = m * MXSER_PORTS_PER_BOARD; |
2736 | for (i = 0; i < brd->info->nports; i++) | 2750 | for (i = 0; i < brd->info->nports; i++) { |
2737 | tty_port_register_device(&brd->ports[i].port, | 2751 | tty_dev = tty_port_register_device(&brd->ports[i].port, |
2738 | mxvar_sdriver, brd->idx + i, NULL); | 2752 | mxvar_sdriver, brd->idx + i, NULL); |
2753 | if (IS_ERR(tty_dev)) { | ||
2754 | for (i--; i >= 0; i--) | ||
2755 | tty_unregister_device(mxvar_sdriver, | ||
2756 | brd->idx + i); | ||
2757 | for (i = 0; i < brd->info->nports; i++) | ||
2758 | tty_port_destroy(&brd->ports[i].port); | ||
2759 | free_irq(brd->irq, brd); | ||
2760 | mxser_release_ISA_res(brd); | ||
2761 | brd->info = NULL; | ||
2762 | break; | ||
2763 | } | ||
2764 | } | ||
2765 | if (brd->info == NULL) | ||
2766 | continue; | ||
2739 | 2767 | ||
2740 | m++; | 2768 | m++; |
2741 | } | 2769 | } |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index dcc0430a49c8..4a43ef5d7962 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -1067,9 +1067,9 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1067 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) | 1067 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) |
1068 | if (!(tty->termios.c_cflag & CLOCAL)) | 1068 | if (!(tty->termios.c_cflag & CLOCAL)) |
1069 | tty_hangup(tty); | 1069 | tty_hangup(tty); |
1070 | if (brk & 0x01) | ||
1071 | tty_insert_flip_char(tty, 0, TTY_BREAK); | ||
1072 | } | 1070 | } |
1071 | if (brk & 0x01) | ||
1072 | tty_insert_flip_char(&dlci->port, 0, TTY_BREAK); | ||
1073 | dlci->modem_rx = mlines; | 1073 | dlci->modem_rx = mlines; |
1074 | } | 1074 | } |
1075 | 1075 | ||
@@ -1137,7 +1137,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen) | |||
1137 | 1137 | ||
1138 | static void gsm_control_rls(struct gsm_mux *gsm, u8 *data, int clen) | 1138 | static void gsm_control_rls(struct gsm_mux *gsm, u8 *data, int clen) |
1139 | { | 1139 | { |
1140 | struct tty_struct *tty; | 1140 | struct tty_port *port; |
1141 | unsigned int addr = 0 ; | 1141 | unsigned int addr = 0 ; |
1142 | u8 bits; | 1142 | u8 bits; |
1143 | int len = clen; | 1143 | int len = clen; |
@@ -1160,19 +1160,18 @@ static void gsm_control_rls(struct gsm_mux *gsm, u8 *data, int clen) | |||
1160 | bits = *dp; | 1160 | bits = *dp; |
1161 | if ((bits & 1) == 0) | 1161 | if ((bits & 1) == 0) |
1162 | return; | 1162 | return; |
1163 | /* See if we have an uplink tty */ | ||
1164 | tty = tty_port_tty_get(&gsm->dlci[addr]->port); | ||
1165 | 1163 | ||
1166 | if (tty) { | 1164 | port = &gsm->dlci[addr]->port; |
1167 | if (bits & 2) | 1165 | |
1168 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1166 | if (bits & 2) |
1169 | if (bits & 4) | 1167 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
1170 | tty_insert_flip_char(tty, 0, TTY_PARITY); | 1168 | if (bits & 4) |
1171 | if (bits & 8) | 1169 | tty_insert_flip_char(port, 0, TTY_PARITY); |
1172 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 1170 | if (bits & 8) |
1173 | tty_flip_buffer_push(tty); | 1171 | tty_insert_flip_char(port, 0, TTY_FRAME); |
1174 | tty_kref_put(tty); | 1172 | |
1175 | } | 1173 | tty_flip_buffer_push(port); |
1174 | |||
1176 | gsm_control_reply(gsm, CMD_RLS, data, clen); | 1175 | gsm_control_reply(gsm, CMD_RLS, data, clen); |
1177 | } | 1176 | } |
1178 | 1177 | ||
@@ -1545,36 +1544,37 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int clen) | |||
1545 | { | 1544 | { |
1546 | /* krefs .. */ | 1545 | /* krefs .. */ |
1547 | struct tty_port *port = &dlci->port; | 1546 | struct tty_port *port = &dlci->port; |
1548 | struct tty_struct *tty = tty_port_tty_get(port); | 1547 | struct tty_struct *tty; |
1549 | unsigned int modem = 0; | 1548 | unsigned int modem = 0; |
1550 | int len = clen; | 1549 | int len = clen; |
1551 | 1550 | ||
1552 | if (debug & 16) | 1551 | if (debug & 16) |
1553 | pr_debug("%d bytes for tty %p\n", len, tty); | 1552 | pr_debug("%d bytes for tty\n", len); |
1554 | if (tty) { | 1553 | switch (dlci->adaption) { |
1555 | switch (dlci->adaption) { | 1554 | /* Unsupported types */ |
1556 | /* Unsupported types */ | 1555 | /* Packetised interruptible data */ |
1557 | /* Packetised interruptible data */ | 1556 | case 4: |
1558 | case 4: | 1557 | break; |
1559 | break; | 1558 | /* Packetised uininterruptible voice/data */ |
1560 | /* Packetised uininterruptible voice/data */ | 1559 | case 3: |
1561 | case 3: | 1560 | break; |
1562 | break; | 1561 | /* Asynchronous serial with line state in each frame */ |
1563 | /* Asynchronous serial with line state in each frame */ | 1562 | case 2: |
1564 | case 2: | 1563 | while (gsm_read_ea(&modem, *data++) == 0) { |
1565 | while (gsm_read_ea(&modem, *data++) == 0) { | 1564 | len--; |
1566 | len--; | 1565 | if (len == 0) |
1567 | if (len == 0) | 1566 | return; |
1568 | return; | 1567 | } |
1569 | } | 1568 | tty = tty_port_tty_get(port); |
1569 | if (tty) { | ||
1570 | gsm_process_modem(tty, dlci, modem, clen); | 1570 | gsm_process_modem(tty, dlci, modem, clen); |
1571 | /* Line state will go via DLCI 0 controls only */ | 1571 | tty_kref_put(tty); |
1572 | case 1: | ||
1573 | default: | ||
1574 | tty_insert_flip_string(tty, data, len); | ||
1575 | tty_flip_buffer_push(tty); | ||
1576 | } | 1572 | } |
1577 | tty_kref_put(tty); | 1573 | /* Line state will go via DLCI 0 controls only */ |
1574 | case 1: | ||
1575 | default: | ||
1576 | tty_insert_flip_string(port, data, len); | ||
1577 | tty_flip_buffer_push(port); | ||
1578 | } | 1578 | } |
1579 | } | 1579 | } |
1580 | 1580 | ||
@@ -1689,6 +1689,8 @@ static inline void dlci_put(struct gsm_dlci *dlci) | |||
1689 | tty_port_put(&dlci->port); | 1689 | tty_port_put(&dlci->port); |
1690 | } | 1690 | } |
1691 | 1691 | ||
1692 | static void gsm_destroy_network(struct gsm_dlci *dlci); | ||
1693 | |||
1692 | /** | 1694 | /** |
1693 | * gsm_dlci_release - release DLCI | 1695 | * gsm_dlci_release - release DLCI |
1694 | * @dlci: DLCI to destroy | 1696 | * @dlci: DLCI to destroy |
@@ -1702,9 +1704,19 @@ static void gsm_dlci_release(struct gsm_dlci *dlci) | |||
1702 | { | 1704 | { |
1703 | struct tty_struct *tty = tty_port_tty_get(&dlci->port); | 1705 | struct tty_struct *tty = tty_port_tty_get(&dlci->port); |
1704 | if (tty) { | 1706 | if (tty) { |
1707 | mutex_lock(&dlci->mutex); | ||
1708 | gsm_destroy_network(dlci); | ||
1709 | mutex_unlock(&dlci->mutex); | ||
1710 | |||
1711 | /* tty_vhangup needs the tty_lock, so unlock and | ||
1712 | relock after doing the hangup. */ | ||
1713 | tty_unlock(tty); | ||
1705 | tty_vhangup(tty); | 1714 | tty_vhangup(tty); |
1715 | tty_lock(tty); | ||
1716 | tty_port_tty_set(&dlci->port, NULL); | ||
1706 | tty_kref_put(tty); | 1717 | tty_kref_put(tty); |
1707 | } | 1718 | } |
1719 | dlci->state = DLCI_CLOSED; | ||
1708 | dlci_put(dlci); | 1720 | dlci_put(dlci); |
1709 | } | 1721 | } |
1710 | 1722 | ||
@@ -2947,6 +2959,8 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) | |||
2947 | 2959 | ||
2948 | if (dlci == NULL) | 2960 | if (dlci == NULL) |
2949 | return; | 2961 | return; |
2962 | if (dlci->state == DLCI_CLOSED) | ||
2963 | return; | ||
2950 | mutex_lock(&dlci->mutex); | 2964 | mutex_lock(&dlci->mutex); |
2951 | gsm_destroy_network(dlci); | 2965 | gsm_destroy_network(dlci); |
2952 | mutex_unlock(&dlci->mutex); | 2966 | mutex_unlock(&dlci->mutex); |
@@ -2965,6 +2979,8 @@ out: | |||
2965 | static void gsmtty_hangup(struct tty_struct *tty) | 2979 | static void gsmtty_hangup(struct tty_struct *tty) |
2966 | { | 2980 | { |
2967 | struct gsm_dlci *dlci = tty->driver_data; | 2981 | struct gsm_dlci *dlci = tty->driver_data; |
2982 | if (dlci->state == DLCI_CLOSED) | ||
2983 | return; | ||
2968 | tty_port_hangup(&dlci->port); | 2984 | tty_port_hangup(&dlci->port); |
2969 | gsm_dlci_begin_close(dlci); | 2985 | gsm_dlci_begin_close(dlci); |
2970 | } | 2986 | } |
@@ -2972,9 +2988,12 @@ static void gsmtty_hangup(struct tty_struct *tty) | |||
2972 | static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf, | 2988 | static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf, |
2973 | int len) | 2989 | int len) |
2974 | { | 2990 | { |
2991 | int sent; | ||
2975 | struct gsm_dlci *dlci = tty->driver_data; | 2992 | struct gsm_dlci *dlci = tty->driver_data; |
2993 | if (dlci->state == DLCI_CLOSED) | ||
2994 | return -EINVAL; | ||
2976 | /* Stuff the bytes into the fifo queue */ | 2995 | /* Stuff the bytes into the fifo queue */ |
2977 | int sent = kfifo_in_locked(dlci->fifo, buf, len, &dlci->lock); | 2996 | sent = kfifo_in_locked(dlci->fifo, buf, len, &dlci->lock); |
2978 | /* Need to kick the channel */ | 2997 | /* Need to kick the channel */ |
2979 | gsm_dlci_data_kick(dlci); | 2998 | gsm_dlci_data_kick(dlci); |
2980 | return sent; | 2999 | return sent; |
@@ -2983,18 +3002,24 @@ static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf, | |||
2983 | static int gsmtty_write_room(struct tty_struct *tty) | 3002 | static int gsmtty_write_room(struct tty_struct *tty) |
2984 | { | 3003 | { |
2985 | struct gsm_dlci *dlci = tty->driver_data; | 3004 | struct gsm_dlci *dlci = tty->driver_data; |
3005 | if (dlci->state == DLCI_CLOSED) | ||
3006 | return -EINVAL; | ||
2986 | return TX_SIZE - kfifo_len(dlci->fifo); | 3007 | return TX_SIZE - kfifo_len(dlci->fifo); |
2987 | } | 3008 | } |
2988 | 3009 | ||
2989 | static int gsmtty_chars_in_buffer(struct tty_struct *tty) | 3010 | static int gsmtty_chars_in_buffer(struct tty_struct *tty) |
2990 | { | 3011 | { |
2991 | struct gsm_dlci *dlci = tty->driver_data; | 3012 | struct gsm_dlci *dlci = tty->driver_data; |
3013 | if (dlci->state == DLCI_CLOSED) | ||
3014 | return -EINVAL; | ||
2992 | return kfifo_len(dlci->fifo); | 3015 | return kfifo_len(dlci->fifo); |
2993 | } | 3016 | } |
2994 | 3017 | ||
2995 | static void gsmtty_flush_buffer(struct tty_struct *tty) | 3018 | static void gsmtty_flush_buffer(struct tty_struct *tty) |
2996 | { | 3019 | { |
2997 | struct gsm_dlci *dlci = tty->driver_data; | 3020 | struct gsm_dlci *dlci = tty->driver_data; |
3021 | if (dlci->state == DLCI_CLOSED) | ||
3022 | return; | ||
2998 | /* Caution needed: If we implement reliable transport classes | 3023 | /* Caution needed: If we implement reliable transport classes |
2999 | then the data being transmitted can't simply be junked once | 3024 | then the data being transmitted can't simply be junked once |
3000 | it has first hit the stack. Until then we can just blow it | 3025 | it has first hit the stack. Until then we can just blow it |
@@ -3013,6 +3038,8 @@ static void gsmtty_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3013 | static int gsmtty_tiocmget(struct tty_struct *tty) | 3038 | static int gsmtty_tiocmget(struct tty_struct *tty) |
3014 | { | 3039 | { |
3015 | struct gsm_dlci *dlci = tty->driver_data; | 3040 | struct gsm_dlci *dlci = tty->driver_data; |
3041 | if (dlci->state == DLCI_CLOSED) | ||
3042 | return -EINVAL; | ||
3016 | return dlci->modem_rx; | 3043 | return dlci->modem_rx; |
3017 | } | 3044 | } |
3018 | 3045 | ||
@@ -3022,6 +3049,8 @@ static int gsmtty_tiocmset(struct tty_struct *tty, | |||
3022 | struct gsm_dlci *dlci = tty->driver_data; | 3049 | struct gsm_dlci *dlci = tty->driver_data; |
3023 | unsigned int modem_tx = dlci->modem_tx; | 3050 | unsigned int modem_tx = dlci->modem_tx; |
3024 | 3051 | ||
3052 | if (dlci->state == DLCI_CLOSED) | ||
3053 | return -EINVAL; | ||
3025 | modem_tx &= ~clear; | 3054 | modem_tx &= ~clear; |
3026 | modem_tx |= set; | 3055 | modem_tx |= set; |
3027 | 3056 | ||
@@ -3040,6 +3069,8 @@ static int gsmtty_ioctl(struct tty_struct *tty, | |||
3040 | struct gsm_netconfig nc; | 3069 | struct gsm_netconfig nc; |
3041 | int index; | 3070 | int index; |
3042 | 3071 | ||
3072 | if (dlci->state == DLCI_CLOSED) | ||
3073 | return -EINVAL; | ||
3043 | switch (cmd) { | 3074 | switch (cmd) { |
3044 | case GSMIOC_ENABLE_NET: | 3075 | case GSMIOC_ENABLE_NET: |
3045 | if (copy_from_user(&nc, (void __user *)arg, sizeof(nc))) | 3076 | if (copy_from_user(&nc, (void __user *)arg, sizeof(nc))) |
@@ -3066,6 +3097,9 @@ static int gsmtty_ioctl(struct tty_struct *tty, | |||
3066 | 3097 | ||
3067 | static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) | 3098 | static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) |
3068 | { | 3099 | { |
3100 | struct gsm_dlci *dlci = tty->driver_data; | ||
3101 | if (dlci->state == DLCI_CLOSED) | ||
3102 | return; | ||
3069 | /* For the moment its fixed. In actual fact the speed information | 3103 | /* For the moment its fixed. In actual fact the speed information |
3070 | for the virtual channel can be propogated in both directions by | 3104 | for the virtual channel can be propogated in both directions by |
3071 | the RPN control message. This however rapidly gets nasty as we | 3105 | the RPN control message. This however rapidly gets nasty as we |
@@ -3077,6 +3111,8 @@ static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
3077 | static void gsmtty_throttle(struct tty_struct *tty) | 3111 | static void gsmtty_throttle(struct tty_struct *tty) |
3078 | { | 3112 | { |
3079 | struct gsm_dlci *dlci = tty->driver_data; | 3113 | struct gsm_dlci *dlci = tty->driver_data; |
3114 | if (dlci->state == DLCI_CLOSED) | ||
3115 | return; | ||
3080 | if (tty->termios.c_cflag & CRTSCTS) | 3116 | if (tty->termios.c_cflag & CRTSCTS) |
3081 | dlci->modem_tx &= ~TIOCM_DTR; | 3117 | dlci->modem_tx &= ~TIOCM_DTR; |
3082 | dlci->throttled = 1; | 3118 | dlci->throttled = 1; |
@@ -3087,6 +3123,8 @@ static void gsmtty_throttle(struct tty_struct *tty) | |||
3087 | static void gsmtty_unthrottle(struct tty_struct *tty) | 3123 | static void gsmtty_unthrottle(struct tty_struct *tty) |
3088 | { | 3124 | { |
3089 | struct gsm_dlci *dlci = tty->driver_data; | 3125 | struct gsm_dlci *dlci = tty->driver_data; |
3126 | if (dlci->state == DLCI_CLOSED) | ||
3127 | return; | ||
3090 | if (tty->termios.c_cflag & CRTSCTS) | 3128 | if (tty->termios.c_cflag & CRTSCTS) |
3091 | dlci->modem_tx |= TIOCM_DTR; | 3129 | dlci->modem_tx |= TIOCM_DTR; |
3092 | dlci->throttled = 0; | 3130 | dlci->throttled = 0; |
@@ -3098,6 +3136,8 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) | |||
3098 | { | 3136 | { |
3099 | struct gsm_dlci *dlci = tty->driver_data; | 3137 | struct gsm_dlci *dlci = tty->driver_data; |
3100 | int encode = 0; /* Off */ | 3138 | int encode = 0; /* Off */ |
3139 | if (dlci->state == DLCI_CLOSED) | ||
3140 | return -EINVAL; | ||
3101 | 3141 | ||
3102 | if (state == -1) /* "On indefinitely" - we can't encode this | 3142 | if (state == -1) /* "On indefinitely" - we can't encode this |
3103 | properly */ | 3143 | properly */ |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 19083efa2314..05e72bea9b07 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/file.h> | 49 | #include <linux/file.h> |
50 | #include <linux/uaccess.h> | 50 | #include <linux/uaccess.h> |
51 | #include <linux/module.h> | 51 | #include <linux/module.h> |
52 | #include <linux/ratelimit.h> | ||
52 | 53 | ||
53 | 54 | ||
54 | /* number of characters left in xmit buffer before select has we have room */ | 55 | /* number of characters left in xmit buffer before select has we have room */ |
@@ -100,7 +101,7 @@ struct n_tty_data { | |||
100 | struct mutex atomic_read_lock; | 101 | struct mutex atomic_read_lock; |
101 | struct mutex output_lock; | 102 | struct mutex output_lock; |
102 | struct mutex echo_lock; | 103 | struct mutex echo_lock; |
103 | spinlock_t read_lock; | 104 | raw_spinlock_t read_lock; |
104 | }; | 105 | }; |
105 | 106 | ||
106 | static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | 107 | static inline int tty_put_user(struct tty_struct *tty, unsigned char x, |
@@ -182,9 +183,9 @@ static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) | |||
182 | * The problem of stomping on the buffers ends here. | 183 | * The problem of stomping on the buffers ends here. |
183 | * Why didn't anyone see this one coming? --AJK | 184 | * Why didn't anyone see this one coming? --AJK |
184 | */ | 185 | */ |
185 | spin_lock_irqsave(&ldata->read_lock, flags); | 186 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
186 | put_tty_queue_nolock(c, ldata); | 187 | put_tty_queue_nolock(c, ldata); |
187 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 188 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
188 | } | 189 | } |
189 | 190 | ||
190 | /** | 191 | /** |
@@ -218,9 +219,9 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
218 | struct n_tty_data *ldata = tty->disc_data; | 219 | struct n_tty_data *ldata = tty->disc_data; |
219 | unsigned long flags; | 220 | unsigned long flags; |
220 | 221 | ||
221 | spin_lock_irqsave(&ldata->read_lock, flags); | 222 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
222 | ldata->read_head = ldata->read_tail = ldata->read_cnt = 0; | 223 | ldata->read_head = ldata->read_tail = ldata->read_cnt = 0; |
223 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 224 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
224 | 225 | ||
225 | mutex_lock(&ldata->echo_lock); | 226 | mutex_lock(&ldata->echo_lock); |
226 | ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0; | 227 | ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0; |
@@ -276,7 +277,7 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) | |||
276 | unsigned long flags; | 277 | unsigned long flags; |
277 | ssize_t n = 0; | 278 | ssize_t n = 0; |
278 | 279 | ||
279 | spin_lock_irqsave(&ldata->read_lock, flags); | 280 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
280 | if (!ldata->icanon) { | 281 | if (!ldata->icanon) { |
281 | n = ldata->read_cnt; | 282 | n = ldata->read_cnt; |
282 | } else if (ldata->canon_data) { | 283 | } else if (ldata->canon_data) { |
@@ -284,7 +285,7 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) | |||
284 | ldata->canon_head - ldata->read_tail : | 285 | ldata->canon_head - ldata->read_tail : |
285 | ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail); | 286 | ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail); |
286 | } | 287 | } |
287 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 288 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
288 | return n; | 289 | return n; |
289 | } | 290 | } |
290 | 291 | ||
@@ -915,19 +916,19 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
915 | kill_type = WERASE; | 916 | kill_type = WERASE; |
916 | else { | 917 | else { |
917 | if (!L_ECHO(tty)) { | 918 | if (!L_ECHO(tty)) { |
918 | spin_lock_irqsave(&ldata->read_lock, flags); | 919 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
919 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & | 920 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & |
920 | (N_TTY_BUF_SIZE - 1)); | 921 | (N_TTY_BUF_SIZE - 1)); |
921 | ldata->read_head = ldata->canon_head; | 922 | ldata->read_head = ldata->canon_head; |
922 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 923 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
923 | return; | 924 | return; |
924 | } | 925 | } |
925 | if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { | 926 | if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { |
926 | spin_lock_irqsave(&ldata->read_lock, flags); | 927 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
927 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & | 928 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & |
928 | (N_TTY_BUF_SIZE - 1)); | 929 | (N_TTY_BUF_SIZE - 1)); |
929 | ldata->read_head = ldata->canon_head; | 930 | ldata->read_head = ldata->canon_head; |
930 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 931 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
931 | finish_erasing(ldata); | 932 | finish_erasing(ldata); |
932 | echo_char(KILL_CHAR(tty), tty); | 933 | echo_char(KILL_CHAR(tty), tty); |
933 | /* Add a newline if ECHOK is on and ECHOKE is off. */ | 934 | /* Add a newline if ECHOK is on and ECHOKE is off. */ |
@@ -961,10 +962,10 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
961 | break; | 962 | break; |
962 | } | 963 | } |
963 | cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1); | 964 | cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1); |
964 | spin_lock_irqsave(&ldata->read_lock, flags); | 965 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
965 | ldata->read_head = head; | 966 | ldata->read_head = head; |
966 | ldata->read_cnt -= cnt; | 967 | ldata->read_cnt -= cnt; |
967 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 968 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
968 | if (L_ECHO(tty)) { | 969 | if (L_ECHO(tty)) { |
969 | if (L_ECHOPRT(tty)) { | 970 | if (L_ECHOPRT(tty)) { |
970 | if (!ldata->erasing) { | 971 | if (!ldata->erasing) { |
@@ -1344,12 +1345,12 @@ send_signal: | |||
1344 | put_tty_queue(c, ldata); | 1345 | put_tty_queue(c, ldata); |
1345 | 1346 | ||
1346 | handle_newline: | 1347 | handle_newline: |
1347 | spin_lock_irqsave(&ldata->read_lock, flags); | 1348 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1348 | set_bit(ldata->read_head, ldata->read_flags); | 1349 | set_bit(ldata->read_head, ldata->read_flags); |
1349 | put_tty_queue_nolock(c, ldata); | 1350 | put_tty_queue_nolock(c, ldata); |
1350 | ldata->canon_head = ldata->read_head; | 1351 | ldata->canon_head = ldata->read_head; |
1351 | ldata->canon_data++; | 1352 | ldata->canon_data++; |
1352 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1353 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1353 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1354 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1354 | if (waitqueue_active(&tty->read_wait)) | 1355 | if (waitqueue_active(&tty->read_wait)) |
1355 | wake_up_interruptible(&tty->read_wait); | 1356 | wake_up_interruptible(&tty->read_wait); |
@@ -1423,7 +1424,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1423 | unsigned long cpuflags; | 1424 | unsigned long cpuflags; |
1424 | 1425 | ||
1425 | if (ldata->real_raw) { | 1426 | if (ldata->real_raw) { |
1426 | spin_lock_irqsave(&ldata->read_lock, cpuflags); | 1427 | raw_spin_lock_irqsave(&ldata->read_lock, cpuflags); |
1427 | i = min(N_TTY_BUF_SIZE - ldata->read_cnt, | 1428 | i = min(N_TTY_BUF_SIZE - ldata->read_cnt, |
1428 | N_TTY_BUF_SIZE - ldata->read_head); | 1429 | N_TTY_BUF_SIZE - ldata->read_head); |
1429 | i = min(count, i); | 1430 | i = min(count, i); |
@@ -1439,7 +1440,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1439 | memcpy(ldata->read_buf + ldata->read_head, cp, i); | 1440 | memcpy(ldata->read_buf + ldata->read_head, cp, i); |
1440 | ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); | 1441 | ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); |
1441 | ldata->read_cnt += i; | 1442 | ldata->read_cnt += i; |
1442 | spin_unlock_irqrestore(&ldata->read_lock, cpuflags); | 1443 | raw_spin_unlock_irqrestore(&ldata->read_lock, cpuflags); |
1443 | } else { | 1444 | } else { |
1444 | for (i = count, p = cp, f = fp; i; i--, p++) { | 1445 | for (i = count, p = cp, f = fp; i; i--, p++) { |
1445 | if (f) | 1446 | if (f) |
@@ -1635,7 +1636,7 @@ static int n_tty_open(struct tty_struct *tty) | |||
1635 | mutex_init(&ldata->atomic_read_lock); | 1636 | mutex_init(&ldata->atomic_read_lock); |
1636 | mutex_init(&ldata->output_lock); | 1637 | mutex_init(&ldata->output_lock); |
1637 | mutex_init(&ldata->echo_lock); | 1638 | mutex_init(&ldata->echo_lock); |
1638 | spin_lock_init(&ldata->read_lock); | 1639 | raw_spin_lock_init(&ldata->read_lock); |
1639 | 1640 | ||
1640 | /* These are ugly. Currently a malloc failure here can panic */ | 1641 | /* These are ugly. Currently a malloc failure here can panic */ |
1641 | ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); | 1642 | ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); |
@@ -1703,10 +1704,10 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1703 | bool is_eof; | 1704 | bool is_eof; |
1704 | 1705 | ||
1705 | retval = 0; | 1706 | retval = 0; |
1706 | spin_lock_irqsave(&ldata->read_lock, flags); | 1707 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1707 | n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail); | 1708 | n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail); |
1708 | n = min(*nr, n); | 1709 | n = min(*nr, n); |
1709 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1710 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1710 | if (n) { | 1711 | if (n) { |
1711 | retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n); | 1712 | retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n); |
1712 | n -= retval; | 1713 | n -= retval; |
@@ -1714,13 +1715,13 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1714 | ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty); | 1715 | ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty); |
1715 | tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n, | 1716 | tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n, |
1716 | ldata->icanon); | 1717 | ldata->icanon); |
1717 | spin_lock_irqsave(&ldata->read_lock, flags); | 1718 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1718 | ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1); | 1719 | ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1); |
1719 | ldata->read_cnt -= n; | 1720 | ldata->read_cnt -= n; |
1720 | /* Turn single EOF into zero-length read */ | 1721 | /* Turn single EOF into zero-length read */ |
1721 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt) | 1722 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt) |
1722 | n = 0; | 1723 | n = 0; |
1723 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1724 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1724 | *b += n; | 1725 | *b += n; |
1725 | *nr -= n; | 1726 | *nr -= n; |
1726 | } | 1727 | } |
@@ -1900,7 +1901,7 @@ do_it_again: | |||
1900 | 1901 | ||
1901 | if (ldata->icanon && !L_EXTPROC(tty)) { | 1902 | if (ldata->icanon && !L_EXTPROC(tty)) { |
1902 | /* N.B. avoid overrun if nr == 0 */ | 1903 | /* N.B. avoid overrun if nr == 0 */ |
1903 | spin_lock_irqsave(&ldata->read_lock, flags); | 1904 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1904 | while (nr && ldata->read_cnt) { | 1905 | while (nr && ldata->read_cnt) { |
1905 | int eol; | 1906 | int eol; |
1906 | 1907 | ||
@@ -1918,25 +1919,25 @@ do_it_again: | |||
1918 | if (--ldata->canon_data < 0) | 1919 | if (--ldata->canon_data < 0) |
1919 | ldata->canon_data = 0; | 1920 | ldata->canon_data = 0; |
1920 | } | 1921 | } |
1921 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1922 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1922 | 1923 | ||
1923 | if (!eol || (c != __DISABLED_CHAR)) { | 1924 | if (!eol || (c != __DISABLED_CHAR)) { |
1924 | if (tty_put_user(tty, c, b++)) { | 1925 | if (tty_put_user(tty, c, b++)) { |
1925 | retval = -EFAULT; | 1926 | retval = -EFAULT; |
1926 | b--; | 1927 | b--; |
1927 | spin_lock_irqsave(&ldata->read_lock, flags); | 1928 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1928 | break; | 1929 | break; |
1929 | } | 1930 | } |
1930 | nr--; | 1931 | nr--; |
1931 | } | 1932 | } |
1932 | if (eol) { | 1933 | if (eol) { |
1933 | tty_audit_push(tty); | 1934 | tty_audit_push(tty); |
1934 | spin_lock_irqsave(&ldata->read_lock, flags); | 1935 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1935 | break; | 1936 | break; |
1936 | } | 1937 | } |
1937 | spin_lock_irqsave(&ldata->read_lock, flags); | 1938 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1938 | } | 1939 | } |
1939 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1940 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1940 | if (retval) | 1941 | if (retval) |
1941 | break; | 1942 | break; |
1942 | } else { | 1943 | } else { |
@@ -2188,7 +2189,7 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
2188 | * n_tty_inherit_ops - inherit N_TTY methods | 2189 | * n_tty_inherit_ops - inherit N_TTY methods |
2189 | * @ops: struct tty_ldisc_ops where to save N_TTY methods | 2190 | * @ops: struct tty_ldisc_ops where to save N_TTY methods |
2190 | * | 2191 | * |
2191 | * Used by a generic struct tty_ldisc_ops to easily inherit N_TTY | 2192 | * Enables a 'subclass' line discipline to 'inherit' N_TTY |
2192 | * methods. | 2193 | * methods. |
2193 | */ | 2194 | */ |
2194 | 2195 | ||
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index a0c69ab04399..2dff19796157 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -827,15 +827,10 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
827 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 827 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
828 | int i, ret; | 828 | int i, ret; |
829 | 829 | ||
830 | if (unlikely(!tty)) { | ||
831 | DBG1("tty not open for port: %d?", index); | ||
832 | return 1; | ||
833 | } | ||
834 | |||
835 | read_mem32((u32 *) &size, addr, 4); | 830 | read_mem32((u32 *) &size, addr, 4); |
836 | /* DBG1( "%d bytes port: %d", size, index); */ | 831 | /* DBG1( "%d bytes port: %d", size, index); */ |
837 | 832 | ||
838 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 833 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { |
839 | DBG1("No room in tty, don't read data, don't ack interrupt, " | 834 | DBG1("No room in tty, don't read data, don't ack interrupt, " |
840 | "disable interrupt"); | 835 | "disable interrupt"); |
841 | 836 | ||
@@ -855,13 +850,14 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
855 | read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); | 850 | read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); |
856 | 851 | ||
857 | if (size == 1) { | 852 | if (size == 1) { |
858 | tty_insert_flip_char(tty, buf[0], TTY_NORMAL); | 853 | tty_insert_flip_char(&port->port, buf[0], TTY_NORMAL); |
859 | size = 0; | 854 | size = 0; |
860 | } else if (size < RECEIVE_BUF_MAX) { | 855 | } else if (size < RECEIVE_BUF_MAX) { |
861 | size -= tty_insert_flip_string(tty, (char *) buf, size); | 856 | size -= tty_insert_flip_string(&port->port, |
857 | (char *)buf, size); | ||
862 | } else { | 858 | } else { |
863 | i = tty_insert_flip_string(tty, \ | 859 | i = tty_insert_flip_string(&port->port, |
864 | (char *) buf, RECEIVE_BUF_MAX); | 860 | (char *)buf, RECEIVE_BUF_MAX); |
865 | size -= i; | 861 | size -= i; |
866 | offset += i; | 862 | offset += i; |
867 | } | 863 | } |
@@ -1276,15 +1272,11 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id) | |||
1276 | 1272 | ||
1277 | exit_handler: | 1273 | exit_handler: |
1278 | spin_unlock(&dc->spin_mutex); | 1274 | spin_unlock(&dc->spin_mutex); |
1279 | for (a = 0; a < NOZOMI_MAX_PORTS; a++) { | 1275 | |
1280 | struct tty_struct *tty; | 1276 | for (a = 0; a < NOZOMI_MAX_PORTS; a++) |
1281 | if (test_and_clear_bit(a, &dc->flip)) { | 1277 | if (test_and_clear_bit(a, &dc->flip)) |
1282 | tty = tty_port_tty_get(&dc->port[a].port); | 1278 | tty_flip_buffer_push(&dc->port[a].port); |
1283 | if (tty) | 1279 | |
1284 | tty_flip_buffer_push(tty); | ||
1285 | tty_kref_put(tty); | ||
1286 | } | ||
1287 | } | ||
1288 | return IRQ_HANDLED; | 1280 | return IRQ_HANDLED; |
1289 | none: | 1281 | none: |
1290 | spin_unlock(&dc->spin_mutex); | 1282 | spin_unlock(&dc->spin_mutex); |
@@ -1687,12 +1679,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1687 | 1679 | ||
1688 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); | 1680 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); |
1689 | 1681 | ||
1690 | /* notify card */ | ||
1691 | if (unlikely(dc == NULL)) { | ||
1692 | DBG1("No device context?"); | ||
1693 | goto exit; | ||
1694 | } | ||
1695 | |||
1696 | spin_lock_irqsave(&dc->spin_mutex, flags); | 1682 | spin_lock_irqsave(&dc->spin_mutex, flags); |
1697 | /* CTS is only valid on the modem channel */ | 1683 | /* CTS is only valid on the modem channel */ |
1698 | if (port == &(dc->port[PORT_MDM])) { | 1684 | if (port == &(dc->port[PORT_MDM])) { |
@@ -1708,7 +1694,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1708 | } | 1694 | } |
1709 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | 1695 | spin_unlock_irqrestore(&dc->spin_mutex, flags); |
1710 | 1696 | ||
1711 | exit: | ||
1712 | return rval; | 1697 | return rval; |
1713 | } | 1698 | } |
1714 | 1699 | ||
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 79ff3a5e925d..c24b4db243b9 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -38,16 +38,18 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
38 | if (tty->driver->subtype == PTY_TYPE_MASTER) | 38 | if (tty->driver->subtype == PTY_TYPE_MASTER) |
39 | WARN_ON(tty->count > 1); | 39 | WARN_ON(tty->count > 1); |
40 | else { | 40 | else { |
41 | if (test_bit(TTY_IO_ERROR, &tty->flags)) | ||
42 | return; | ||
41 | if (tty->count > 2) | 43 | if (tty->count > 2) |
42 | return; | 44 | return; |
43 | } | 45 | } |
46 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
44 | wake_up_interruptible(&tty->read_wait); | 47 | wake_up_interruptible(&tty->read_wait); |
45 | wake_up_interruptible(&tty->write_wait); | 48 | wake_up_interruptible(&tty->write_wait); |
46 | tty->packet = 0; | 49 | tty->packet = 0; |
47 | /* Review - krefs on tty_link ?? */ | 50 | /* Review - krefs on tty_link ?? */ |
48 | if (!tty->link) | 51 | if (!tty->link) |
49 | return; | 52 | return; |
50 | tty->link->packet = 0; | ||
51 | set_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 53 | set_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
52 | wake_up_interruptible(&tty->link->read_wait); | 54 | wake_up_interruptible(&tty->link->read_wait); |
53 | wake_up_interruptible(&tty->link->write_wait); | 55 | wake_up_interruptible(&tty->link->write_wait); |
@@ -55,9 +57,10 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
55 | set_bit(TTY_OTHER_CLOSED, &tty->flags); | 57 | set_bit(TTY_OTHER_CLOSED, &tty->flags); |
56 | #ifdef CONFIG_UNIX98_PTYS | 58 | #ifdef CONFIG_UNIX98_PTYS |
57 | if (tty->driver == ptm_driver) { | 59 | if (tty->driver == ptm_driver) { |
58 | mutex_lock(&devpts_mutex); | 60 | mutex_lock(&devpts_mutex); |
59 | devpts_pty_kill(tty->link->driver_data); | 61 | if (tty->link->driver_data) |
60 | mutex_unlock(&devpts_mutex); | 62 | devpts_pty_kill(tty->link->driver_data); |
63 | mutex_unlock(&devpts_mutex); | ||
61 | } | 64 | } |
62 | #endif | 65 | #endif |
63 | tty_unlock(tty); | 66 | tty_unlock(tty); |
@@ -120,10 +123,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) | |||
120 | 123 | ||
121 | if (c > 0) { | 124 | if (c > 0) { |
122 | /* Stuff the data into the input queue of the other end */ | 125 | /* Stuff the data into the input queue of the other end */ |
123 | c = tty_insert_flip_string(to, buf, c); | 126 | c = tty_insert_flip_string(to->port, buf, c); |
124 | /* And shovel */ | 127 | /* And shovel */ |
125 | if (c) { | 128 | if (c) { |
126 | tty_flip_buffer_push(to); | 129 | tty_flip_buffer_push(to->port); |
127 | tty_wakeup(tty); | 130 | tty_wakeup(tty); |
128 | } | 131 | } |
129 | } | 132 | } |
@@ -246,14 +249,17 @@ static int pty_open(struct tty_struct *tty, struct file *filp) | |||
246 | if (!tty || !tty->link) | 249 | if (!tty || !tty->link) |
247 | goto out; | 250 | goto out; |
248 | 251 | ||
252 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
253 | |||
249 | retval = -EIO; | 254 | retval = -EIO; |
250 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | 255 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) |
251 | goto out; | 256 | goto out; |
252 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) | 257 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) |
253 | goto out; | 258 | goto out; |
254 | if (tty->link->count != 1) | 259 | if (tty->driver->subtype == PTY_TYPE_SLAVE && tty->link->count != 1) |
255 | goto out; | 260 | goto out; |
256 | 261 | ||
262 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
257 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 263 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
258 | set_bit(TTY_THROTTLED, &tty->flags); | 264 | set_bit(TTY_THROTTLED, &tty->flags); |
259 | retval = 0; | 265 | retval = 0; |
@@ -663,7 +669,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
663 | * Allocate a unix98 pty master device from the ptmx driver. | 669 | * Allocate a unix98 pty master device from the ptmx driver. |
664 | * | 670 | * |
665 | * Locking: tty_mutex protects the init_dev work. tty->count should | 671 | * Locking: tty_mutex protects the init_dev work. tty->count should |
666 | * protect the rest. | 672 | * protect the rest. |
667 | * allocated_ptys_lock handles the list of free pty numbers | 673 | * allocated_ptys_lock handles the list of free pty numbers |
668 | */ | 674 | */ |
669 | 675 | ||
@@ -704,6 +710,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
704 | mutex_unlock(&tty_mutex); | 710 | mutex_unlock(&tty_mutex); |
705 | 711 | ||
706 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 712 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
713 | tty->driver_data = inode; | ||
707 | 714 | ||
708 | tty_add_file(tty, filp); | 715 | tty_add_file(tty, filp); |
709 | 716 | ||
@@ -714,14 +721,13 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
714 | retval = PTR_ERR(slave_inode); | 721 | retval = PTR_ERR(slave_inode); |
715 | goto err_release; | 722 | goto err_release; |
716 | } | 723 | } |
724 | tty->link->driver_data = slave_inode; | ||
717 | 725 | ||
718 | retval = ptm_driver->ops->open(tty, filp); | 726 | retval = ptm_driver->ops->open(tty, filp); |
719 | if (retval) | 727 | if (retval) |
720 | goto err_release; | 728 | goto err_release; |
721 | 729 | ||
722 | tty_unlock(tty); | 730 | tty_unlock(tty); |
723 | tty->driver_data = inode; | ||
724 | tty->link->driver_data = slave_inode; | ||
725 | return 0; | 731 | return 0; |
726 | err_release: | 732 | err_release: |
727 | tty_unlock(tty); | 733 | tty_unlock(tty); |
@@ -797,7 +803,7 @@ static void __init unix98_pty_init(void) | |||
797 | cdev_init(&ptmx_cdev, &ptmx_fops); | 803 | cdev_init(&ptmx_cdev, &ptmx_fops); |
798 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | 804 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || |
799 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | 805 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) |
800 | panic("Couldn't register /dev/ptmx driver\n"); | 806 | panic("Couldn't register /dev/ptmx driver"); |
801 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | 807 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); |
802 | } | 808 | } |
803 | 809 | ||
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index e42009a00529..1d270034bfc3 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #undef REV_PCI_ORDER | 55 | #undef REV_PCI_ORDER |
56 | #undef ROCKET_DEBUG_IO | 56 | #undef ROCKET_DEBUG_IO |
57 | 57 | ||
58 | #define POLL_PERIOD HZ/100 /* Polling period .01 seconds (10ms) */ | 58 | #define POLL_PERIOD (HZ/100) /* Polling period .01 seconds (10ms) */ |
59 | 59 | ||
60 | /****** Kernel includes ******/ | 60 | /****** Kernel includes ******/ |
61 | 61 | ||
@@ -315,9 +315,8 @@ static inline int rocket_paranoia_check(struct r_port *info, | |||
315 | * that receive data is present on a serial port. Pulls data from FIFO, moves it into the | 315 | * that receive data is present on a serial port. Pulls data from FIFO, moves it into the |
316 | * tty layer. | 316 | * tty layer. |
317 | */ | 317 | */ |
318 | static void rp_do_receive(struct r_port *info, | 318 | static void rp_do_receive(struct r_port *info, CHANNEL_t *cp, |
319 | struct tty_struct *tty, | 319 | unsigned int ChanStatus) |
320 | CHANNEL_t * cp, unsigned int ChanStatus) | ||
321 | { | 320 | { |
322 | unsigned int CharNStat; | 321 | unsigned int CharNStat; |
323 | int ToRecv, wRecv, space; | 322 | int ToRecv, wRecv, space; |
@@ -379,7 +378,8 @@ static void rp_do_receive(struct r_port *info, | |||
379 | flag = TTY_OVERRUN; | 378 | flag = TTY_OVERRUN; |
380 | else | 379 | else |
381 | flag = TTY_NORMAL; | 380 | flag = TTY_NORMAL; |
382 | tty_insert_flip_char(tty, CharNStat & 0xff, flag); | 381 | tty_insert_flip_char(&info->port, CharNStat & 0xff, |
382 | flag); | ||
383 | ToRecv--; | 383 | ToRecv--; |
384 | } | 384 | } |
385 | 385 | ||
@@ -399,7 +399,7 @@ static void rp_do_receive(struct r_port *info, | |||
399 | * characters at time by doing repeated word IO | 399 | * characters at time by doing repeated word IO |
400 | * transfer. | 400 | * transfer. |
401 | */ | 401 | */ |
402 | space = tty_prepare_flip_string(tty, &cbuf, ToRecv); | 402 | space = tty_prepare_flip_string(&info->port, &cbuf, ToRecv); |
403 | if (space < ToRecv) { | 403 | if (space < ToRecv) { |
404 | #ifdef ROCKET_DEBUG_RECEIVE | 404 | #ifdef ROCKET_DEBUG_RECEIVE |
405 | printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space); | 405 | printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space); |
@@ -415,7 +415,7 @@ static void rp_do_receive(struct r_port *info, | |||
415 | cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); | 415 | cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); |
416 | } | 416 | } |
417 | /* Push the data up to the tty layer */ | 417 | /* Push the data up to the tty layer */ |
418 | tty_flip_buffer_push(tty); | 418 | tty_flip_buffer_push(&info->port); |
419 | } | 419 | } |
420 | 420 | ||
421 | /* | 421 | /* |
@@ -494,7 +494,6 @@ static void rp_do_transmit(struct r_port *info) | |||
494 | static void rp_handle_port(struct r_port *info) | 494 | static void rp_handle_port(struct r_port *info) |
495 | { | 495 | { |
496 | CHANNEL_t *cp; | 496 | CHANNEL_t *cp; |
497 | struct tty_struct *tty; | ||
498 | unsigned int IntMask, ChanStatus; | 497 | unsigned int IntMask, ChanStatus; |
499 | 498 | ||
500 | if (!info) | 499 | if (!info) |
@@ -505,12 +504,7 @@ static void rp_handle_port(struct r_port *info) | |||
505 | "info->flags & NOT_INIT\n"); | 504 | "info->flags & NOT_INIT\n"); |
506 | return; | 505 | return; |
507 | } | 506 | } |
508 | tty = tty_port_tty_get(&info->port); | 507 | |
509 | if (!tty) { | ||
510 | printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " | ||
511 | "tty==NULL\n"); | ||
512 | return; | ||
513 | } | ||
514 | cp = &info->channel; | 508 | cp = &info->channel; |
515 | 509 | ||
516 | IntMask = sGetChanIntID(cp) & info->intmask; | 510 | IntMask = sGetChanIntID(cp) & info->intmask; |
@@ -519,7 +513,7 @@ static void rp_handle_port(struct r_port *info) | |||
519 | #endif | 513 | #endif |
520 | ChanStatus = sGetChanStatus(cp); | 514 | ChanStatus = sGetChanStatus(cp); |
521 | if (IntMask & RXF_TRIG) { /* Rx FIFO trigger level */ | 515 | if (IntMask & RXF_TRIG) { /* Rx FIFO trigger level */ |
522 | rp_do_receive(info, tty, cp, ChanStatus); | 516 | rp_do_receive(info, cp, ChanStatus); |
523 | } | 517 | } |
524 | if (IntMask & DELTA_CD) { /* CD change */ | 518 | if (IntMask & DELTA_CD) { /* CD change */ |
525 | #if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP)) | 519 | #if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP)) |
@@ -527,10 +521,15 @@ static void rp_handle_port(struct r_port *info) | |||
527 | (ChanStatus & CD_ACT) ? "on" : "off"); | 521 | (ChanStatus & CD_ACT) ? "on" : "off"); |
528 | #endif | 522 | #endif |
529 | if (!(ChanStatus & CD_ACT) && info->cd_status) { | 523 | if (!(ChanStatus & CD_ACT) && info->cd_status) { |
524 | struct tty_struct *tty; | ||
530 | #ifdef ROCKET_DEBUG_HANGUP | 525 | #ifdef ROCKET_DEBUG_HANGUP |
531 | printk(KERN_INFO "CD drop, calling hangup.\n"); | 526 | printk(KERN_INFO "CD drop, calling hangup.\n"); |
532 | #endif | 527 | #endif |
533 | tty_hangup(tty); | 528 | tty = tty_port_tty_get(&info->port); |
529 | if (tty) { | ||
530 | tty_hangup(tty); | ||
531 | tty_kref_put(tty); | ||
532 | } | ||
534 | } | 533 | } |
535 | info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; | 534 | info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; |
536 | wake_up_interruptible(&info->port.open_wait); | 535 | wake_up_interruptible(&info->port.open_wait); |
@@ -543,7 +542,6 @@ static void rp_handle_port(struct r_port *info) | |||
543 | printk(KERN_INFO "DSR change...\n"); | 542 | printk(KERN_INFO "DSR change...\n"); |
544 | } | 543 | } |
545 | #endif | 544 | #endif |
546 | tty_kref_put(tty); | ||
547 | } | 545 | } |
548 | 546 | ||
549 | /* | 547 | /* |
@@ -1758,8 +1756,29 @@ static void rp_flush_buffer(struct tty_struct *tty) | |||
1758 | 1756 | ||
1759 | #ifdef CONFIG_PCI | 1757 | #ifdef CONFIG_PCI |
1760 | 1758 | ||
1761 | static struct pci_device_id __used rocket_pci_ids[] = { | 1759 | static DEFINE_PCI_DEVICE_TABLE(rocket_pci_ids) = { |
1762 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, | 1760 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4QUAD) }, |
1761 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8OCTA) }, | ||
1762 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP8OCTA) }, | ||
1763 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8INTF) }, | ||
1764 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP8INTF) }, | ||
1765 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8J) }, | ||
1766 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4J) }, | ||
1767 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8SNI) }, | ||
1768 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP16SNI) }, | ||
1769 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP16INTF) }, | ||
1770 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP16INTF) }, | ||
1771 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_CRP16INTF) }, | ||
1772 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP32INTF) }, | ||
1773 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP32INTF) }, | ||
1774 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RPP4) }, | ||
1775 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RPP8) }, | ||
1776 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP2_232) }, | ||
1777 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP2_422) }, | ||
1778 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP6M) }, | ||
1779 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4M) }, | ||
1780 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_UPCI_RM3_8PORT) }, | ||
1781 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_UPCI_RM3_4PORT) }, | ||
1763 | { } | 1782 | { } |
1764 | }; | 1783 | }; |
1765 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); | 1784 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); |
@@ -1781,7 +1800,8 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1781 | WordIO_t ConfigIO = 0; | 1800 | WordIO_t ConfigIO = 0; |
1782 | ByteIO_t UPCIRingInd = 0; | 1801 | ByteIO_t UPCIRingInd = 0; |
1783 | 1802 | ||
1784 | if (!dev || pci_enable_device(dev)) | 1803 | if (!dev || !pci_match_id(rocket_pci_ids, dev) || |
1804 | pci_enable_device(dev)) | ||
1785 | return 0; | 1805 | return 0; |
1786 | 1806 | ||
1787 | rcktpt_io_addr[i] = pci_resource_start(dev, 0); | 1807 | rcktpt_io_addr[i] = pci_resource_start(dev, 0); |
diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index a44345a2dbb4..c7e8b60b6177 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c | |||
@@ -85,7 +85,6 @@ static void serial21285_enable_ms(struct uart_port *port) | |||
85 | static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) | 85 | static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) |
86 | { | 86 | { |
87 | struct uart_port *port = dev_id; | 87 | struct uart_port *port = dev_id; |
88 | struct tty_struct *tty = port->state->port.tty; | ||
89 | unsigned int status, ch, flag, rxs, max_count = 256; | 88 | unsigned int status, ch, flag, rxs, max_count = 256; |
90 | 89 | ||
91 | status = *CSR_UARTFLG; | 90 | status = *CSR_UARTFLG; |
@@ -115,7 +114,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) | |||
115 | 114 | ||
116 | status = *CSR_UARTFLG; | 115 | status = *CSR_UARTFLG; |
117 | } | 116 | } |
118 | tty_flip_buffer_push(tty); | 117 | tty_flip_buffer_push(&port->state->port); |
119 | 118 | ||
120 | return IRQ_HANDLED; | 119 | return IRQ_HANDLED; |
121 | } | 120 | } |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index f99a84526f82..49399470794d 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
@@ -262,8 +262,7 @@ static void rs_start(struct tty_struct *tty) | |||
262 | local_irq_restore(flags); | 262 | local_irq_restore(flags); |
263 | } | 263 | } |
264 | 264 | ||
265 | static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | 265 | static void receive_chars(struct m68k_serial *info, unsigned short rx) |
266 | unsigned short rx) | ||
267 | { | 266 | { |
268 | m68328_uart *uart = &uart_addr[info->line]; | 267 | m68328_uart *uart = &uart_addr[info->line]; |
269 | unsigned char ch, flag; | 268 | unsigned char ch, flag; |
@@ -293,9 +292,6 @@ static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | |||
293 | } | 292 | } |
294 | } | 293 | } |
295 | 294 | ||
296 | if(!tty) | ||
297 | goto clear_and_exit; | ||
298 | |||
299 | flag = TTY_NORMAL; | 295 | flag = TTY_NORMAL; |
300 | 296 | ||
301 | if (rx & URX_PARITY_ERROR) | 297 | if (rx & URX_PARITY_ERROR) |
@@ -305,15 +301,12 @@ static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | |||
305 | else if (rx & URX_FRAME_ERROR) | 301 | else if (rx & URX_FRAME_ERROR) |
306 | flag = TTY_FRAME; | 302 | flag = TTY_FRAME; |
307 | 303 | ||
308 | tty_insert_flip_char(tty, ch, flag); | 304 | tty_insert_flip_char(&info->tport, ch, flag); |
309 | #ifndef CONFIG_XCOPILOT_BUGS | 305 | #ifndef CONFIG_XCOPILOT_BUGS |
310 | } while((rx = uart->urx.w) & URX_DATA_READY); | 306 | } while((rx = uart->urx.w) & URX_DATA_READY); |
311 | #endif | 307 | #endif |
312 | 308 | ||
313 | tty_schedule_flip(tty); | 309 | tty_schedule_flip(&info->tport); |
314 | |||
315 | clear_and_exit: | ||
316 | return; | ||
317 | } | 310 | } |
318 | 311 | ||
319 | static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) | 312 | static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) |
@@ -367,11 +360,11 @@ irqreturn_t rs_interrupt(int irq, void *dev_id) | |||
367 | tx = uart->utx.w; | 360 | tx = uart->utx.w; |
368 | 361 | ||
369 | if (rx & URX_DATA_READY) | 362 | if (rx & URX_DATA_READY) |
370 | receive_chars(info, tty, rx); | 363 | receive_chars(info, rx); |
371 | if (tx & UTX_TX_AVAIL) | 364 | if (tx & UTX_TX_AVAIL) |
372 | transmit_chars(info, tty); | 365 | transmit_chars(info, tty); |
373 | #else | 366 | #else |
374 | receive_chars(info, tty, rx); | 367 | receive_chars(info, rx); |
375 | #endif | 368 | #endif |
376 | tty_kref_put(tty); | 369 | tty_kref_put(tty); |
377 | 370 | ||
@@ -1009,7 +1002,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1009 | m68328_uart *uart = &uart_addr[info->line]; | 1002 | m68328_uart *uart = &uart_addr[info->line]; |
1010 | unsigned long flags; | 1003 | unsigned long flags; |
1011 | 1004 | ||
1012 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) | 1005 | if (serial_paranoia_check(info, tty->name, "rs_close")) |
1013 | return; | 1006 | return; |
1014 | 1007 | ||
1015 | local_irq_save(flags); | 1008 | local_irq_save(flags); |
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index f9320437a649..0efc815a4968 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c | |||
@@ -239,13 +239,6 @@ static const struct serial8250_config uart_config[] = { | |||
239 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 239 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
240 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, | 240 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, |
241 | }, | 241 | }, |
242 | [PORT_RM9000] = { | ||
243 | .name = "RM9000", | ||
244 | .fifo_size = 16, | ||
245 | .tx_loadsz = 16, | ||
246 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | ||
247 | .flags = UART_CAP_FIFO, | ||
248 | }, | ||
249 | [PORT_OCTEON] = { | 242 | [PORT_OCTEON] = { |
250 | .name = "OCTEON", | 243 | .name = "OCTEON", |
251 | .fifo_size = 64, | 244 | .fifo_size = 64, |
@@ -324,9 +317,9 @@ static void default_serial_dl_write(struct uart_8250_port *up, int value) | |||
324 | serial_out(up, UART_DLM, value >> 8 & 0xff); | 317 | serial_out(up, UART_DLM, value >> 8 & 0xff); |
325 | } | 318 | } |
326 | 319 | ||
327 | #ifdef CONFIG_MIPS_ALCHEMY | 320 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) |
328 | 321 | ||
329 | /* Au1x00 UART hardware has a weird register layout */ | 322 | /* Au1x00/RT288x UART hardware has a weird register layout */ |
330 | static const u8 au_io_in_map[] = { | 323 | static const u8 au_io_in_map[] = { |
331 | [UART_RX] = 0, | 324 | [UART_RX] = 0, |
332 | [UART_IER] = 2, | 325 | [UART_IER] = 2, |
@@ -370,56 +363,6 @@ static void au_serial_dl_write(struct uart_8250_port *up, int value) | |||
370 | 363 | ||
371 | #endif | 364 | #endif |
372 | 365 | ||
373 | #ifdef CONFIG_SERIAL_8250_RM9K | ||
374 | |||
375 | static const u8 | ||
376 | regmap_in[8] = { | ||
377 | [UART_RX] = 0x00, | ||
378 | [UART_IER] = 0x0c, | ||
379 | [UART_IIR] = 0x14, | ||
380 | [UART_LCR] = 0x1c, | ||
381 | [UART_MCR] = 0x20, | ||
382 | [UART_LSR] = 0x24, | ||
383 | [UART_MSR] = 0x28, | ||
384 | [UART_SCR] = 0x2c | ||
385 | }, | ||
386 | regmap_out[8] = { | ||
387 | [UART_TX] = 0x04, | ||
388 | [UART_IER] = 0x0c, | ||
389 | [UART_FCR] = 0x18, | ||
390 | [UART_LCR] = 0x1c, | ||
391 | [UART_MCR] = 0x20, | ||
392 | [UART_LSR] = 0x24, | ||
393 | [UART_MSR] = 0x28, | ||
394 | [UART_SCR] = 0x2c | ||
395 | }; | ||
396 | |||
397 | static unsigned int rm9k_serial_in(struct uart_port *p, int offset) | ||
398 | { | ||
399 | offset = regmap_in[offset] << p->regshift; | ||
400 | return readl(p->membase + offset); | ||
401 | } | ||
402 | |||
403 | static void rm9k_serial_out(struct uart_port *p, int offset, int value) | ||
404 | { | ||
405 | offset = regmap_out[offset] << p->regshift; | ||
406 | writel(value, p->membase + offset); | ||
407 | } | ||
408 | |||
409 | static int rm9k_serial_dl_read(struct uart_8250_port *up) | ||
410 | { | ||
411 | return ((__raw_readl(up->port.membase + 0x10) << 8) | | ||
412 | (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff; | ||
413 | } | ||
414 | |||
415 | static void rm9k_serial_dl_write(struct uart_8250_port *up, int value) | ||
416 | { | ||
417 | __raw_writel(value, up->port.membase + 0x08); | ||
418 | __raw_writel(value >> 8, up->port.membase + 0x10); | ||
419 | } | ||
420 | |||
421 | #endif | ||
422 | |||
423 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) | 366 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) |
424 | { | 367 | { |
425 | offset = offset << p->regshift; | 368 | offset = offset << p->regshift; |
@@ -497,16 +440,7 @@ static void set_io_from_upio(struct uart_port *p) | |||
497 | p->serial_out = mem32_serial_out; | 440 | p->serial_out = mem32_serial_out; |
498 | break; | 441 | break; |
499 | 442 | ||
500 | #ifdef CONFIG_SERIAL_8250_RM9K | 443 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) |
501 | case UPIO_RM9000: | ||
502 | p->serial_in = rm9k_serial_in; | ||
503 | p->serial_out = rm9k_serial_out; | ||
504 | up->dl_read = rm9k_serial_dl_read; | ||
505 | up->dl_write = rm9k_serial_dl_write; | ||
506 | break; | ||
507 | #endif | ||
508 | |||
509 | #ifdef CONFIG_MIPS_ALCHEMY | ||
510 | case UPIO_AU: | 444 | case UPIO_AU: |
511 | p->serial_in = au_serial_in; | 445 | p->serial_in = au_serial_in; |
512 | p->serial_out = au_serial_out; | 446 | p->serial_out = au_serial_out; |
@@ -1341,7 +1275,9 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1341 | struct uart_8250_port *up = | 1275 | struct uart_8250_port *up = |
1342 | container_of(port, struct uart_8250_port, port); | 1276 | container_of(port, struct uart_8250_port, port); |
1343 | 1277 | ||
1344 | if (!(up->ier & UART_IER_THRI)) { | 1278 | if (up->dma && !serial8250_tx_dma(up)) { |
1279 | return; | ||
1280 | } else if (!(up->ier & UART_IER_THRI)) { | ||
1345 | up->ier |= UART_IER_THRI; | 1281 | up->ier |= UART_IER_THRI; |
1346 | serial_port_out(port, UART_IER, up->ier); | 1282 | serial_port_out(port, UART_IER, up->ier); |
1347 | 1283 | ||
@@ -1349,9 +1285,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1349 | unsigned char lsr; | 1285 | unsigned char lsr; |
1350 | lsr = serial_in(up, UART_LSR); | 1286 | lsr = serial_in(up, UART_LSR); |
1351 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1287 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1352 | if ((port->type == PORT_RM9000) ? | 1288 | if (lsr & UART_LSR_TEMT) |
1353 | (lsr & UART_LSR_THRE) : | ||
1354 | (lsr & UART_LSR_TEMT)) | ||
1355 | serial8250_tx_chars(up); | 1289 | serial8250_tx_chars(up); |
1356 | } | 1290 | } |
1357 | } | 1291 | } |
@@ -1397,7 +1331,6 @@ unsigned char | |||
1397 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | 1331 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) |
1398 | { | 1332 | { |
1399 | struct uart_port *port = &up->port; | 1333 | struct uart_port *port = &up->port; |
1400 | struct tty_struct *tty = port->state->port.tty; | ||
1401 | unsigned char ch; | 1334 | unsigned char ch; |
1402 | int max_count = 256; | 1335 | int max_count = 256; |
1403 | char flag; | 1336 | char flag; |
@@ -1462,7 +1395,7 @@ ignore_char: | |||
1462 | lsr = serial_in(up, UART_LSR); | 1395 | lsr = serial_in(up, UART_LSR); |
1463 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); | 1396 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); |
1464 | spin_unlock(&port->lock); | 1397 | spin_unlock(&port->lock); |
1465 | tty_flip_buffer_push(tty); | 1398 | tty_flip_buffer_push(&port->state->port); |
1466 | spin_lock(&port->lock); | 1399 | spin_lock(&port->lock); |
1467 | return lsr; | 1400 | return lsr; |
1468 | } | 1401 | } |
@@ -1547,6 +1480,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1547 | unsigned long flags; | 1480 | unsigned long flags; |
1548 | struct uart_8250_port *up = | 1481 | struct uart_8250_port *up = |
1549 | container_of(port, struct uart_8250_port, port); | 1482 | container_of(port, struct uart_8250_port, port); |
1483 | int dma_err = 0; | ||
1550 | 1484 | ||
1551 | if (iir & UART_IIR_NO_INT) | 1485 | if (iir & UART_IIR_NO_INT) |
1552 | return 0; | 1486 | return 0; |
@@ -1557,8 +1491,13 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1557 | 1491 | ||
1558 | DEBUG_INTR("status = %x...", status); | 1492 | DEBUG_INTR("status = %x...", status); |
1559 | 1493 | ||
1560 | if (status & (UART_LSR_DR | UART_LSR_BI)) | 1494 | if (status & (UART_LSR_DR | UART_LSR_BI)) { |
1561 | status = serial8250_rx_chars(up, status); | 1495 | if (up->dma) |
1496 | dma_err = serial8250_rx_dma(up, iir); | ||
1497 | |||
1498 | if (!up->dma || dma_err) | ||
1499 | status = serial8250_rx_chars(up, status); | ||
1500 | } | ||
1562 | serial8250_modem_status(up); | 1501 | serial8250_modem_status(up); |
1563 | if (status & UART_LSR_THRE) | 1502 | if (status & UART_LSR_THRE) |
1564 | serial8250_tx_chars(up); | 1503 | serial8250_tx_chars(up); |
@@ -1991,9 +1930,12 @@ static int serial8250_startup(struct uart_port *port) | |||
1991 | if (port->type == PORT_8250_CIR) | 1930 | if (port->type == PORT_8250_CIR) |
1992 | return -ENODEV; | 1931 | return -ENODEV; |
1993 | 1932 | ||
1994 | port->fifosize = uart_config[up->port.type].fifo_size; | 1933 | if (!port->fifosize) |
1995 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; | 1934 | port->fifosize = uart_config[port->type].fifo_size; |
1996 | up->capabilities = uart_config[up->port.type].flags; | 1935 | if (!up->tx_loadsz) |
1936 | up->tx_loadsz = uart_config[port->type].tx_loadsz; | ||
1937 | if (!up->capabilities) | ||
1938 | up->capabilities = uart_config[port->type].flags; | ||
1997 | up->mcr = 0; | 1939 | up->mcr = 0; |
1998 | 1940 | ||
1999 | if (port->iotype != up->cur_iotype) | 1941 | if (port->iotype != up->cur_iotype) |
@@ -2198,6 +2140,18 @@ dont_test_tx_en: | |||
2198 | up->msr_saved_flags = 0; | 2140 | up->msr_saved_flags = 0; |
2199 | 2141 | ||
2200 | /* | 2142 | /* |
2143 | * Request DMA channels for both RX and TX. | ||
2144 | */ | ||
2145 | if (up->dma) { | ||
2146 | retval = serial8250_request_dma(up); | ||
2147 | if (retval) { | ||
2148 | pr_warn_ratelimited("ttyS%d - failed to request DMA\n", | ||
2149 | serial_index(port)); | ||
2150 | up->dma = NULL; | ||
2151 | } | ||
2152 | } | ||
2153 | |||
2154 | /* | ||
2201 | * Finally, enable interrupts. Note: Modem status interrupts | 2155 | * Finally, enable interrupts. Note: Modem status interrupts |
2202 | * are set via set_termios(), which will be occurring imminently | 2156 | * are set via set_termios(), which will be occurring imminently |
2203 | * anyway, so we don't enable them here. | 2157 | * anyway, so we don't enable them here. |
@@ -2230,6 +2184,9 @@ static void serial8250_shutdown(struct uart_port *port) | |||
2230 | up->ier = 0; | 2184 | up->ier = 0; |
2231 | serial_port_out(port, UART_IER, 0); | 2185 | serial_port_out(port, UART_IER, 0); |
2232 | 2186 | ||
2187 | if (up->dma) | ||
2188 | serial8250_release_dma(up); | ||
2189 | |||
2233 | spin_lock_irqsave(&port->lock, flags); | 2190 | spin_lock_irqsave(&port->lock, flags); |
2234 | if (port->flags & UPF_FOURPORT) { | 2191 | if (port->flags & UPF_FOURPORT) { |
2235 | /* reset interrupts on the AST Fourport board */ | 2192 | /* reset interrupts on the AST Fourport board */ |
@@ -2826,9 +2783,12 @@ static void | |||
2826 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) | 2783 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) |
2827 | { | 2784 | { |
2828 | up->port.type = type; | 2785 | up->port.type = type; |
2829 | up->port.fifosize = uart_config[type].fifo_size; | 2786 | if (!up->port.fifosize) |
2830 | up->capabilities = uart_config[type].flags; | 2787 | up->port.fifosize = uart_config[type].fifo_size; |
2831 | up->tx_loadsz = uart_config[type].tx_loadsz; | 2788 | if (!up->tx_loadsz) |
2789 | up->tx_loadsz = uart_config[type].tx_loadsz; | ||
2790 | if (!up->capabilities) | ||
2791 | up->capabilities = uart_config[type].flags; | ||
2832 | } | 2792 | } |
2833 | 2793 | ||
2834 | static void __init | 2794 | static void __init |
@@ -3262,6 +3222,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3262 | uart->bugs = up->bugs; | 3222 | uart->bugs = up->bugs; |
3263 | uart->port.mapbase = up->port.mapbase; | 3223 | uart->port.mapbase = up->port.mapbase; |
3264 | uart->port.private_data = up->port.private_data; | 3224 | uart->port.private_data = up->port.private_data; |
3225 | uart->port.fifosize = up->port.fifosize; | ||
3226 | uart->tx_loadsz = up->tx_loadsz; | ||
3227 | uart->capabilities = up->capabilities; | ||
3228 | |||
3265 | if (up->port.dev) | 3229 | if (up->port.dev) |
3266 | uart->port.dev = up->port.dev; | 3230 | uart->port.dev = up->port.dev; |
3267 | 3231 | ||
@@ -3287,6 +3251,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3287 | uart->dl_read = up->dl_read; | 3251 | uart->dl_read = up->dl_read; |
3288 | if (up->dl_write) | 3252 | if (up->dl_write) |
3289 | uart->dl_write = up->dl_write; | 3253 | uart->dl_write = up->dl_write; |
3254 | if (up->dma) | ||
3255 | uart->dma = up->dma; | ||
3290 | 3256 | ||
3291 | if (serial8250_isa_config != NULL) | 3257 | if (serial8250_isa_config != NULL) |
3292 | serial8250_isa_config(0, &uart->port, | 3258 | serial8250_isa_config(0, &uart->port, |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 12caa1292b75..34eb676916fe 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -12,6 +12,35 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
15 | #include <linux/dmaengine.h> | ||
16 | |||
17 | struct uart_8250_dma { | ||
18 | dma_filter_fn fn; | ||
19 | void *rx_param; | ||
20 | void *tx_param; | ||
21 | |||
22 | int rx_chan_id; | ||
23 | int tx_chan_id; | ||
24 | |||
25 | struct dma_slave_config rxconf; | ||
26 | struct dma_slave_config txconf; | ||
27 | |||
28 | struct dma_chan *rxchan; | ||
29 | struct dma_chan *txchan; | ||
30 | |||
31 | dma_addr_t rx_addr; | ||
32 | dma_addr_t tx_addr; | ||
33 | |||
34 | dma_cookie_t rx_cookie; | ||
35 | dma_cookie_t tx_cookie; | ||
36 | |||
37 | void *rx_buf; | ||
38 | |||
39 | size_t rx_size; | ||
40 | size_t tx_size; | ||
41 | |||
42 | unsigned char tx_running:1; | ||
43 | }; | ||
15 | 44 | ||
16 | struct old_serial_port { | 45 | struct old_serial_port { |
17 | unsigned int uart; | 46 | unsigned int uart; |
@@ -143,3 +172,24 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt) | |||
143 | return 0; | 172 | return 0; |
144 | } | 173 | } |
145 | #endif | 174 | #endif |
175 | |||
176 | #ifdef CONFIG_SERIAL_8250_DMA | ||
177 | extern int serial8250_tx_dma(struct uart_8250_port *); | ||
178 | extern int serial8250_rx_dma(struct uart_8250_port *, unsigned int iir); | ||
179 | extern int serial8250_request_dma(struct uart_8250_port *); | ||
180 | extern void serial8250_release_dma(struct uart_8250_port *); | ||
181 | #else | ||
182 | static inline int serial8250_tx_dma(struct uart_8250_port *p) | ||
183 | { | ||
184 | return -1; | ||
185 | } | ||
186 | static inline int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | ||
187 | { | ||
188 | return -1; | ||
189 | } | ||
190 | static inline int serial8250_request_dma(struct uart_8250_port *p) | ||
191 | { | ||
192 | return -1; | ||
193 | } | ||
194 | static inline void serial8250_release_dma(struct uart_8250_port *p) { } | ||
195 | #endif | ||
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c new file mode 100644 index 000000000000..b9f7fd28112e --- /dev/null +++ b/drivers/tty/serial/8250/8250_dma.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * 8250_dma.c - DMA Engine API support for 8250.c | ||
3 | * | ||
4 | * Copyright (C) 2013 Intel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/tty.h> | ||
12 | #include <linux/tty_flip.h> | ||
13 | #include <linux/serial_reg.h> | ||
14 | #include <linux/dma-mapping.h> | ||
15 | |||
16 | #include "8250.h" | ||
17 | |||
18 | static void __dma_tx_complete(void *param) | ||
19 | { | ||
20 | struct uart_8250_port *p = param; | ||
21 | struct uart_8250_dma *dma = p->dma; | ||
22 | struct circ_buf *xmit = &p->port.state->xmit; | ||
23 | |||
24 | dma->tx_running = 0; | ||
25 | |||
26 | dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, | ||
27 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
28 | |||
29 | xmit->tail += dma->tx_size; | ||
30 | xmit->tail &= UART_XMIT_SIZE - 1; | ||
31 | p->port.icount.tx += dma->tx_size; | ||
32 | |||
33 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
34 | uart_write_wakeup(&p->port); | ||
35 | |||
36 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) { | ||
37 | serial8250_tx_dma(p); | ||
38 | uart_write_wakeup(&p->port); | ||
39 | } | ||
40 | } | ||
41 | |||
42 | static void __dma_rx_complete(void *param) | ||
43 | { | ||
44 | struct uart_8250_port *p = param; | ||
45 | struct uart_8250_dma *dma = p->dma; | ||
46 | struct tty_port *tty_port = &p->port.state->port; | ||
47 | struct dma_tx_state state; | ||
48 | int count; | ||
49 | |||
50 | dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, | ||
51 | dma->rx_size, DMA_FROM_DEVICE); | ||
52 | |||
53 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | ||
54 | dmaengine_terminate_all(dma->rxchan); | ||
55 | |||
56 | count = dma->rx_size - state.residue; | ||
57 | |||
58 | tty_insert_flip_string(tty_port, dma->rx_buf, count); | ||
59 | p->port.icount.rx += count; | ||
60 | |||
61 | tty_flip_buffer_push(tty_port); | ||
62 | } | ||
63 | |||
64 | int serial8250_tx_dma(struct uart_8250_port *p) | ||
65 | { | ||
66 | struct uart_8250_dma *dma = p->dma; | ||
67 | struct circ_buf *xmit = &p->port.state->xmit; | ||
68 | struct dma_async_tx_descriptor *desc; | ||
69 | |||
70 | if (dma->tx_running) | ||
71 | return -EBUSY; | ||
72 | |||
73 | dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
74 | if (!dma->tx_size) | ||
75 | return -EINVAL; | ||
76 | |||
77 | desc = dmaengine_prep_slave_single(dma->txchan, | ||
78 | dma->tx_addr + xmit->tail, | ||
79 | dma->tx_size, DMA_MEM_TO_DEV, | ||
80 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
81 | if (!desc) | ||
82 | return -EBUSY; | ||
83 | |||
84 | dma->tx_running = 1; | ||
85 | |||
86 | desc->callback = __dma_tx_complete; | ||
87 | desc->callback_param = p; | ||
88 | |||
89 | dma->tx_cookie = dmaengine_submit(desc); | ||
90 | |||
91 | dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr, | ||
92 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
93 | |||
94 | dma_async_issue_pending(dma->txchan); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | EXPORT_SYMBOL_GPL(serial8250_tx_dma); | ||
99 | |||
100 | int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | ||
101 | { | ||
102 | struct uart_8250_dma *dma = p->dma; | ||
103 | struct dma_async_tx_descriptor *desc; | ||
104 | struct dma_tx_state state; | ||
105 | int dma_status; | ||
106 | |||
107 | /* | ||
108 | * If RCVR FIFO trigger level was not reached, complete the transfer and | ||
109 | * let 8250.c copy the remaining data. | ||
110 | */ | ||
111 | if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) { | ||
112 | dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, | ||
113 | &state); | ||
114 | if (dma_status == DMA_IN_PROGRESS) { | ||
115 | dmaengine_pause(dma->rxchan); | ||
116 | __dma_rx_complete(p); | ||
117 | } | ||
118 | return -ETIMEDOUT; | ||
119 | } | ||
120 | |||
121 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, | ||
122 | dma->rx_size, DMA_DEV_TO_MEM, | ||
123 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
124 | if (!desc) | ||
125 | return -EBUSY; | ||
126 | |||
127 | desc->callback = __dma_rx_complete; | ||
128 | desc->callback_param = p; | ||
129 | |||
130 | dma->rx_cookie = dmaengine_submit(desc); | ||
131 | |||
132 | dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr, | ||
133 | dma->rx_size, DMA_FROM_DEVICE); | ||
134 | |||
135 | dma_async_issue_pending(dma->rxchan); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(serial8250_rx_dma); | ||
140 | |||
141 | int serial8250_request_dma(struct uart_8250_port *p) | ||
142 | { | ||
143 | struct uart_8250_dma *dma = p->dma; | ||
144 | dma_cap_mask_t mask; | ||
145 | |||
146 | dma->rxconf.src_addr = p->port.mapbase + UART_RX; | ||
147 | dma->txconf.dst_addr = p->port.mapbase + UART_TX; | ||
148 | |||
149 | dma_cap_zero(mask); | ||
150 | dma_cap_set(DMA_SLAVE, mask); | ||
151 | |||
152 | /* Get a channel for RX */ | ||
153 | dma->rxchan = dma_request_channel(mask, dma->fn, dma->rx_param); | ||
154 | if (!dma->rxchan) | ||
155 | return -ENODEV; | ||
156 | |||
157 | dmaengine_slave_config(dma->rxchan, &dma->rxconf); | ||
158 | |||
159 | /* Get a channel for TX */ | ||
160 | dma->txchan = dma_request_channel(mask, dma->fn, dma->tx_param); | ||
161 | if (!dma->txchan) { | ||
162 | dma_release_channel(dma->rxchan); | ||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
166 | dmaengine_slave_config(dma->txchan, &dma->txconf); | ||
167 | |||
168 | /* RX buffer */ | ||
169 | if (!dma->rx_size) | ||
170 | dma->rx_size = PAGE_SIZE; | ||
171 | |||
172 | dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size, | ||
173 | &dma->rx_addr, GFP_KERNEL); | ||
174 | if (!dma->rx_buf) { | ||
175 | dma_release_channel(dma->rxchan); | ||
176 | dma_release_channel(dma->txchan); | ||
177 | return -ENOMEM; | ||
178 | } | ||
179 | |||
180 | /* TX buffer */ | ||
181 | dma->tx_addr = dma_map_single(dma->txchan->device->dev, | ||
182 | p->port.state->xmit.buf, | ||
183 | UART_XMIT_SIZE, | ||
184 | DMA_TO_DEVICE); | ||
185 | |||
186 | dev_dbg_ratelimited(p->port.dev, "got both dma channels\n"); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | EXPORT_SYMBOL_GPL(serial8250_request_dma); | ||
191 | |||
192 | void serial8250_release_dma(struct uart_8250_port *p) | ||
193 | { | ||
194 | struct uart_8250_dma *dma = p->dma; | ||
195 | |||
196 | if (!dma) | ||
197 | return; | ||
198 | |||
199 | /* Release RX resources */ | ||
200 | dmaengine_terminate_all(dma->rxchan); | ||
201 | dma_free_coherent(dma->rxchan->device->dev, dma->rx_size, dma->rx_buf, | ||
202 | dma->rx_addr); | ||
203 | dma_release_channel(dma->rxchan); | ||
204 | dma->rxchan = NULL; | ||
205 | |||
206 | /* Release TX resources */ | ||
207 | dmaengine_terminate_all(dma->txchan); | ||
208 | dma_unmap_single(dma->txchan->device->dev, dma->tx_addr, | ||
209 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
210 | dma_release_channel(dma->txchan); | ||
211 | dma->txchan = NULL; | ||
212 | dma->tx_running = 0; | ||
213 | |||
214 | dev_dbg_ratelimited(p->port.dev, "dma channels released\n"); | ||
215 | } | ||
216 | EXPORT_SYMBOL_GPL(serial8250_release_dma); | ||
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 096d2ef48b32..db0e66f6dd0e 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Synopsys DesignWare 8250 driver. | 2 | * Synopsys DesignWare 8250 driver. |
3 | * | 3 | * |
4 | * Copyright 2011 Picochip, Jamie Iles. | 4 | * Copyright 2011 Picochip, Jamie Iles. |
5 | * Copyright 2013 Intel Corporation | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -24,6 +25,34 @@ | |||
24 | #include <linux/of_platform.h> | 25 | #include <linux/of_platform.h> |
25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/acpi.h> | ||
29 | |||
30 | #include "8250.h" | ||
31 | |||
32 | /* Offsets for the DesignWare specific registers */ | ||
33 | #define DW_UART_USR 0x1f /* UART Status Register */ | ||
34 | #define DW_UART_CPR 0xf4 /* Component Parameter Register */ | ||
35 | #define DW_UART_UCV 0xf8 /* UART Component Version */ | ||
36 | |||
37 | /* Intel Low Power Subsystem specific */ | ||
38 | #define LPSS_PRV_CLOCK_PARAMS 0x800 | ||
39 | |||
40 | /* Component Parameter Register bits */ | ||
41 | #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) | ||
42 | #define DW_UART_CPR_AFCE_MODE (1 << 4) | ||
43 | #define DW_UART_CPR_THRE_MODE (1 << 5) | ||
44 | #define DW_UART_CPR_SIR_MODE (1 << 6) | ||
45 | #define DW_UART_CPR_SIR_LP_MODE (1 << 7) | ||
46 | #define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8) | ||
47 | #define DW_UART_CPR_FIFO_ACCESS (1 << 9) | ||
48 | #define DW_UART_CPR_FIFO_STAT (1 << 10) | ||
49 | #define DW_UART_CPR_SHADOW (1 << 11) | ||
50 | #define DW_UART_CPR_ENCODED_PARMS (1 << 12) | ||
51 | #define DW_UART_CPR_DMA_EXTRA (1 << 13) | ||
52 | #define DW_UART_CPR_FIFO_MODE (0xff << 16) | ||
53 | /* Helper for fifo size calculation */ | ||
54 | #define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16) | ||
55 | |||
27 | 56 | ||
28 | struct dw8250_data { | 57 | struct dw8250_data { |
29 | int last_lcr; | 58 | int last_lcr; |
@@ -66,9 +95,6 @@ static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) | |||
66 | return readl(p->membase + offset); | 95 | return readl(p->membase + offset); |
67 | } | 96 | } |
68 | 97 | ||
69 | /* Offset for the DesignWare's UART Status Register. */ | ||
70 | #define UART_USR 0x1f | ||
71 | |||
72 | static int dw8250_handle_irq(struct uart_port *p) | 98 | static int dw8250_handle_irq(struct uart_port *p) |
73 | { | 99 | { |
74 | struct dw8250_data *d = p->private_data; | 100 | struct dw8250_data *d = p->private_data; |
@@ -78,7 +104,7 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
78 | return 1; | 104 | return 1; |
79 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | 105 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { |
80 | /* Clear the USR and write the LCR again. */ | 106 | /* Clear the USR and write the LCR again. */ |
81 | (void)p->serial_in(p, UART_USR); | 107 | (void)p->serial_in(p, DW_UART_USR); |
82 | p->serial_out(p, UART_LCR, d->last_lcr); | 108 | p->serial_out(p, UART_LCR, d->last_lcr); |
83 | 109 | ||
84 | return 1; | 110 | return 1; |
@@ -87,61 +113,210 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
87 | return 0; | 113 | return 0; |
88 | } | 114 | } |
89 | 115 | ||
116 | static int dw8250_probe_of(struct uart_port *p) | ||
117 | { | ||
118 | struct device_node *np = p->dev->of_node; | ||
119 | u32 val; | ||
120 | |||
121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | ||
122 | switch (val) { | ||
123 | case 1: | ||
124 | break; | ||
125 | case 4: | ||
126 | p->iotype = UPIO_MEM32; | ||
127 | p->serial_in = dw8250_serial_in32; | ||
128 | p->serial_out = dw8250_serial_out32; | ||
129 | break; | ||
130 | default: | ||
131 | dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | if (!of_property_read_u32(np, "reg-shift", &val)) | ||
137 | p->regshift = val; | ||
138 | |||
139 | if (of_property_read_u32(np, "clock-frequency", &val)) { | ||
140 | dev_err(p->dev, "no clock-frequency property set\n"); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | p->uartclk = val; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | #ifdef CONFIG_ACPI | ||
149 | static bool dw8250_acpi_dma_filter(struct dma_chan *chan, void *parm) | ||
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 | { | ||
207 | const struct acpi_device_id *id; | ||
208 | acpi_status status; | ||
209 | u32 reg; | ||
210 | |||
211 | id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); | ||
212 | if (!id) | ||
213 | return -ENODEV; | ||
214 | |||
215 | p->iotype = UPIO_MEM32; | ||
216 | p->serial_in = dw8250_serial_in32; | ||
217 | p->serial_out = dw8250_serial_out32; | ||
218 | p->regshift = 2; | ||
219 | p->uartclk = (unsigned int)id->driver_data; | ||
220 | |||
221 | status = acpi_walk_resources(ACPI_HANDLE(p->dev), METHOD_NAME__CRS, | ||
222 | dw8250_acpi_walk_resource, p); | ||
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 | |||
229 | /* Fix Haswell issue where the clocks do not get enabled */ | ||
230 | if (!strcmp(id->id, "INT33C4") || !strcmp(id->id, "INT33C5")) { | ||
231 | reg = readl(p->membase + LPSS_PRV_CLOCK_PARAMS); | ||
232 | writel(reg | 1, p->membase + LPSS_PRV_CLOCK_PARAMS); | ||
233 | } | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | #else | ||
238 | static inline int dw8250_probe_acpi(struct uart_port *p) | ||
239 | { | ||
240 | return -ENODEV; | ||
241 | } | ||
242 | #endif /* CONFIG_ACPI */ | ||
243 | |||
244 | static void dw8250_setup_port(struct uart_8250_port *up) | ||
245 | { | ||
246 | struct uart_port *p = &up->port; | ||
247 | u32 reg = readl(p->membase + DW_UART_UCV); | ||
248 | |||
249 | /* | ||
250 | * If the Component Version Register returns zero, we know that | ||
251 | * ADDITIONAL_FEATURES are not enabled. No need to go any further. | ||
252 | */ | ||
253 | if (!reg) | ||
254 | return; | ||
255 | |||
256 | dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n", | ||
257 | (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); | ||
258 | |||
259 | reg = readl(p->membase + DW_UART_CPR); | ||
260 | if (!reg) | ||
261 | return; | ||
262 | |||
263 | /* Select the type based on fifo */ | ||
264 | if (reg & DW_UART_CPR_FIFO_MODE) { | ||
265 | p->type = PORT_16550A; | ||
266 | p->flags |= UPF_FIXED_TYPE; | ||
267 | p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); | ||
268 | up->tx_loadsz = p->fifosize; | ||
269 | } | ||
270 | } | ||
271 | |||
90 | static int dw8250_probe(struct platform_device *pdev) | 272 | static int dw8250_probe(struct platform_device *pdev) |
91 | { | 273 | { |
92 | struct uart_8250_port uart = {}; | 274 | struct uart_8250_port uart = {}; |
93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 275 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
94 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 276 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
95 | struct device_node *np = pdev->dev.of_node; | ||
96 | u32 val; | ||
97 | struct dw8250_data *data; | 277 | struct dw8250_data *data; |
278 | int err; | ||
98 | 279 | ||
99 | if (!regs || !irq) { | 280 | if (!regs || !irq) { |
100 | dev_err(&pdev->dev, "no registers/irq defined\n"); | 281 | dev_err(&pdev->dev, "no registers/irq defined\n"); |
101 | return -EINVAL; | 282 | return -EINVAL; |
102 | } | 283 | } |
103 | 284 | ||
104 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
105 | if (!data) | ||
106 | return -ENOMEM; | ||
107 | uart.port.private_data = data; | ||
108 | |||
109 | spin_lock_init(&uart.port.lock); | 285 | spin_lock_init(&uart.port.lock); |
110 | uart.port.mapbase = regs->start; | 286 | uart.port.mapbase = regs->start; |
111 | uart.port.irq = irq->start; | 287 | uart.port.irq = irq->start; |
112 | uart.port.handle_irq = dw8250_handle_irq; | 288 | uart.port.handle_irq = dw8250_handle_irq; |
113 | uart.port.type = PORT_8250; | 289 | uart.port.type = PORT_8250; |
114 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | | 290 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; |
115 | UPF_FIXED_PORT | UPF_FIXED_TYPE; | ||
116 | uart.port.dev = &pdev->dev; | 291 | uart.port.dev = &pdev->dev; |
117 | 292 | ||
293 | uart.port.membase = ioremap(regs->start, resource_size(regs)); | ||
294 | if (!uart.port.membase) | ||
295 | return -ENOMEM; | ||
296 | |||
118 | uart.port.iotype = UPIO_MEM; | 297 | uart.port.iotype = UPIO_MEM; |
119 | uart.port.serial_in = dw8250_serial_in; | 298 | uart.port.serial_in = dw8250_serial_in; |
120 | uart.port.serial_out = dw8250_serial_out; | 299 | uart.port.serial_out = dw8250_serial_out; |
121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | 300 | |
122 | switch (val) { | 301 | dw8250_setup_port(&uart); |
123 | case 1: | 302 | |
124 | break; | 303 | if (pdev->dev.of_node) { |
125 | case 4: | 304 | err = dw8250_probe_of(&uart.port); |
126 | uart.port.iotype = UPIO_MEM32; | 305 | if (err) |
127 | uart.port.serial_in = dw8250_serial_in32; | 306 | return err; |
128 | uart.port.serial_out = dw8250_serial_out32; | 307 | } else if (ACPI_HANDLE(&pdev->dev)) { |
129 | break; | 308 | err = dw8250_probe_acpi(&uart.port); |
130 | default: | 309 | if (err) |
131 | dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n", | 310 | return err; |
132 | val); | 311 | } else { |
133 | return -EINVAL; | 312 | return -ENODEV; |
134 | } | ||
135 | } | 313 | } |
136 | 314 | ||
137 | if (!of_property_read_u32(np, "reg-shift", &val)) | 315 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
138 | uart.port.regshift = val; | 316 | if (!data) |
317 | return -ENOMEM; | ||
139 | 318 | ||
140 | if (of_property_read_u32(np, "clock-frequency", &val)) { | 319 | uart.port.private_data = data; |
141 | dev_err(&pdev->dev, "no clock-frequency property set\n"); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | uart.port.uartclk = val; | ||
145 | 320 | ||
146 | data->line = serial8250_register_8250_port(&uart); | 321 | data->line = serial8250_register_8250_port(&uart); |
147 | if (data->line < 0) | 322 | if (data->line < 0) |
@@ -184,17 +359,25 @@ static int dw8250_resume(struct platform_device *pdev) | |||
184 | #define dw8250_resume NULL | 359 | #define dw8250_resume NULL |
185 | #endif /* CONFIG_PM */ | 360 | #endif /* CONFIG_PM */ |
186 | 361 | ||
187 | static const struct of_device_id dw8250_match[] = { | 362 | static const struct of_device_id dw8250_of_match[] = { |
188 | { .compatible = "snps,dw-apb-uart" }, | 363 | { .compatible = "snps,dw-apb-uart" }, |
189 | { /* Sentinel */ } | 364 | { /* Sentinel */ } |
190 | }; | 365 | }; |
191 | MODULE_DEVICE_TABLE(of, dw8250_match); | 366 | MODULE_DEVICE_TABLE(of, dw8250_of_match); |
367 | |||
368 | static const struct acpi_device_id dw8250_acpi_match[] = { | ||
369 | { "INT33C4", 100000000 }, | ||
370 | { "INT33C5", 100000000 }, | ||
371 | { }, | ||
372 | }; | ||
373 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | ||
192 | 374 | ||
193 | static struct platform_driver dw8250_platform_driver = { | 375 | static struct platform_driver dw8250_platform_driver = { |
194 | .driver = { | 376 | .driver = { |
195 | .name = "dw-apb-uart", | 377 | .name = "dw-apb-uart", |
196 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
197 | .of_match_table = dw8250_match, | 379 | .of_match_table = dw8250_of_match, |
380 | .acpi_match_table = ACPI_PTR(dw8250_acpi_match), | ||
198 | }, | 381 | }, |
199 | .probe = dw8250_probe, | 382 | .probe = dw8250_probe, |
200 | .remove = dw8250_remove, | 383 | .remove = dw8250_remove, |
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index f53a7db4350d..721904f8efa9 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c | |||
@@ -194,7 +194,7 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
194 | options++; | 194 | options++; |
195 | device->baud = simple_strtoul(options, NULL, 0); | 195 | device->baud = simple_strtoul(options, NULL, 0); |
196 | length = min(strcspn(options, " "), sizeof(device->options)); | 196 | length = min(strcspn(options, " "), sizeof(device->options)); |
197 | strncpy(device->options, options, length); | 197 | strlcpy(device->options, options, length); |
198 | } else { | 198 | } else { |
199 | device->baud = probe_baud(port); | 199 | device->baud = probe_baud(port); |
200 | snprintf(device->options, sizeof(device->options), "%u", | 200 | snprintf(device->options, sizeof(device->options), "%u", |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index a27a98e1b066..791c5a77ec61 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1040,6 +1040,253 @@ static int pci_asix_setup(struct serial_private *priv, | |||
1040 | return pci_default_setup(priv, board, port, idx); | 1040 | return pci_default_setup(priv, board, port, idx); |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | /* Quatech devices have their own extra interface features */ | ||
1044 | |||
1045 | struct quatech_feature { | ||
1046 | u16 devid; | ||
1047 | bool amcc; | ||
1048 | }; | ||
1049 | |||
1050 | #define QPCR_TEST_FOR1 0x3F | ||
1051 | #define QPCR_TEST_GET1 0x00 | ||
1052 | #define QPCR_TEST_FOR2 0x40 | ||
1053 | #define QPCR_TEST_GET2 0x40 | ||
1054 | #define QPCR_TEST_FOR3 0x80 | ||
1055 | #define QPCR_TEST_GET3 0x40 | ||
1056 | #define QPCR_TEST_FOR4 0xC0 | ||
1057 | #define QPCR_TEST_GET4 0x80 | ||
1058 | |||
1059 | #define QOPR_CLOCK_X1 0x0000 | ||
1060 | #define QOPR_CLOCK_X2 0x0001 | ||
1061 | #define QOPR_CLOCK_X4 0x0002 | ||
1062 | #define QOPR_CLOCK_X8 0x0003 | ||
1063 | #define QOPR_CLOCK_RATE_MASK 0x0003 | ||
1064 | |||
1065 | |||
1066 | static struct quatech_feature quatech_cards[] = { | ||
1067 | { PCI_DEVICE_ID_QUATECH_QSC100, 1 }, | ||
1068 | { PCI_DEVICE_ID_QUATECH_DSC100, 1 }, | ||
1069 | { PCI_DEVICE_ID_QUATECH_DSC100E, 0 }, | ||
1070 | { PCI_DEVICE_ID_QUATECH_DSC200, 1 }, | ||
1071 | { PCI_DEVICE_ID_QUATECH_DSC200E, 0 }, | ||
1072 | { PCI_DEVICE_ID_QUATECH_ESC100D, 1 }, | ||
1073 | { PCI_DEVICE_ID_QUATECH_ESC100M, 1 }, | ||
1074 | { PCI_DEVICE_ID_QUATECH_QSCP100, 1 }, | ||
1075 | { PCI_DEVICE_ID_QUATECH_DSCP100, 1 }, | ||
1076 | { PCI_DEVICE_ID_QUATECH_QSCP200, 1 }, | ||
1077 | { PCI_DEVICE_ID_QUATECH_DSCP200, 1 }, | ||
1078 | { PCI_DEVICE_ID_QUATECH_ESCLP100, 0 }, | ||
1079 | { PCI_DEVICE_ID_QUATECH_QSCLP100, 0 }, | ||
1080 | { PCI_DEVICE_ID_QUATECH_DSCLP100, 0 }, | ||
1081 | { PCI_DEVICE_ID_QUATECH_SSCLP100, 0 }, | ||
1082 | { PCI_DEVICE_ID_QUATECH_QSCLP200, 0 }, | ||
1083 | { PCI_DEVICE_ID_QUATECH_DSCLP200, 0 }, | ||
1084 | { PCI_DEVICE_ID_QUATECH_SSCLP200, 0 }, | ||
1085 | { PCI_DEVICE_ID_QUATECH_SPPXP_100, 0 }, | ||
1086 | { 0, } | ||
1087 | }; | ||
1088 | |||
1089 | static int pci_quatech_amcc(u16 devid) | ||
1090 | { | ||
1091 | struct quatech_feature *qf = &quatech_cards[0]; | ||
1092 | while (qf->devid) { | ||
1093 | if (qf->devid == devid) | ||
1094 | return qf->amcc; | ||
1095 | qf++; | ||
1096 | } | ||
1097 | pr_err("quatech: unknown port type '0x%04X'.\n", devid); | ||
1098 | return 0; | ||
1099 | }; | ||
1100 | |||
1101 | static int pci_quatech_rqopr(struct uart_8250_port *port) | ||
1102 | { | ||
1103 | unsigned long base = port->port.iobase; | ||
1104 | u8 LCR, val; | ||
1105 | |||
1106 | LCR = inb(base + UART_LCR); | ||
1107 | outb(0xBF, base + UART_LCR); | ||
1108 | val = inb(base + UART_SCR); | ||
1109 | outb(LCR, base + UART_LCR); | ||
1110 | return val; | ||
1111 | } | ||
1112 | |||
1113 | static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr) | ||
1114 | { | ||
1115 | unsigned long base = port->port.iobase; | ||
1116 | u8 LCR, val; | ||
1117 | |||
1118 | LCR = inb(base + UART_LCR); | ||
1119 | outb(0xBF, base + UART_LCR); | ||
1120 | val = inb(base + UART_SCR); | ||
1121 | outb(qopr, base + UART_SCR); | ||
1122 | outb(LCR, base + UART_LCR); | ||
1123 | } | ||
1124 | |||
1125 | static int pci_quatech_rqmcr(struct uart_8250_port *port) | ||
1126 | { | ||
1127 | unsigned long base = port->port.iobase; | ||
1128 | u8 LCR, val, qmcr; | ||
1129 | |||
1130 | LCR = inb(base + UART_LCR); | ||
1131 | outb(0xBF, base + UART_LCR); | ||
1132 | val = inb(base + UART_SCR); | ||
1133 | outb(val | 0x10, base + UART_SCR); | ||
1134 | qmcr = inb(base + UART_MCR); | ||
1135 | outb(val, base + UART_SCR); | ||
1136 | outb(LCR, base + UART_LCR); | ||
1137 | |||
1138 | return qmcr; | ||
1139 | } | ||
1140 | |||
1141 | static void pci_quatech_wqmcr(struct uart_8250_port *port, u8 qmcr) | ||
1142 | { | ||
1143 | unsigned long base = port->port.iobase; | ||
1144 | u8 LCR, val; | ||
1145 | |||
1146 | LCR = inb(base + UART_LCR); | ||
1147 | outb(0xBF, base + UART_LCR); | ||
1148 | val = inb(base + UART_SCR); | ||
1149 | outb(val | 0x10, base + UART_SCR); | ||
1150 | outb(qmcr, base + UART_MCR); | ||
1151 | outb(val, base + UART_SCR); | ||
1152 | outb(LCR, base + UART_LCR); | ||
1153 | } | ||
1154 | |||
1155 | static int pci_quatech_has_qmcr(struct uart_8250_port *port) | ||
1156 | { | ||
1157 | unsigned long base = port->port.iobase; | ||
1158 | u8 LCR, val; | ||
1159 | |||
1160 | LCR = inb(base + UART_LCR); | ||
1161 | outb(0xBF, base + UART_LCR); | ||
1162 | val = inb(base + UART_SCR); | ||
1163 | if (val & 0x20) { | ||
1164 | outb(0x80, UART_LCR); | ||
1165 | if (!(inb(UART_SCR) & 0x20)) { | ||
1166 | outb(LCR, base + UART_LCR); | ||
1167 | return 1; | ||
1168 | } | ||
1169 | } | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static int pci_quatech_test(struct uart_8250_port *port) | ||
1174 | { | ||
1175 | u8 reg; | ||
1176 | u8 qopr = pci_quatech_rqopr(port); | ||
1177 | pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1); | ||
1178 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1179 | if (reg != QPCR_TEST_GET1) | ||
1180 | return -EINVAL; | ||
1181 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR2); | ||
1182 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1183 | if (reg != QPCR_TEST_GET2) | ||
1184 | return -EINVAL; | ||
1185 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR3); | ||
1186 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1187 | if (reg != QPCR_TEST_GET3) | ||
1188 | return -EINVAL; | ||
1189 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR4); | ||
1190 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1191 | if (reg != QPCR_TEST_GET4) | ||
1192 | return -EINVAL; | ||
1193 | |||
1194 | pci_quatech_wqopr(port, qopr); | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | static int pci_quatech_clock(struct uart_8250_port *port) | ||
1199 | { | ||
1200 | u8 qopr, reg, set; | ||
1201 | unsigned long clock; | ||
1202 | |||
1203 | if (pci_quatech_test(port) < 0) | ||
1204 | return 1843200; | ||
1205 | |||
1206 | qopr = pci_quatech_rqopr(port); | ||
1207 | |||
1208 | pci_quatech_wqopr(port, qopr & ~QOPR_CLOCK_X8); | ||
1209 | reg = pci_quatech_rqopr(port); | ||
1210 | if (reg & QOPR_CLOCK_X8) { | ||
1211 | clock = 1843200; | ||
1212 | goto out; | ||
1213 | } | ||
1214 | pci_quatech_wqopr(port, qopr | QOPR_CLOCK_X8); | ||
1215 | reg = pci_quatech_rqopr(port); | ||
1216 | if (!(reg & QOPR_CLOCK_X8)) { | ||
1217 | clock = 1843200; | ||
1218 | goto out; | ||
1219 | } | ||
1220 | reg &= QOPR_CLOCK_X8; | ||
1221 | if (reg == QOPR_CLOCK_X2) { | ||
1222 | clock = 3685400; | ||
1223 | set = QOPR_CLOCK_X2; | ||
1224 | } else if (reg == QOPR_CLOCK_X4) { | ||
1225 | clock = 7372800; | ||
1226 | set = QOPR_CLOCK_X4; | ||
1227 | } else if (reg == QOPR_CLOCK_X8) { | ||
1228 | clock = 14745600; | ||
1229 | set = QOPR_CLOCK_X8; | ||
1230 | } else { | ||
1231 | clock = 1843200; | ||
1232 | set = QOPR_CLOCK_X1; | ||
1233 | } | ||
1234 | qopr &= ~QOPR_CLOCK_RATE_MASK; | ||
1235 | qopr |= set; | ||
1236 | |||
1237 | out: | ||
1238 | pci_quatech_wqopr(port, qopr); | ||
1239 | return clock; | ||
1240 | } | ||
1241 | |||
1242 | static int pci_quatech_rs422(struct uart_8250_port *port) | ||
1243 | { | ||
1244 | u8 qmcr; | ||
1245 | int rs422 = 0; | ||
1246 | |||
1247 | if (!pci_quatech_has_qmcr(port)) | ||
1248 | return 0; | ||
1249 | qmcr = pci_quatech_rqmcr(port); | ||
1250 | pci_quatech_wqmcr(port, 0xFF); | ||
1251 | if (pci_quatech_rqmcr(port)) | ||
1252 | rs422 = 1; | ||
1253 | pci_quatech_wqmcr(port, qmcr); | ||
1254 | return rs422; | ||
1255 | } | ||
1256 | |||
1257 | static int pci_quatech_init(struct pci_dev *dev) | ||
1258 | { | ||
1259 | if (pci_quatech_amcc(dev->device)) { | ||
1260 | unsigned long base = pci_resource_start(dev, 0); | ||
1261 | if (base) { | ||
1262 | u32 tmp; | ||
1263 | outl(inl(base + 0x38), base + 0x38); | ||
1264 | tmp = inl(base + 0x3c); | ||
1265 | outl(tmp | 0x01000000, base + 0x3c); | ||
1266 | outl(tmp, base + 0x3c); | ||
1267 | } | ||
1268 | } | ||
1269 | return 0; | ||
1270 | } | ||
1271 | |||
1272 | static int pci_quatech_setup(struct serial_private *priv, | ||
1273 | const struct pciserial_board *board, | ||
1274 | struct uart_8250_port *port, int idx) | ||
1275 | { | ||
1276 | /* Needed by pci_quatech calls below */ | ||
1277 | port->port.iobase = pci_resource_start(priv->dev, FL_GET_BASE(board->flags)); | ||
1278 | /* Set up the clocking */ | ||
1279 | port->port.uartclk = pci_quatech_clock(port); | ||
1280 | /* For now just warn about RS422 */ | ||
1281 | if (pci_quatech_rs422(port)) | ||
1282 | pr_warn("quatech: software control of RS422 features not currently supported.\n"); | ||
1283 | return pci_default_setup(priv, board, port, idx); | ||
1284 | } | ||
1285 | |||
1286 | static void pci_quatech_exit(struct pci_dev *dev) | ||
1287 | { | ||
1288 | } | ||
1289 | |||
1043 | static int pci_default_setup(struct serial_private *priv, | 1290 | static int pci_default_setup(struct serial_private *priv, |
1044 | const struct pciserial_board *board, | 1291 | const struct pciserial_board *board, |
1045 | struct uart_8250_port *port, int idx) | 1292 | struct uart_8250_port *port, int idx) |
@@ -1318,6 +1565,9 @@ pci_wch_ch353_setup(struct serial_private *priv, | |||
1318 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 | 1565 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 |
1319 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a | 1566 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a |
1320 | 1567 | ||
1568 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 | ||
1569 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 | ||
1570 | |||
1321 | 1571 | ||
1322 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1572 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1323 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1573 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -1541,6 +1791,16 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1541 | .setup = pci_ni8430_setup, | 1791 | .setup = pci_ni8430_setup, |
1542 | .exit = pci_ni8430_exit, | 1792 | .exit = pci_ni8430_exit, |
1543 | }, | 1793 | }, |
1794 | /* Quatech */ | ||
1795 | { | ||
1796 | .vendor = PCI_VENDOR_ID_QUATECH, | ||
1797 | .device = PCI_ANY_ID, | ||
1798 | .subvendor = PCI_ANY_ID, | ||
1799 | .subdevice = PCI_ANY_ID, | ||
1800 | .init = pci_quatech_init, | ||
1801 | .setup = pci_quatech_setup, | ||
1802 | .exit = pci_quatech_exit, | ||
1803 | }, | ||
1544 | /* | 1804 | /* |
1545 | * Panacom | 1805 | * Panacom |
1546 | */ | 1806 | */ |
@@ -1704,6 +1964,23 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1704 | .setup = pci_timedia_setup, | 1964 | .setup = pci_timedia_setup, |
1705 | }, | 1965 | }, |
1706 | /* | 1966 | /* |
1967 | * SUNIX (Timedia) cards | ||
1968 | * Do not "probe" for these cards as there is at least one combination | ||
1969 | * card that should be handled by parport_pc that doesn't match the | ||
1970 | * rule in pci_timedia_probe. | ||
1971 | * It is part number is MIO5079A but its subdevice ID is 0x0102. | ||
1972 | * There are some boards with part number SER5037AL that report | ||
1973 | * subdevice ID 0x0002. | ||
1974 | */ | ||
1975 | { | ||
1976 | .vendor = PCI_VENDOR_ID_SUNIX, | ||
1977 | .device = PCI_DEVICE_ID_SUNIX_1999, | ||
1978 | .subvendor = PCI_VENDOR_ID_SUNIX, | ||
1979 | .subdevice = PCI_ANY_ID, | ||
1980 | .init = pci_timedia_init, | ||
1981 | .setup = pci_timedia_setup, | ||
1982 | }, | ||
1983 | /* | ||
1707 | * Exar cards | 1984 | * Exar cards |
1708 | */ | 1985 | */ |
1709 | { | 1986 | { |
@@ -3506,18 +3783,70 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3506 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, | 3783 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, |
3507 | 0x10b5, 0x106a, 0, 0, | 3784 | 0x10b5, 0x106a, 0, 0, |
3508 | pbn_plx_romulus }, | 3785 | pbn_plx_romulus }, |
3786 | /* | ||
3787 | * Quatech cards. These actually have configurable clocks but for | ||
3788 | * now we just use the default. | ||
3789 | * | ||
3790 | * 100 series are RS232, 200 series RS422, | ||
3791 | */ | ||
3509 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, | 3792 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, |
3510 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3793 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3511 | pbn_b1_4_115200 }, | 3794 | pbn_b1_4_115200 }, |
3512 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100, | 3795 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100, |
3513 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3796 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3514 | pbn_b1_2_115200 }, | 3797 | pbn_b1_2_115200 }, |
3798 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100E, | ||
3799 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3800 | pbn_b2_2_115200 }, | ||
3801 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200, | ||
3802 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3803 | pbn_b1_2_115200 }, | ||
3804 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200E, | ||
3805 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3806 | pbn_b2_2_115200 }, | ||
3807 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC200, | ||
3808 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3809 | pbn_b1_4_115200 }, | ||
3515 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D, | 3810 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D, |
3516 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3811 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3517 | pbn_b1_8_115200 }, | 3812 | pbn_b1_8_115200 }, |
3518 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, | 3813 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, |
3519 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3814 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3520 | pbn_b1_8_115200 }, | 3815 | pbn_b1_8_115200 }, |
3816 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP100, | ||
3817 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3818 | pbn_b1_4_115200 }, | ||
3819 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP100, | ||
3820 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3821 | pbn_b1_2_115200 }, | ||
3822 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP200, | ||
3823 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3824 | pbn_b1_4_115200 }, | ||
3825 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP200, | ||
3826 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3827 | pbn_b1_2_115200 }, | ||
3828 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP100, | ||
3829 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3830 | pbn_b2_4_115200 }, | ||
3831 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP100, | ||
3832 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3833 | pbn_b2_2_115200 }, | ||
3834 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP100, | ||
3835 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3836 | pbn_b2_1_115200 }, | ||
3837 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP200, | ||
3838 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3839 | pbn_b2_4_115200 }, | ||
3840 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP200, | ||
3841 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3842 | pbn_b2_2_115200 }, | ||
3843 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP200, | ||
3844 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3845 | pbn_b2_1_115200 }, | ||
3846 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESCLP100, | ||
3847 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3848 | pbn_b0_8_115200 }, | ||
3849 | |||
3521 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, | 3850 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, |
3522 | PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, | 3851 | PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, |
3523 | 0, 0, | 3852 | 0, 0, |
@@ -3902,6 +4231,19 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3902 | pbn_b0_bt_1_921600 }, | 4231 | pbn_b0_bt_1_921600 }, |
3903 | 4232 | ||
3904 | /* | 4233 | /* |
4234 | * SUNIX (TIMEDIA) | ||
4235 | */ | ||
4236 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, | ||
4237 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, | ||
4238 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, | ||
4239 | pbn_b0_bt_1_921600 }, | ||
4240 | |||
4241 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, | ||
4242 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, | ||
4243 | PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, | ||
4244 | pbn_b0_bt_1_921600 }, | ||
4245 | |||
4246 | /* | ||
3905 | * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> | 4247 | * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> |
3906 | */ | 4248 | */ |
3907 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, | 4249 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, |
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c31133a6ea8e..2ef9537bcb2c 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -84,6 +84,14 @@ config SERIAL_8250_GSC | |||
84 | depends on SERIAL_8250 && GSC | 84 | depends on SERIAL_8250 && GSC |
85 | default SERIAL_8250 | 85 | default SERIAL_8250 |
86 | 86 | ||
87 | config SERIAL_8250_DMA | ||
88 | bool "DMA support for 16550 compatible UART controllers" if EXPERT | ||
89 | depends on SERIAL_8250 && DMADEVICES=y | ||
90 | default SERIAL_8250 | ||
91 | help | ||
92 | This builds DMA support that can be used with 8250/16650 | ||
93 | compatible UART controllers that support DMA signaling. | ||
94 | |||
87 | config SERIAL_8250_PCI | 95 | config SERIAL_8250_PCI |
88 | tristate "8250/16550 PCI device support" if EXPERT | 96 | tristate "8250/16550 PCI device support" if EXPERT |
89 | depends on SERIAL_8250 && PCI | 97 | depends on SERIAL_8250 && PCI |
@@ -249,15 +257,6 @@ config SERIAL_8250_ACORN | |||
249 | system, say Y to this option. The driver can handle 1, 2, or 3 port | 257 | system, say Y to this option. The driver can handle 1, 2, or 3 port |
250 | cards. If unsure, say N. | 258 | cards. If unsure, say N. |
251 | 259 | ||
252 | config SERIAL_8250_RM9K | ||
253 | bool "Support for MIPS RM9xxx integrated serial port" | ||
254 | depends on SERIAL_8250 != n && SERIAL_RM9000 | ||
255 | select SERIAL_8250_SHARE_IRQ | ||
256 | help | ||
257 | Selecting this option will add support for the integrated serial | ||
258 | port hardware found on MIPS RM9122 and similar processors. | ||
259 | If unsure, say N. | ||
260 | |||
261 | config SERIAL_8250_FSL | 260 | config SERIAL_8250_FSL |
262 | bool | 261 | bool |
263 | depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 | 262 | depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 |
@@ -265,7 +264,7 @@ config SERIAL_8250_FSL | |||
265 | 264 | ||
266 | config SERIAL_8250_DW | 265 | config SERIAL_8250_DW |
267 | tristate "Support for Synopsys DesignWare 8250 quirks" | 266 | tristate "Support for Synopsys DesignWare 8250 quirks" |
268 | depends on SERIAL_8250 && OF | 267 | depends on SERIAL_8250 |
269 | help | 268 | help |
270 | Selecting this option will enable handling of the extra features | 269 | Selecting this option will enable handling of the extra features |
271 | present in the Synopsys DesignWare APB UART. | 270 | present in the Synopsys DesignWare APB UART. |
@@ -277,3 +276,11 @@ config SERIAL_8250_EM | |||
277 | Selecting this option will add support for the integrated serial | 276 | Selecting this option will add support for the integrated serial |
278 | port hardware found on the Emma Mobile line of processors. | 277 | port hardware found on the Emma Mobile line of processors. |
279 | If unsure, say N. | 278 | If unsure, say N. |
279 | |||
280 | config SERIAL_8250_RT288X | ||
281 | bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" | ||
282 | depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883) | ||
283 | help | ||
284 | If you have a Ralink RT288x/RT305x SoC based board and want to use the | ||
285 | serial port, say Y to this option. The driver can handle up to 2 serial | ||
286 | ports. If unsure, say N. | ||
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 108fe7fe13e2..a23838a4d535 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | obj-$(CONFIG_SERIAL_8250) += 8250_core.o | 5 | obj-$(CONFIG_SERIAL_8250) += 8250_core.o |
6 | 8250_core-y := 8250.o | 6 | 8250_core-y := 8250.o |
7 | 8250_core-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o | 7 | 8250_core-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o |
8 | 8250_core-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o | ||
8 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o | 9 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o |
9 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o | 10 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o |
10 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o | 11 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 59c23d038106..a0162cbf0557 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -2,8 +2,10 @@ | |||
2 | # Serial device configuration | 2 | # Serial device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | if TTY | ||
6 | |||
5 | menu "Serial drivers" | 7 | menu "Serial drivers" |
6 | depends on HAS_IOMEM | 8 | depends on HAS_IOMEM && GENERIC_HARDIRQS |
7 | 9 | ||
8 | source "drivers/tty/serial/8250/Kconfig" | 10 | source "drivers/tty/serial/8250/Kconfig" |
9 | 11 | ||
@@ -269,6 +271,17 @@ config SERIAL_SIRFSOC_CONSOLE | |||
269 | your boot loader about how to pass options to the kernel at | 271 | your boot loader about how to pass options to the kernel at |
270 | boot time.) | 272 | boot time.) |
271 | 273 | ||
274 | config SERIAL_TEGRA | ||
275 | tristate "NVIDIA Tegra20/30 SoC serial controller" | ||
276 | depends on ARCH_TEGRA && TEGRA20_APB_DMA | ||
277 | select SERIAL_CORE | ||
278 | help | ||
279 | Support for the on-chip UARTs on the NVIDIA Tegra series SOCs | ||
280 | providing /dev/ttyHS0, 1, 2, 3 and 4 (note, some machines may not | ||
281 | provide all of these ports, depending on how the serial port | ||
282 | are enabled). This driver uses the APB DMA to achieve higher baudrate | ||
283 | and better performance. | ||
284 | |||
272 | config SERIAL_MAX3100 | 285 | config SERIAL_MAX3100 |
273 | tristate "MAX3100 support" | 286 | tristate "MAX3100 support" |
274 | depends on SPI | 287 | depends on SPI |
@@ -1447,4 +1460,30 @@ config SERIAL_ARC_NR_PORTS | |||
1447 | Set this to the number of serial ports you want the driver | 1460 | Set this to the number of serial ports you want the driver |
1448 | to support. | 1461 | to support. |
1449 | 1462 | ||
1463 | config SERIAL_RP2 | ||
1464 | tristate "Comtrol RocketPort EXPRESS/INFINITY support" | ||
1465 | depends on PCI | ||
1466 | select SERIAL_CORE | ||
1467 | help | ||
1468 | This driver supports the Comtrol RocketPort EXPRESS and | ||
1469 | RocketPort INFINITY families of PCI/PCIe multiport serial adapters. | ||
1470 | These adapters use a "RocketPort 2" ASIC that is not compatible | ||
1471 | with the original RocketPort driver (CONFIG_ROCKETPORT). | ||
1472 | |||
1473 | To compile this driver as a module, choose M here: the | ||
1474 | module will be called rp2. | ||
1475 | |||
1476 | If you want to compile this driver into the kernel, say Y here. If | ||
1477 | you don't have a suitable RocketPort card installed, say N. | ||
1478 | |||
1479 | config SERIAL_RP2_NR_UARTS | ||
1480 | int "Maximum number of RocketPort EXPRESS/INFINITY ports" | ||
1481 | depends on SERIAL_RP2 | ||
1482 | default "32" | ||
1483 | help | ||
1484 | If multiple cards are present, the default limit of 32 ports may | ||
1485 | need to be increased. | ||
1486 | |||
1450 | endmenu | 1487 | endmenu |
1488 | |||
1489 | endif # TTY | ||
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index df1b998c436b..eedfec40e3dd 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -80,6 +80,8 @@ obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o | |||
80 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | 80 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o |
81 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | 81 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o |
82 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o | 82 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o |
83 | obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o | ||
83 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o | 84 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o |
84 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o | 85 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o |
85 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o | 86 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o |
87 | obj-$(CONFIG_SERIAL_RP2) += rp2.o | ||
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 872f14ae43d2..c6bdb943726b 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c | |||
@@ -139,7 +139,7 @@ static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) | |||
139 | uart_insert_char(port, 0, 0, ch, flag); | 139 | uart_insert_char(port, 0, 0, ch, flag); |
140 | } | 140 | } |
141 | 141 | ||
142 | tty_flip_buffer_push(port->state->port.tty); | 142 | tty_flip_buffer_push(&port->state->port); |
143 | } | 143 | } |
144 | 144 | ||
145 | static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) | 145 | static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) |
@@ -493,11 +493,9 @@ static int __init altera_jtaguart_init(void) | |||
493 | if (rc) | 493 | if (rc) |
494 | return rc; | 494 | return rc; |
495 | rc = platform_driver_register(&altera_jtaguart_platform_driver); | 495 | rc = platform_driver_register(&altera_jtaguart_platform_driver); |
496 | if (rc) { | 496 | if (rc) |
497 | uart_unregister_driver(&altera_jtaguart_driver); | 497 | uart_unregister_driver(&altera_jtaguart_driver); |
498 | return rc; | 498 | return rc; |
499 | } | ||
500 | return 0; | ||
501 | } | 499 | } |
502 | 500 | ||
503 | static void __exit altera_jtaguart_exit(void) | 501 | static void __exit altera_jtaguart_exit(void) |
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 684a0808e1c7..13471dd95793 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -231,7 +231,7 @@ static void altera_uart_rx_chars(struct altera_uart *pp) | |||
231 | flag); | 231 | flag); |
232 | } | 232 | } |
233 | 233 | ||
234 | tty_flip_buffer_push(port->state->port.tty); | 234 | tty_flip_buffer_push(&port->state->port); |
235 | } | 235 | } |
236 | 236 | ||
237 | static void altera_uart_tx_chars(struct altera_uart *pp) | 237 | static void altera_uart_tx_chars(struct altera_uart *pp) |
@@ -637,11 +637,9 @@ static int __init altera_uart_init(void) | |||
637 | if (rc) | 637 | if (rc) |
638 | return rc; | 638 | return rc; |
639 | rc = platform_driver_register(&altera_uart_platform_driver); | 639 | rc = platform_driver_register(&altera_uart_platform_driver); |
640 | if (rc) { | 640 | if (rc) |
641 | uart_unregister_driver(&altera_uart_driver); | 641 | uart_unregister_driver(&altera_uart_driver); |
642 | return rc; | 642 | return rc; |
643 | } | ||
644 | return 0; | ||
645 | } | 643 | } |
646 | 644 | ||
647 | static void __exit altera_uart_exit(void) | 645 | static void __exit altera_uart_exit(void) |
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 22317dd16474..c36840519527 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c | |||
@@ -116,7 +116,6 @@ static void pl010_enable_ms(struct uart_port *port) | |||
116 | 116 | ||
117 | static void pl010_rx_chars(struct uart_amba_port *uap) | 117 | static void pl010_rx_chars(struct uart_amba_port *uap) |
118 | { | 118 | { |
119 | struct tty_struct *tty = uap->port.state->port.tty; | ||
120 | unsigned int status, ch, flag, rsr, max_count = 256; | 119 | unsigned int status, ch, flag, rsr, max_count = 256; |
121 | 120 | ||
122 | status = readb(uap->port.membase + UART01x_FR); | 121 | status = readb(uap->port.membase + UART01x_FR); |
@@ -165,7 +164,7 @@ static void pl010_rx_chars(struct uart_amba_port *uap) | |||
165 | status = readb(uap->port.membase + UART01x_FR); | 164 | status = readb(uap->port.membase + UART01x_FR); |
166 | } | 165 | } |
167 | spin_unlock(&uap->port.lock); | 166 | spin_unlock(&uap->port.lock); |
168 | tty_flip_buffer_push(tty); | 167 | tty_flip_buffer_push(&uap->port.state->port); |
169 | spin_lock(&uap->port.lock); | 168 | spin_lock(&uap->port.lock); |
170 | } | 169 | } |
171 | 170 | ||
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 7fca4022a8b2..3ea5408fcbeb 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -698,7 +698,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
698 | u32 pending, bool use_buf_b, | 698 | u32 pending, bool use_buf_b, |
699 | bool readfifo) | 699 | bool readfifo) |
700 | { | 700 | { |
701 | struct tty_struct *tty = uap->port.state->port.tty; | 701 | struct tty_port *port = &uap->port.state->port; |
702 | struct pl011_sgbuf *sgbuf = use_buf_b ? | 702 | struct pl011_sgbuf *sgbuf = use_buf_b ? |
703 | &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; | 703 | &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; |
704 | struct device *dev = uap->dmarx.chan->device->dev; | 704 | struct device *dev = uap->dmarx.chan->device->dev; |
@@ -715,8 +715,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
715 | * Note that tty_insert_flip_buf() tries to take as many chars | 715 | * Note that tty_insert_flip_buf() tries to take as many chars |
716 | * as it can. | 716 | * as it can. |
717 | */ | 717 | */ |
718 | dma_count = tty_insert_flip_string(uap->port.state->port.tty, | 718 | dma_count = tty_insert_flip_string(port, sgbuf->buf, pending); |
719 | sgbuf->buf, pending); | ||
720 | 719 | ||
721 | /* Return buffer to device */ | 720 | /* Return buffer to device */ |
722 | dma_sync_sg_for_device(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE); | 721 | dma_sync_sg_for_device(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE); |
@@ -754,7 +753,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
754 | dev_vdbg(uap->port.dev, | 753 | dev_vdbg(uap->port.dev, |
755 | "Took %d chars from DMA buffer and %d chars from the FIFO\n", | 754 | "Took %d chars from DMA buffer and %d chars from the FIFO\n", |
756 | dma_count, fifotaken); | 755 | dma_count, fifotaken); |
757 | tty_flip_buffer_push(tty); | 756 | tty_flip_buffer_push(port); |
758 | spin_lock(&uap->port.lock); | 757 | spin_lock(&uap->port.lock); |
759 | } | 758 | } |
760 | 759 | ||
@@ -1076,12 +1075,10 @@ static void pl011_enable_ms(struct uart_port *port) | |||
1076 | 1075 | ||
1077 | static void pl011_rx_chars(struct uart_amba_port *uap) | 1076 | static void pl011_rx_chars(struct uart_amba_port *uap) |
1078 | { | 1077 | { |
1079 | struct tty_struct *tty = uap->port.state->port.tty; | ||
1080 | |||
1081 | pl011_fifo_to_tty(uap); | 1078 | pl011_fifo_to_tty(uap); |
1082 | 1079 | ||
1083 | spin_unlock(&uap->port.lock); | 1080 | spin_unlock(&uap->port.lock); |
1084 | tty_flip_buffer_push(tty); | 1081 | tty_flip_buffer_push(&uap->port.state->port); |
1085 | /* | 1082 | /* |
1086 | * If we were temporarily out of DMA mode for a while, | 1083 | * If we were temporarily out of DMA mode for a while, |
1087 | * attempt to switch back to DMA mode again. | 1084 | * attempt to switch back to DMA mode again. |
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 59ae2b53e765..6331464d9101 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c | |||
@@ -78,7 +78,6 @@ static void apbuart_enable_ms(struct uart_port *port) | |||
78 | 78 | ||
79 | static void apbuart_rx_chars(struct uart_port *port) | 79 | static void apbuart_rx_chars(struct uart_port *port) |
80 | { | 80 | { |
81 | struct tty_struct *tty = port->state->port.tty; | ||
82 | unsigned int status, ch, rsr, flag; | 81 | unsigned int status, ch, rsr, flag; |
83 | unsigned int max_chars = port->fifosize; | 82 | unsigned int max_chars = port->fifosize; |
84 | 83 | ||
@@ -126,7 +125,7 @@ static void apbuart_rx_chars(struct uart_port *port) | |||
126 | status = UART_GET_STATUS(port); | 125 | status = UART_GET_STATUS(port); |
127 | } | 126 | } |
128 | 127 | ||
129 | tty_flip_buffer_push(tty); | 128 | tty_flip_buffer_push(&port->state->port); |
130 | } | 129 | } |
131 | 130 | ||
132 | static void apbuart_tx_chars(struct uart_port *port) | 131 | static void apbuart_tx_chars(struct uart_port *port) |
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 505c490c0b44..27f20c57abed 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c | |||
@@ -297,10 +297,9 @@ static void ar933x_uart_set_termios(struct uart_port *port, | |||
297 | 297 | ||
298 | static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | 298 | static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) |
299 | { | 299 | { |
300 | struct tty_struct *tty; | 300 | struct tty_port *port = &up->port.state->port; |
301 | int max_count = 256; | 301 | int max_count = 256; |
302 | 302 | ||
303 | tty = tty_port_tty_get(&up->port.state->port); | ||
304 | do { | 303 | do { |
305 | unsigned int rdata; | 304 | unsigned int rdata; |
306 | unsigned char ch; | 305 | unsigned char ch; |
@@ -313,11 +312,6 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | |||
313 | ar933x_uart_write(up, AR933X_UART_DATA_REG, | 312 | ar933x_uart_write(up, AR933X_UART_DATA_REG, |
314 | AR933X_UART_DATA_RX_CSR); | 313 | AR933X_UART_DATA_RX_CSR); |
315 | 314 | ||
316 | if (!tty) { | ||
317 | /* discard the data if no tty available */ | ||
318 | continue; | ||
319 | } | ||
320 | |||
321 | up->port.icount.rx++; | 315 | up->port.icount.rx++; |
322 | ch = rdata & AR933X_UART_DATA_TX_RX_MASK; | 316 | ch = rdata & AR933X_UART_DATA_TX_RX_MASK; |
323 | 317 | ||
@@ -325,13 +319,10 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | |||
325 | continue; | 319 | continue; |
326 | 320 | ||
327 | if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) | 321 | if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) |
328 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 322 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
329 | } while (max_count-- > 0); | 323 | } while (max_count-- > 0); |
330 | 324 | ||
331 | if (tty) { | 325 | tty_flip_buffer_push(port); |
332 | tty_flip_buffer_push(tty); | ||
333 | tty_kref_put(tty); | ||
334 | } | ||
335 | } | 326 | } |
336 | 327 | ||
337 | static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) | 328 | static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) |
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 3e0b3fac6a0e..d97e194b6bc5 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <linux/tty_flip.h> | 37 | #include <linux/tty_flip.h> |
38 | #include <linux/serial_core.h> | 38 | #include <linux/serial_core.h> |
39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
40 | #include <linux/of.h> | ||
41 | #include <linux/of_platform.h> | ||
40 | 42 | ||
41 | /************************************* | 43 | /************************************* |
42 | * ARC UART Hardware Specs | 44 | * ARC UART Hardware Specs |
@@ -209,12 +211,8 @@ static void arc_serial_start_tx(struct uart_port *port) | |||
209 | 211 | ||
210 | static void arc_serial_rx_chars(struct arc_uart_port *uart) | 212 | static void arc_serial_rx_chars(struct arc_uart_port *uart) |
211 | { | 213 | { |
212 | struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port); | ||
213 | unsigned int status, ch, flg = 0; | 214 | unsigned int status, ch, flg = 0; |
214 | 215 | ||
215 | if (!tty) | ||
216 | return; | ||
217 | |||
218 | /* | 216 | /* |
219 | * UART has 4 deep RX-FIFO. Driver's recongnition of this fact | 217 | * UART has 4 deep RX-FIFO. Driver's recongnition of this fact |
220 | * is very subtle. Here's how ... | 218 | * is very subtle. Here's how ... |
@@ -250,10 +248,8 @@ static void arc_serial_rx_chars(struct arc_uart_port *uart) | |||
250 | uart_insert_char(&uart->port, status, RXOERR, ch, flg); | 248 | uart_insert_char(&uart->port, status, RXOERR, ch, flg); |
251 | 249 | ||
252 | done: | 250 | done: |
253 | tty_flip_buffer_push(tty); | 251 | tty_flip_buffer_push(&uart->port.state->port); |
254 | } | 252 | } |
255 | |||
256 | tty_kref_put(tty); | ||
257 | } | 253 | } |
258 | 254 | ||
259 | /* | 255 | /* |
@@ -526,18 +522,37 @@ static struct uart_ops arc_serial_pops = { | |||
526 | }; | 522 | }; |
527 | 523 | ||
528 | static int | 524 | static int |
529 | arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | 525 | arc_uart_init_one(struct platform_device *pdev, int dev_id) |
530 | { | 526 | { |
531 | struct resource *res, *res2; | 527 | struct resource *res, *res2; |
532 | unsigned long *plat_data; | 528 | unsigned long *plat_data; |
533 | 529 | struct arc_uart_port *uart = &arc_uart_ports[dev_id]; | |
534 | if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) { | ||
535 | dev_err(&pdev->dev, "Wrong uart platform device id.\n"); | ||
536 | return -ENOENT; | ||
537 | } | ||
538 | 530 | ||
539 | plat_data = ((unsigned long *)(pdev->dev.platform_data)); | 531 | plat_data = ((unsigned long *)(pdev->dev.platform_data)); |
540 | uart->baud = plat_data[0]; | 532 | if (!plat_data) |
533 | return -ENODEV; | ||
534 | |||
535 | uart->is_emulated = !!plat_data[0]; /* workaround ISS bug */ | ||
536 | |||
537 | if (is_early_platform_device(pdev)) { | ||
538 | uart->port.uartclk = plat_data[1]; | ||
539 | uart->baud = plat_data[2]; | ||
540 | } else { | ||
541 | struct device_node *np = pdev->dev.of_node; | ||
542 | u32 val; | ||
543 | |||
544 | if (of_property_read_u32(np, "clock-frequency", &val)) { | ||
545 | dev_err(&pdev->dev, "clock-frequency property NOTset\n"); | ||
546 | return -EINVAL; | ||
547 | } | ||
548 | uart->port.uartclk = val; | ||
549 | |||
550 | if (of_property_read_u32(np, "current-speed", &val)) { | ||
551 | dev_err(&pdev->dev, "current-speed property NOT set\n"); | ||
552 | return -EINVAL; | ||
553 | } | ||
554 | uart->baud = val; | ||
555 | } | ||
541 | 556 | ||
542 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 557 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
543 | if (!res) | 558 | if (!res) |
@@ -557,10 +572,9 @@ arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | |||
557 | uart->port.dev = &pdev->dev; | 572 | uart->port.dev = &pdev->dev; |
558 | uart->port.iotype = UPIO_MEM; | 573 | uart->port.iotype = UPIO_MEM; |
559 | uart->port.flags = UPF_BOOT_AUTOCONF; | 574 | uart->port.flags = UPF_BOOT_AUTOCONF; |
560 | uart->port.line = pdev->id; | 575 | uart->port.line = dev_id; |
561 | uart->port.ops = &arc_serial_pops; | 576 | uart->port.ops = &arc_serial_pops; |
562 | 577 | ||
563 | uart->port.uartclk = plat_data[1]; | ||
564 | uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; | 578 | uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; |
565 | 579 | ||
566 | /* | 580 | /* |
@@ -569,9 +583,6 @@ arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | |||
569 | */ | 583 | */ |
570 | uart->port.ignore_status_mask = 0; | 584 | uart->port.ignore_status_mask = 0; |
571 | 585 | ||
572 | /* Real Hardware vs. emulated to work around a bug */ | ||
573 | uart->is_emulated = !!plat_data[2]; | ||
574 | |||
575 | return 0; | 586 | return 0; |
576 | } | 587 | } |
577 | 588 | ||
@@ -648,45 +659,50 @@ static __init void early_serial_write(struct console *con, const char *s, | |||
648 | } | 659 | } |
649 | } | 660 | } |
650 | 661 | ||
651 | static struct __initdata console arc_early_serial_console = { | 662 | static struct console arc_early_serial_console __initdata = { |
652 | .name = "early_ARCuart", | 663 | .name = "early_ARCuart", |
653 | .write = early_serial_write, | 664 | .write = early_serial_write, |
654 | .flags = CON_PRINTBUFFER | CON_BOOT, | 665 | .flags = CON_PRINTBUFFER | CON_BOOT, |
655 | .index = -1 | 666 | .index = -1 |
656 | }; | 667 | }; |
657 | 668 | ||
658 | static int arc_serial_probe_earlyprintk(struct platform_device *pdev) | 669 | static int __init arc_serial_probe_earlyprintk(struct platform_device *pdev) |
659 | { | 670 | { |
660 | arc_early_serial_console.index = pdev->id; | 671 | int dev_id = pdev->id < 0 ? 0 : pdev->id; |
672 | int rc; | ||
673 | |||
674 | arc_early_serial_console.index = dev_id; | ||
661 | 675 | ||
662 | arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]); | 676 | rc = arc_uart_init_one(pdev, dev_id); |
677 | if (rc) | ||
678 | panic("early console init failed\n"); | ||
663 | 679 | ||
664 | arc_serial_console_setup(&arc_early_serial_console, NULL); | 680 | arc_serial_console_setup(&arc_early_serial_console, NULL); |
665 | 681 | ||
666 | register_console(&arc_early_serial_console); | 682 | register_console(&arc_early_serial_console); |
667 | return 0; | 683 | return 0; |
668 | } | 684 | } |
669 | #else | ||
670 | static int arc_serial_probe_earlyprintk(struct platform_device *pdev) | ||
671 | { | ||
672 | return -ENODEV; | ||
673 | } | ||
674 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | 685 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ |
675 | 686 | ||
676 | static int arc_serial_probe(struct platform_device *pdev) | 687 | static int arc_serial_probe(struct platform_device *pdev) |
677 | { | 688 | { |
678 | struct arc_uart_port *uart; | 689 | int rc, dev_id; |
679 | int rc; | 690 | struct device_node *np = pdev->dev.of_node; |
691 | |||
692 | /* no device tree device */ | ||
693 | if (!np) | ||
694 | return -ENODEV; | ||
680 | 695 | ||
681 | if (is_early_platform_device(pdev)) | 696 | dev_id = of_alias_get_id(np, "serial"); |
682 | return arc_serial_probe_earlyprintk(pdev); | 697 | if (dev_id < 0) |
698 | dev_id = 0; | ||
683 | 699 | ||
684 | uart = &arc_uart_ports[pdev->id]; | 700 | rc = arc_uart_init_one(pdev, dev_id); |
685 | rc = arc_uart_init_one(pdev, uart); | ||
686 | if (rc) | 701 | if (rc) |
687 | return rc; | 702 | return rc; |
688 | 703 | ||
689 | return uart_add_one_port(&arc_uart_driver, &uart->port); | 704 | rc = uart_add_one_port(&arc_uart_driver, &arc_uart_ports[dev_id].port); |
705 | return rc; | ||
690 | } | 706 | } |
691 | 707 | ||
692 | static int arc_serial_remove(struct platform_device *pdev) | 708 | static int arc_serial_remove(struct platform_device *pdev) |
@@ -695,16 +711,32 @@ static int arc_serial_remove(struct platform_device *pdev) | |||
695 | return 0; | 711 | return 0; |
696 | } | 712 | } |
697 | 713 | ||
714 | static const struct of_device_id arc_uart_dt_ids[] = { | ||
715 | { .compatible = "snps,arc-uart" }, | ||
716 | { /* Sentinel */ } | ||
717 | }; | ||
718 | MODULE_DEVICE_TABLE(of, arc_uart_dt_ids); | ||
719 | |||
698 | static struct platform_driver arc_platform_driver = { | 720 | static struct platform_driver arc_platform_driver = { |
699 | .probe = arc_serial_probe, | 721 | .probe = arc_serial_probe, |
700 | .remove = arc_serial_remove, | 722 | .remove = arc_serial_remove, |
701 | .driver = { | 723 | .driver = { |
702 | .name = DRIVER_NAME, | 724 | .name = DRIVER_NAME, |
703 | .owner = THIS_MODULE, | 725 | .owner = THIS_MODULE, |
726 | .of_match_table = arc_uart_dt_ids, | ||
704 | }, | 727 | }, |
705 | }; | 728 | }; |
706 | 729 | ||
707 | #ifdef CONFIG_SERIAL_ARC_CONSOLE | 730 | #ifdef CONFIG_SERIAL_ARC_CONSOLE |
731 | |||
732 | static struct platform_driver early_arc_platform_driver __initdata = { | ||
733 | .probe = arc_serial_probe_earlyprintk, | ||
734 | .remove = arc_serial_remove, | ||
735 | .driver = { | ||
736 | .name = DRIVER_NAME, | ||
737 | .owner = THIS_MODULE, | ||
738 | }, | ||
739 | }; | ||
708 | /* | 740 | /* |
709 | * Register an early platform driver of "earlyprintk" class. | 741 | * Register an early platform driver of "earlyprintk" class. |
710 | * ARCH platform code installs the driver and probes the early devices | 742 | * ARCH platform code installs the driver and probes the early devices |
@@ -712,7 +744,7 @@ static struct platform_driver arc_platform_driver = { | |||
712 | * or it could be done independently, for all "earlyprintk" class drivers. | 744 | * or it could be done independently, for all "earlyprintk" class drivers. |
713 | * [see arch/arc/plat-arcfpga/platform.c] | 745 | * [see arch/arc/plat-arcfpga/platform.c] |
714 | */ | 746 | */ |
715 | early_platform_init("earlyprintk", &arc_platform_driver); | 747 | early_platform_init("earlyprintk", &early_arc_platform_driver); |
716 | 748 | ||
717 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | 749 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ |
718 | 750 | ||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 922e85aeb63a..d4a7c241b751 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -774,14 +774,14 @@ static void atmel_rx_from_ring(struct uart_port *port) | |||
774 | * uart_start(), which takes the lock. | 774 | * uart_start(), which takes the lock. |
775 | */ | 775 | */ |
776 | spin_unlock(&port->lock); | 776 | spin_unlock(&port->lock); |
777 | tty_flip_buffer_push(port->state->port.tty); | 777 | tty_flip_buffer_push(&port->state->port); |
778 | spin_lock(&port->lock); | 778 | spin_lock(&port->lock); |
779 | } | 779 | } |
780 | 780 | ||
781 | static void atmel_rx_from_dma(struct uart_port *port) | 781 | static void atmel_rx_from_dma(struct uart_port *port) |
782 | { | 782 | { |
783 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 783 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
784 | struct tty_struct *tty = port->state->port.tty; | 784 | struct tty_port *tport = &port->state->port; |
785 | struct atmel_dma_buffer *pdc; | 785 | struct atmel_dma_buffer *pdc; |
786 | int rx_idx = atmel_port->pdc_rx_idx; | 786 | int rx_idx = atmel_port->pdc_rx_idx; |
787 | unsigned int head; | 787 | unsigned int head; |
@@ -820,7 +820,8 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
820 | */ | 820 | */ |
821 | count = head - tail; | 821 | count = head - tail; |
822 | 822 | ||
823 | tty_insert_flip_string(tty, pdc->buf + pdc->ofs, count); | 823 | tty_insert_flip_string(tport, pdc->buf + pdc->ofs, |
824 | count); | ||
824 | 825 | ||
825 | dma_sync_single_for_device(port->dev, pdc->dma_addr, | 826 | dma_sync_single_for_device(port->dev, pdc->dma_addr, |
826 | pdc->dma_size, DMA_FROM_DEVICE); | 827 | pdc->dma_size, DMA_FROM_DEVICE); |
@@ -848,7 +849,7 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
848 | * uart_start(), which takes the lock. | 849 | * uart_start(), which takes the lock. |
849 | */ | 850 | */ |
850 | spin_unlock(&port->lock); | 851 | spin_unlock(&port->lock); |
851 | tty_flip_buffer_push(tty); | 852 | tty_flip_buffer_push(tport); |
852 | spin_lock(&port->lock); | 853 | spin_lock(&port->lock); |
853 | 854 | ||
854 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); | 855 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); |
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index c76a226080f2..719594e5fc21 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c | |||
@@ -235,14 +235,13 @@ static const char *bcm_uart_type(struct uart_port *port) | |||
235 | */ | 235 | */ |
236 | static void bcm_uart_do_rx(struct uart_port *port) | 236 | static void bcm_uart_do_rx(struct uart_port *port) |
237 | { | 237 | { |
238 | struct tty_struct *tty; | 238 | struct tty_port *port = &port->state->port; |
239 | unsigned int max_count; | 239 | unsigned int max_count; |
240 | 240 | ||
241 | /* limit number of char read in interrupt, should not be | 241 | /* limit number of char read in interrupt, should not be |
242 | * higher than fifo size anyway since we're much faster than | 242 | * higher than fifo size anyway since we're much faster than |
243 | * serial port */ | 243 | * serial port */ |
244 | max_count = 32; | 244 | max_count = 32; |
245 | tty = port->state->port.tty; | ||
246 | do { | 245 | do { |
247 | unsigned int iestat, c, cstat; | 246 | unsigned int iestat, c, cstat; |
248 | char flag; | 247 | char flag; |
@@ -261,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port) | |||
261 | bcm_uart_writel(port, val, UART_CTL_REG); | 260 | bcm_uart_writel(port, val, UART_CTL_REG); |
262 | 261 | ||
263 | port->icount.overrun++; | 262 | port->icount.overrun++; |
264 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 263 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
265 | } | 264 | } |
266 | 265 | ||
267 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) | 266 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) |
@@ -300,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port) | |||
300 | 299 | ||
301 | 300 | ||
302 | if ((cstat & port->ignore_status_mask) == 0) | 301 | if ((cstat & port->ignore_status_mask) == 0) |
303 | tty_insert_flip_char(tty, c, flag); | 302 | tty_insert_flip_char(port, c, flag); |
304 | 303 | ||
305 | } while (--max_count); | 304 | } while (--max_count); |
306 | 305 | ||
307 | tty_flip_buffer_push(tty); | 306 | tty_flip_buffer_push(port); |
308 | } | 307 | } |
309 | 308 | ||
310 | /* | 309 | /* |
diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index f5d117379b60..487c173b0f72 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c | |||
@@ -149,7 +149,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate) | |||
149 | static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | 149 | static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) |
150 | { | 150 | { |
151 | struct sport_uart_port *up = dev_id; | 151 | struct sport_uart_port *up = dev_id; |
152 | struct tty_struct *tty = up->port.state->port.tty; | 152 | struct tty_port *port = &up->port.state->port; |
153 | unsigned int ch; | 153 | unsigned int ch; |
154 | 154 | ||
155 | spin_lock(&up->port.lock); | 155 | spin_lock(&up->port.lock); |
@@ -159,9 +159,10 @@ static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | |||
159 | up->port.icount.rx++; | 159 | up->port.icount.rx++; |
160 | 160 | ||
161 | if (!uart_handle_sysrq_char(&up->port, ch)) | 161 | if (!uart_handle_sysrq_char(&up->port, ch)) |
162 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 162 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
163 | } | 163 | } |
164 | tty_flip_buffer_push(tty); | 164 | /* XXX this won't deadlock with lowlat? */ |
165 | tty_flip_buffer_push(port); | ||
165 | 166 | ||
166 | spin_unlock(&up->port.lock); | 167 | spin_unlock(&up->port.lock); |
167 | 168 | ||
@@ -182,7 +183,6 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) | |||
182 | static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | 183 | static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) |
183 | { | 184 | { |
184 | struct sport_uart_port *up = dev_id; | 185 | struct sport_uart_port *up = dev_id; |
185 | struct tty_struct *tty = up->port.state->port.tty; | ||
186 | unsigned int stat = SPORT_GET_STAT(up); | 186 | unsigned int stat = SPORT_GET_STAT(up); |
187 | 187 | ||
188 | spin_lock(&up->port.lock); | 188 | spin_lock(&up->port.lock); |
@@ -190,7 +190,7 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
190 | /* Overflow in RX FIFO */ | 190 | /* Overflow in RX FIFO */ |
191 | if (stat & ROVF) { | 191 | if (stat & ROVF) { |
192 | up->port.icount.overrun++; | 192 | up->port.icount.overrun++; |
193 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 193 | tty_insert_flip_char(&up->port.state->port, 0, TTY_OVERRUN); |
194 | SPORT_PUT_STAT(up, ROVF); /* Clear ROVF bit */ | 194 | SPORT_PUT_STAT(up, ROVF); /* Clear ROVF bit */ |
195 | } | 195 | } |
196 | /* These should not happen */ | 196 | /* These should not happen */ |
@@ -205,6 +205,8 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
205 | SSYNC(); | 205 | SSYNC(); |
206 | 206 | ||
207 | spin_unlock(&up->port.lock); | 207 | spin_unlock(&up->port.lock); |
208 | /* XXX we don't push the overrun bit to TTY? */ | ||
209 | |||
208 | return IRQ_HANDLED; | 210 | return IRQ_HANDLED; |
209 | } | 211 | } |
210 | 212 | ||
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 2e2b2c1cb722..12dceda9db33 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -223,7 +223,6 @@ static void bfin_serial_enable_ms(struct uart_port *port) | |||
223 | #ifdef CONFIG_SERIAL_BFIN_PIO | 223 | #ifdef CONFIG_SERIAL_BFIN_PIO |
224 | static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | 224 | static void bfin_serial_rx_chars(struct bfin_serial_port *uart) |
225 | { | 225 | { |
226 | struct tty_struct *tty = NULL; | ||
227 | unsigned int status, ch, flg; | 226 | unsigned int status, ch, flg; |
228 | static struct timeval anomaly_start = { .tv_sec = 0 }; | 227 | static struct timeval anomaly_start = { .tv_sec = 0 }; |
229 | 228 | ||
@@ -242,11 +241,9 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
242 | return; | 241 | return; |
243 | } | 242 | } |
244 | 243 | ||
245 | if (!uart->port.state || !uart->port.state->port.tty) | 244 | if (!uart->port.state) |
246 | return; | 245 | return; |
247 | #endif | 246 | #endif |
248 | tty = uart->port.state->port.tty; | ||
249 | |||
250 | if (ANOMALY_05000363) { | 247 | if (ANOMALY_05000363) { |
251 | /* The BF533 (and BF561) family of processors have a nice anomaly | 248 | /* The BF533 (and BF561) family of processors have a nice anomaly |
252 | * where they continuously generate characters for a "single" break. | 249 | * where they continuously generate characters for a "single" break. |
@@ -325,7 +322,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
325 | uart_insert_char(&uart->port, status, OE, ch, flg); | 322 | uart_insert_char(&uart->port, status, OE, ch, flg); |
326 | 323 | ||
327 | ignore_char: | 324 | ignore_char: |
328 | tty_flip_buffer_push(tty); | 325 | tty_flip_buffer_push(&uart->port.state->port); |
329 | } | 326 | } |
330 | 327 | ||
331 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | 328 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) |
@@ -426,7 +423,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
426 | 423 | ||
427 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | 424 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) |
428 | { | 425 | { |
429 | struct tty_struct *tty = uart->port.state->port.tty; | ||
430 | int i, flg, status; | 426 | int i, flg, status; |
431 | 427 | ||
432 | status = UART_GET_LSR(uart); | 428 | status = UART_GET_LSR(uart); |
@@ -471,7 +467,7 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | |||
471 | } | 467 | } |
472 | 468 | ||
473 | dma_ignore_char: | 469 | dma_ignore_char: |
474 | tty_flip_buffer_push(tty); | 470 | tty_flip_buffer_push(&uart->port.state->port); |
475 | } | 471 | } |
476 | 472 | ||
477 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | 473 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) |
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 3fd2526d121e..bfb17968c8db 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -85,12 +85,8 @@ static void uart_clps711x_enable_ms(struct uart_port *port) | |||
85 | static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) | 85 | static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) |
86 | { | 86 | { |
87 | struct uart_port *port = dev_id; | 87 | struct uart_port *port = dev_id; |
88 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
89 | unsigned int status, ch, flg; | 88 | unsigned int status, ch, flg; |
90 | 89 | ||
91 | if (!tty) | ||
92 | return IRQ_HANDLED; | ||
93 | |||
94 | for (;;) { | 90 | for (;;) { |
95 | status = clps_readl(SYSFLG(port)); | 91 | status = clps_readl(SYSFLG(port)); |
96 | if (status & SYSFLG_URXFE) | 92 | if (status & SYSFLG_URXFE) |
@@ -130,9 +126,7 @@ static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) | |||
130 | uart_insert_char(port, status, UARTDR_OVERR, ch, flg); | 126 | uart_insert_char(port, status, UARTDR_OVERR, ch, flg); |
131 | } | 127 | } |
132 | 128 | ||
133 | tty_flip_buffer_push(tty); | 129 | tty_flip_buffer_push(&port->state->port); |
134 | |||
135 | tty_kref_put(tty); | ||
136 | 130 | ||
137 | return IRQ_HANDLED; | 131 | return IRQ_HANDLED; |
138 | } | 132 | } |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index ad0caf176808..97f4e1858649 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c | |||
@@ -245,7 +245,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
245 | int i; | 245 | int i; |
246 | unsigned char ch; | 246 | unsigned char ch; |
247 | u8 *cp; | 247 | u8 *cp; |
248 | struct tty_struct *tty = port->state->port.tty; | 248 | struct tty_port *tport = &port->state->port; |
249 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 249 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
250 | cbd_t __iomem *bdp; | 250 | cbd_t __iomem *bdp; |
251 | u16 status; | 251 | u16 status; |
@@ -276,7 +276,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
276 | /* If we have not enough room in tty flip buffer, then we try | 276 | /* If we have not enough room in tty flip buffer, then we try |
277 | * later, which will be the next rx-interrupt or a timeout | 277 | * later, which will be the next rx-interrupt or a timeout |
278 | */ | 278 | */ |
279 | if(tty_buffer_request_room(tty, i) < i) { | 279 | if (tty_buffer_request_room(tport, i) < i) { |
280 | printk(KERN_WARNING "No room in flip buffer\n"); | 280 | printk(KERN_WARNING "No room in flip buffer\n"); |
281 | return; | 281 | return; |
282 | } | 282 | } |
@@ -302,7 +302,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
302 | } | 302 | } |
303 | #endif | 303 | #endif |
304 | error_return: | 304 | error_return: |
305 | tty_insert_flip_char(tty, ch, flg); | 305 | tty_insert_flip_char(tport, ch, flg); |
306 | 306 | ||
307 | } /* End while (i--) */ | 307 | } /* End while (i--) */ |
308 | 308 | ||
@@ -322,7 +322,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
322 | pinfo->rx_cur = bdp; | 322 | pinfo->rx_cur = bdp; |
323 | 323 | ||
324 | /* activate BH processing */ | 324 | /* activate BH processing */ |
325 | tty_flip_buffer_push(tty); | 325 | tty_flip_buffer_push(tport); |
326 | 326 | ||
327 | return; | 327 | return; |
328 | 328 | ||
@@ -507,7 +507,7 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
507 | 507 | ||
508 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | 508 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); |
509 | if (baud < HW_BUF_SPD_THRESHOLD || | 509 | if (baud < HW_BUF_SPD_THRESHOLD || |
510 | (pinfo->port.state && pinfo->port.state->port.tty->low_latency)) | 510 | (pinfo->port.state && pinfo->port.state->port.low_latency)) |
511 | pinfo->rx_fifosize = 1; | 511 | pinfo->rx_fifosize = 1; |
512 | else | 512 | else |
513 | pinfo->rx_fifosize = RX_BUF_SIZE; | 513 | pinfo->rx_fifosize = RX_BUF_SIZE; |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 35ee6a2c6877..5f37c31e32bc 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -1760,8 +1760,7 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl | |||
1760 | 1760 | ||
1761 | info->icount.rx++; | 1761 | info->icount.rx++; |
1762 | } else { | 1762 | } else { |
1763 | struct tty_struct *tty = info->port.tty; | 1763 | tty_insert_flip_char(&info->port, data, flag); |
1764 | tty_insert_flip_char(tty, data, flag); | ||
1765 | info->icount.rx++; | 1764 | info->icount.rx++; |
1766 | } | 1765 | } |
1767 | 1766 | ||
@@ -2105,22 +2104,15 @@ static int force_eop_if_needed(struct e100_serial *info) | |||
2105 | 2104 | ||
2106 | static void flush_to_flip_buffer(struct e100_serial *info) | 2105 | static void flush_to_flip_buffer(struct e100_serial *info) |
2107 | { | 2106 | { |
2108 | struct tty_struct *tty; | ||
2109 | struct etrax_recv_buffer *buffer; | 2107 | struct etrax_recv_buffer *buffer; |
2110 | unsigned long flags; | 2108 | unsigned long flags; |
2111 | 2109 | ||
2112 | local_irq_save(flags); | 2110 | local_irq_save(flags); |
2113 | tty = info->port.tty; | ||
2114 | |||
2115 | if (!tty) { | ||
2116 | local_irq_restore(flags); | ||
2117 | return; | ||
2118 | } | ||
2119 | 2111 | ||
2120 | while ((buffer = info->first_recv_buffer) != NULL) { | 2112 | while ((buffer = info->first_recv_buffer) != NULL) { |
2121 | unsigned int count = buffer->length; | 2113 | unsigned int count = buffer->length; |
2122 | 2114 | ||
2123 | tty_insert_flip_string(tty, buffer->buffer, count); | 2115 | tty_insert_flip_string(&info->port, buffer->buffer, count); |
2124 | info->recv_cnt -= count; | 2116 | info->recv_cnt -= count; |
2125 | 2117 | ||
2126 | if (count == buffer->length) { | 2118 | if (count == buffer->length) { |
@@ -2139,7 +2131,7 @@ static void flush_to_flip_buffer(struct e100_serial *info) | |||
2139 | local_irq_restore(flags); | 2131 | local_irq_restore(flags); |
2140 | 2132 | ||
2141 | /* This includes a check for low-latency */ | 2133 | /* This includes a check for low-latency */ |
2142 | tty_flip_buffer_push(tty); | 2134 | tty_flip_buffer_push(&info->port); |
2143 | } | 2135 | } |
2144 | 2136 | ||
2145 | static void check_flush_timeout(struct e100_serial *info) | 2137 | static void check_flush_timeout(struct e100_serial *info) |
@@ -2275,12 +2267,6 @@ static | |||
2275 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) | 2267 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) |
2276 | { | 2268 | { |
2277 | unsigned long data_read; | 2269 | unsigned long data_read; |
2278 | struct tty_struct *tty = info->port.tty; | ||
2279 | |||
2280 | if (!tty) { | ||
2281 | printk("!NO TTY!\n"); | ||
2282 | return info; | ||
2283 | } | ||
2284 | 2270 | ||
2285 | /* Read data and status at the same time */ | 2271 | /* Read data and status at the same time */ |
2286 | data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); | 2272 | data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); |
@@ -2338,8 +2324,7 @@ more_data: | |||
2338 | data_in, data_read); | 2324 | data_in, data_read); |
2339 | char flag = TTY_NORMAL; | 2325 | char flag = TTY_NORMAL; |
2340 | if (info->errorcode == ERRCODE_INSERT_BREAK) { | 2326 | if (info->errorcode == ERRCODE_INSERT_BREAK) { |
2341 | struct tty_struct *tty = info->port.tty; | 2327 | tty_insert_flip_char(&info->port, 0, flag); |
2342 | tty_insert_flip_char(tty, 0, flag); | ||
2343 | info->icount.rx++; | 2328 | info->icount.rx++; |
2344 | } | 2329 | } |
2345 | 2330 | ||
@@ -2353,7 +2338,7 @@ more_data: | |||
2353 | info->icount.frame++; | 2338 | info->icount.frame++; |
2354 | flag = TTY_FRAME; | 2339 | flag = TTY_FRAME; |
2355 | } | 2340 | } |
2356 | tty_insert_flip_char(tty, data, flag); | 2341 | tty_insert_flip_char(&info->port, data, flag); |
2357 | info->errorcode = 0; | 2342 | info->errorcode = 0; |
2358 | } | 2343 | } |
2359 | info->break_detected_cnt = 0; | 2344 | info->break_detected_cnt = 0; |
@@ -2369,7 +2354,7 @@ more_data: | |||
2369 | log_int(rdpc(), 0, 0); | 2354 | log_int(rdpc(), 0, 0); |
2370 | } | 2355 | } |
2371 | ); | 2356 | ); |
2372 | tty_insert_flip_char(tty, | 2357 | tty_insert_flip_char(&info->port, |
2373 | IO_EXTRACT(R_SERIAL0_READ, data_in, data_read), | 2358 | IO_EXTRACT(R_SERIAL0_READ, data_in, data_read), |
2374 | TTY_NORMAL); | 2359 | TTY_NORMAL); |
2375 | } else { | 2360 | } else { |
@@ -2384,7 +2369,7 @@ more_data: | |||
2384 | goto more_data; | 2369 | goto more_data; |
2385 | } | 2370 | } |
2386 | 2371 | ||
2387 | tty_flip_buffer_push(info->port.tty); | 2372 | tty_flip_buffer_push(&info->port); |
2388 | return info; | 2373 | return info; |
2389 | } | 2374 | } |
2390 | 2375 | ||
@@ -3137,7 +3122,7 @@ static int rs_raw_write(struct tty_struct *tty, | |||
3137 | 3122 | ||
3138 | /* first some sanity checks */ | 3123 | /* first some sanity checks */ |
3139 | 3124 | ||
3140 | if (!tty || !info->xmit.buf) | 3125 | if (!info->xmit.buf) |
3141 | return 0; | 3126 | return 0; |
3142 | 3127 | ||
3143 | #ifdef SERIAL_DEBUG_DATA | 3128 | #ifdef SERIAL_DEBUG_DATA |
@@ -3464,7 +3449,7 @@ set_serial_info(struct e100_serial *info, | |||
3464 | info->type = new_serial.type; | 3449 | info->type = new_serial.type; |
3465 | info->close_delay = new_serial.close_delay; | 3450 | info->close_delay = new_serial.close_delay; |
3466 | info->closing_wait = new_serial.closing_wait; | 3451 | info->closing_wait = new_serial.closing_wait; |
3467 | info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 3452 | info->port.low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
3468 | 3453 | ||
3469 | check_and_exit: | 3454 | check_and_exit: |
3470 | if (info->flags & ASYNC_INITIALIZED) { | 3455 | if (info->flags & ASYNC_INITIALIZED) { |
@@ -4108,7 +4093,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4108 | tty->driver_data = info; | 4093 | tty->driver_data = info; |
4109 | info->port.tty = tty; | 4094 | info->port.tty = tty; |
4110 | 4095 | ||
4111 | tty->low_latency = !!(info->flags & ASYNC_LOW_LATENCY); | 4096 | info->port.low_latency = !!(info->flags & ASYNC_LOW_LATENCY); |
4112 | 4097 | ||
4113 | /* | 4098 | /* |
4114 | * If the port is in the middle of closing, bail out now | 4099 | * If the port is in the middle of closing, bail out now |
diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 6491b8644a7f..2f2b2e538a54 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c | |||
@@ -187,7 +187,6 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
187 | { | 187 | { |
188 | struct uart_port *uport; | 188 | struct uart_port *uport; |
189 | struct dz_port *dport = &mux->dport[0]; | 189 | struct dz_port *dport = &mux->dport[0]; |
190 | struct tty_struct *tty = NULL; | ||
191 | struct uart_icount *icount; | 190 | struct uart_icount *icount; |
192 | int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; | 191 | int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; |
193 | unsigned char ch, flag; | 192 | unsigned char ch, flag; |
@@ -197,7 +196,6 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
197 | while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { | 196 | while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { |
198 | dport = &mux->dport[LINE(status)]; | 197 | dport = &mux->dport[LINE(status)]; |
199 | uport = &dport->port; | 198 | uport = &dport->port; |
200 | tty = uport->state->port.tty; /* point to the proper dev */ | ||
201 | 199 | ||
202 | ch = UCHAR(status); /* grab the char */ | 200 | ch = UCHAR(status); /* grab the char */ |
203 | flag = TTY_NORMAL; | 201 | flag = TTY_NORMAL; |
@@ -249,7 +247,7 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
249 | } | 247 | } |
250 | for (i = 0; i < DZ_NB_PORT; i++) | 248 | for (i = 0; i < DZ_NB_PORT; i++) |
251 | if (lines_rx[i]) | 249 | if (lines_rx[i]) |
252 | tty_flip_buffer_push(mux->dport[i].port.state->port.tty); | 250 | tty_flip_buffer_push(&mux->dport[i].port.state->port); |
253 | } | 251 | } |
254 | 252 | ||
255 | /* | 253 | /* |
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index a8cbb2670521..7d199c8e1a75 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c | |||
@@ -81,6 +81,7 @@ struct efm32_uart_port { | |||
81 | struct uart_port port; | 81 | struct uart_port port; |
82 | unsigned int txirq; | 82 | unsigned int txirq; |
83 | struct clk *clk; | 83 | struct clk *clk; |
84 | struct efm32_uart_pdata pdata; | ||
84 | }; | 85 | }; |
85 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) | 86 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) |
86 | #define efm_debug(efm_port, format, arg...) \ | 87 | #define efm_debug(efm_port, format, arg...) \ |
@@ -194,8 +195,7 @@ static void efm32_uart_break_ctl(struct uart_port *port, int ctl) | |||
194 | /* not possible without fiddling with gpios */ | 195 | /* not possible without fiddling with gpios */ |
195 | } | 196 | } |
196 | 197 | ||
197 | static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, | 198 | static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port) |
198 | struct tty_struct *tty) | ||
199 | { | 199 | { |
200 | struct uart_port *port = &efm_port->port; | 200 | struct uart_port *port = &efm_port->port; |
201 | 201 | ||
@@ -237,8 +237,8 @@ static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, | |||
237 | rxdata & UARTn_RXDATAX_RXDATA__MASK)) | 237 | rxdata & UARTn_RXDATAX_RXDATA__MASK)) |
238 | continue; | 238 | continue; |
239 | 239 | ||
240 | if (tty && (rxdata & port->ignore_status_mask) == 0) | 240 | if ((rxdata & port->ignore_status_mask) == 0) |
241 | tty_insert_flip_char(tty, | 241 | tty_insert_flip_char(&port->state->port, |
242 | rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); | 242 | rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); |
243 | } | 243 | } |
244 | } | 244 | } |
@@ -249,15 +249,13 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) | |||
249 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); | 249 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); |
250 | int handled = IRQ_NONE; | 250 | int handled = IRQ_NONE; |
251 | struct uart_port *port = &efm_port->port; | 251 | struct uart_port *port = &efm_port->port; |
252 | struct tty_struct *tty; | 252 | struct tty_port *tport = &port->state->port; |
253 | 253 | ||
254 | spin_lock(&port->lock); | 254 | spin_lock(&port->lock); |
255 | 255 | ||
256 | tty = tty_kref_get(port->state->port.tty); | ||
257 | |||
258 | if (irqflag & UARTn_IF_RXDATAV) { | 256 | if (irqflag & UARTn_IF_RXDATAV) { |
259 | efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); | 257 | efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); |
260 | efm32_uart_rx_chars(efm_port, tty); | 258 | efm32_uart_rx_chars(efm_port); |
261 | 259 | ||
262 | handled = IRQ_HANDLED; | 260 | handled = IRQ_HANDLED; |
263 | } | 261 | } |
@@ -265,16 +263,12 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) | |||
265 | if (irqflag & UARTn_IF_RXOF) { | 263 | if (irqflag & UARTn_IF_RXOF) { |
266 | efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); | 264 | efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); |
267 | port->icount.overrun++; | 265 | port->icount.overrun++; |
268 | if (tty) | 266 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
269 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
270 | 267 | ||
271 | handled = IRQ_HANDLED; | 268 | handled = IRQ_HANDLED; |
272 | } | 269 | } |
273 | 270 | ||
274 | if (tty) { | 271 | tty_flip_buffer_push(tport); |
275 | tty_flip_buffer_push(tty); | ||
276 | tty_kref_put(tty); | ||
277 | } | ||
278 | 272 | ||
279 | spin_unlock(&port->lock); | 273 | spin_unlock(&port->lock); |
280 | 274 | ||
@@ -300,13 +294,8 @@ static irqreturn_t efm32_uart_txirq(int irq, void *data) | |||
300 | static int efm32_uart_startup(struct uart_port *port) | 294 | static int efm32_uart_startup(struct uart_port *port) |
301 | { | 295 | { |
302 | struct efm32_uart_port *efm_port = to_efm_port(port); | 296 | struct efm32_uart_port *efm_port = to_efm_port(port); |
303 | u32 location = 0; | ||
304 | struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); | ||
305 | int ret; | 297 | int ret; |
306 | 298 | ||
307 | if (pdata) | ||
308 | location = UARTn_ROUTE_LOCATION(pdata->location); | ||
309 | |||
310 | ret = clk_enable(efm_port->clk); | 299 | ret = clk_enable(efm_port->clk); |
311 | if (ret) { | 300 | if (ret) { |
312 | efm_debug(efm_port, "failed to enable clk\n"); | 301 | efm_debug(efm_port, "failed to enable clk\n"); |
@@ -315,7 +304,9 @@ static int efm32_uart_startup(struct uart_port *port) | |||
315 | port->uartclk = clk_get_rate(efm_port->clk); | 304 | port->uartclk = clk_get_rate(efm_port->clk); |
316 | 305 | ||
317 | /* Enable pins at configured location */ | 306 | /* Enable pins at configured location */ |
318 | efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | 307 | efm32_uart_write32(efm_port, |
308 | UARTn_ROUTE_LOCATION(efm_port->pdata.location) | | ||
309 | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | ||
319 | UARTn_ROUTE); | 310 | UARTn_ROUTE); |
320 | 311 | ||
321 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, | 312 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, |
@@ -674,11 +665,24 @@ static int efm32_uart_probe_dt(struct platform_device *pdev, | |||
674 | struct efm32_uart_port *efm_port) | 665 | struct efm32_uart_port *efm_port) |
675 | { | 666 | { |
676 | struct device_node *np = pdev->dev.of_node; | 667 | struct device_node *np = pdev->dev.of_node; |
668 | u32 location; | ||
677 | int ret; | 669 | int ret; |
678 | 670 | ||
679 | if (!np) | 671 | if (!np) |
680 | return 1; | 672 | return 1; |
681 | 673 | ||
674 | ret = of_property_read_u32(np, "location", &location); | ||
675 | if (!ret) { | ||
676 | if (location > 5) { | ||
677 | dev_err(&pdev->dev, "invalid location\n"); | ||
678 | return -EINVAL; | ||
679 | } | ||
680 | efm_debug(efm_port, "using location %u\n", location); | ||
681 | efm_port->pdata.location = location; | ||
682 | } else { | ||
683 | efm_debug(efm_port, "fall back to location 0\n"); | ||
684 | } | ||
685 | |||
682 | ret = of_alias_get_id(np, "serial"); | 686 | ret = of_alias_get_id(np, "serial"); |
683 | if (ret < 0) { | 687 | if (ret < 0) { |
684 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); | 688 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); |
@@ -738,10 +742,16 @@ static int efm32_uart_probe(struct platform_device *pdev) | |||
738 | efm_port->port.flags = UPF_BOOT_AUTOCONF; | 742 | efm_port->port.flags = UPF_BOOT_AUTOCONF; |
739 | 743 | ||
740 | ret = efm32_uart_probe_dt(pdev, efm_port); | 744 | ret = efm32_uart_probe_dt(pdev, efm_port); |
741 | if (ret > 0) | 745 | if (ret > 0) { |
742 | /* not created by device tree */ | 746 | /* not created by device tree */ |
747 | const struct efm32_uart_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
748 | |||
743 | efm_port->port.line = pdev->id; | 749 | efm_port->port.line = pdev->id; |
744 | 750 | ||
751 | if (pdata) | ||
752 | efm_port->pdata = *pdata; | ||
753 | } | ||
754 | |||
745 | if (efm_port->port.line >= 0 && | 755 | if (efm_port->port.line >= 0 && |
746 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) | 756 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) |
747 | efm32_uart_ports[efm_port->port.line] = efm_port; | 757 | efm32_uart_ports[efm_port->port.line] = efm_port; |
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 72b6334bcf1a..bc9e6b017b05 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c | |||
@@ -734,7 +734,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
734 | static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | 734 | static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) |
735 | { | 735 | { |
736 | short int count, rcv_buff; | 736 | short int count, rcv_buff; |
737 | struct tty_struct *tty = icom_port->uart_port.state->port.tty; | 737 | struct tty_port *port = &icom_port->uart_port.state->port; |
738 | unsigned short int status; | 738 | unsigned short int status; |
739 | struct uart_icount *icount; | 739 | struct uart_icount *icount; |
740 | unsigned long offset; | 740 | unsigned long offset; |
@@ -761,7 +761,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
761 | /* Block copy all but the last byte as this may have status */ | 761 | /* Block copy all but the last byte as this may have status */ |
762 | if (count > 0) { | 762 | if (count > 0) { |
763 | first = icom_port->recv_buf[offset]; | 763 | first = icom_port->recv_buf[offset]; |
764 | tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1); | 764 | tty_insert_flip_string(port, icom_port->recv_buf + offset, count - 1); |
765 | } | 765 | } |
766 | 766 | ||
767 | icount = &icom_port->uart_port.icount; | 767 | icount = &icom_port->uart_port.icount; |
@@ -812,7 +812,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
812 | 812 | ||
813 | } | 813 | } |
814 | 814 | ||
815 | tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag); | 815 | tty_insert_flip_char(port, *(icom_port->recv_buf + offset + count - 1), flag); |
816 | 816 | ||
817 | if (status & SA_FLAGS_OVERRUN) | 817 | if (status & SA_FLAGS_OVERRUN) |
818 | /* | 818 | /* |
@@ -820,7 +820,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
820 | * reported immediately, and doesn't | 820 | * reported immediately, and doesn't |
821 | * affect the current character | 821 | * affect the current character |
822 | */ | 822 | */ |
823 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 823 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
824 | ignore_char: | 824 | ignore_char: |
825 | icom_port->statStg->rcv[rcv_buff].flags = 0; | 825 | icom_port->statStg->rcv[rcv_buff].flags = 0; |
826 | icom_port->statStg->rcv[rcv_buff].leLength = 0; | 826 | icom_port->statStg->rcv[rcv_buff].leLength = 0; |
@@ -834,7 +834,7 @@ ignore_char: | |||
834 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); | 834 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); |
835 | } | 835 | } |
836 | icom_port->next_rcv = rcv_buff; | 836 | icom_port->next_rcv = rcv_buff; |
837 | tty_flip_buffer_push(tty); | 837 | tty_flip_buffer_push(port); |
838 | } | 838 | } |
839 | 839 | ||
840 | static void process_interrupt(u16 port_int_reg, | 840 | static void process_interrupt(u16 port_int_reg, |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 8cb6d8d66a13..68d7ce997ede 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -481,7 +481,6 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev) | |||
481 | unsigned char *tx_buffer; | 481 | unsigned char *tx_buffer; |
482 | 482 | ||
483 | tx_buffer = ifx_dev->tx_buffer; | 483 | tx_buffer = ifx_dev->tx_buffer; |
484 | memset(tx_buffer, 0, IFX_SPI_TRANSFER_SIZE); | ||
485 | 484 | ||
486 | /* make room for required SPI header */ | 485 | /* make room for required SPI header */ |
487 | tx_buffer += IFX_SPI_HEADER_OVERHEAD; | 486 | tx_buffer += IFX_SPI_HEADER_OVERHEAD; |
@@ -615,7 +614,7 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty) | |||
615 | tty->driver_data = ifx_dev; | 614 | tty->driver_data = ifx_dev; |
616 | 615 | ||
617 | /* allows flip string push from int context */ | 616 | /* allows flip string push from int context */ |
618 | tty->low_latency = 1; | 617 | port->low_latency = 1; |
619 | 618 | ||
620 | /* set flag to allows data transfer */ | 619 | /* set flag to allows data transfer */ |
621 | set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); | 620 | set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); |
@@ -670,12 +669,8 @@ static const struct tty_operations ifx_spi_serial_ops = { | |||
670 | static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, | 669 | static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, |
671 | unsigned char *chars, size_t size) | 670 | unsigned char *chars, size_t size) |
672 | { | 671 | { |
673 | struct tty_struct *tty = tty_port_tty_get(&ifx_dev->tty_port); | 672 | tty_insert_flip_string(&ifx_dev->tty_port, chars, size); |
674 | if (!tty) | 673 | tty_flip_buffer_push(&ifx_dev->tty_port); |
675 | return; | ||
676 | tty_insert_flip_string(tty, chars, size); | ||
677 | tty_flip_buffer_push(tty); | ||
678 | tty_kref_put(tty); | ||
679 | } | 674 | } |
680 | 675 | ||
681 | /** | 676 | /** |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 59819121fe9b..147c9e193595 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -48,8 +48,8 @@ | |||
48 | #include <linux/of.h> | 48 | #include <linux/of.h> |
49 | #include <linux/of_device.h> | 49 | #include <linux/of_device.h> |
50 | #include <linux/pinctrl/consumer.h> | 50 | #include <linux/pinctrl/consumer.h> |
51 | #include <linux/io.h> | ||
51 | 52 | ||
52 | #include <asm/io.h> | ||
53 | #include <asm/irq.h> | 53 | #include <asm/irq.h> |
54 | #include <linux/platform_data/serial-imx.h> | 54 | #include <linux/platform_data/serial-imx.h> |
55 | 55 | ||
@@ -73,102 +73,102 @@ | |||
73 | #define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/ | 73 | #define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/ |
74 | 74 | ||
75 | /* UART Control Register Bit Fields.*/ | 75 | /* UART Control Register Bit Fields.*/ |
76 | #define URXD_CHARRDY (1<<15) | 76 | #define URXD_CHARRDY (1<<15) |
77 | #define URXD_ERR (1<<14) | 77 | #define URXD_ERR (1<<14) |
78 | #define URXD_OVRRUN (1<<13) | 78 | #define URXD_OVRRUN (1<<13) |
79 | #define URXD_FRMERR (1<<12) | 79 | #define URXD_FRMERR (1<<12) |
80 | #define URXD_BRK (1<<11) | 80 | #define URXD_BRK (1<<11) |
81 | #define URXD_PRERR (1<<10) | 81 | #define URXD_PRERR (1<<10) |
82 | #define UCR1_ADEN (1<<15) /* Auto detect interrupt */ | 82 | #define UCR1_ADEN (1<<15) /* Auto detect interrupt */ |
83 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ | 83 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ |
84 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ | 84 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ |
85 | #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ | 85 | #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ |
86 | #define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ | 86 | #define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ |
87 | #define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ | 87 | #define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ |
88 | #define UCR1_IREN (1<<7) /* Infrared interface enable */ | 88 | #define UCR1_IREN (1<<7) /* Infrared interface enable */ |
89 | #define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ | 89 | #define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ |
90 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ | 90 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ |
91 | #define UCR1_SNDBRK (1<<4) /* Send break */ | 91 | #define UCR1_SNDBRK (1<<4) /* Send break */ |
92 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ | 92 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ |
93 | #define IMX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, i.mx1 only */ | 93 | #define IMX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, i.mx1 only */ |
94 | #define UCR1_DOZE (1<<1) /* Doze */ | 94 | #define UCR1_DOZE (1<<1) /* Doze */ |
95 | #define UCR1_UARTEN (1<<0) /* UART enabled */ | 95 | #define UCR1_UARTEN (1<<0) /* UART enabled */ |
96 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ | 96 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ |
97 | #define UCR2_IRTS (1<<14) /* Ignore RTS pin */ | 97 | #define UCR2_IRTS (1<<14) /* Ignore RTS pin */ |
98 | #define UCR2_CTSC (1<<13) /* CTS pin control */ | 98 | #define UCR2_CTSC (1<<13) /* CTS pin control */ |
99 | #define UCR2_CTS (1<<12) /* Clear to send */ | 99 | #define UCR2_CTS (1<<12) /* Clear to send */ |
100 | #define UCR2_ESCEN (1<<11) /* Escape enable */ | 100 | #define UCR2_ESCEN (1<<11) /* Escape enable */ |
101 | #define UCR2_PREN (1<<8) /* Parity enable */ | 101 | #define UCR2_PREN (1<<8) /* Parity enable */ |
102 | #define UCR2_PROE (1<<7) /* Parity odd/even */ | 102 | #define UCR2_PROE (1<<7) /* Parity odd/even */ |
103 | #define UCR2_STPB (1<<6) /* Stop */ | 103 | #define UCR2_STPB (1<<6) /* Stop */ |
104 | #define UCR2_WS (1<<5) /* Word size */ | 104 | #define UCR2_WS (1<<5) /* Word size */ |
105 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ | 105 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ |
106 | #define UCR2_ATEN (1<<3) /* Aging Timer Enable */ | 106 | #define UCR2_ATEN (1<<3) /* Aging Timer Enable */ |
107 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ | 107 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ |
108 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ | 108 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ |
109 | #define UCR2_SRST (1<<0) /* SW reset */ | 109 | #define UCR2_SRST (1<<0) /* SW reset */ |
110 | #define UCR3_DTREN (1<<13) /* DTR interrupt enable */ | 110 | #define UCR3_DTREN (1<<13) /* DTR interrupt enable */ |
111 | #define UCR3_PARERREN (1<<12) /* Parity enable */ | 111 | #define UCR3_PARERREN (1<<12) /* Parity enable */ |
112 | #define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ | 112 | #define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ |
113 | #define UCR3_DSR (1<<10) /* Data set ready */ | 113 | #define UCR3_DSR (1<<10) /* Data set ready */ |
114 | #define UCR3_DCD (1<<9) /* Data carrier detect */ | 114 | #define UCR3_DCD (1<<9) /* Data carrier detect */ |
115 | #define UCR3_RI (1<<8) /* Ring indicator */ | 115 | #define UCR3_RI (1<<8) /* Ring indicator */ |
116 | #define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */ | 116 | #define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */ |
117 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ | 117 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ |
118 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ | 118 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ |
119 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ | 119 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ |
120 | #define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */ | 120 | #define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */ |
121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ | 121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ |
122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ | 122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ |
123 | #define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ | 123 | #define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ |
124 | #define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ | 124 | #define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ |
125 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ | 125 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ |
126 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ | 126 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ |
127 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ | 127 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ |
128 | #define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ | 128 | #define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ |
129 | #define UCR4_IRSC (1<<5) /* IR special case */ | 129 | #define UCR4_IRSC (1<<5) /* IR special case */ |
130 | #define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ | 130 | #define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ |
131 | #define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ | 131 | #define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ |
132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ | 132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ |
133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ | 133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ |
134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ | 134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ |
135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ | 135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ |
136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ | 136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ |
137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) | 137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) |
138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ | 138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ |
139 | #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ | 139 | #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ |
140 | #define USR1_RTSS (1<<14) /* RTS pin status */ | 140 | #define USR1_RTSS (1<<14) /* RTS pin status */ |
141 | #define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ | 141 | #define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ |
142 | #define USR1_RTSD (1<<12) /* RTS delta */ | 142 | #define USR1_RTSD (1<<12) /* RTS delta */ |
143 | #define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ | 143 | #define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ |
144 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ | 144 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ |
145 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ | 145 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ |
146 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ | 146 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ |
147 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ | 147 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ |
148 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ | 148 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ |
149 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ | 149 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ |
150 | #define USR2_ADET (1<<15) /* Auto baud rate detect complete */ | 150 | #define USR2_ADET (1<<15) /* Auto baud rate detect complete */ |
151 | #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ | 151 | #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ |
152 | #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ | 152 | #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ |
153 | #define USR2_IDLE (1<<12) /* Idle condition */ | 153 | #define USR2_IDLE (1<<12) /* Idle condition */ |
154 | #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ | 154 | #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ |
155 | #define USR2_WAKE (1<<7) /* Wake */ | 155 | #define USR2_WAKE (1<<7) /* Wake */ |
156 | #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ | 156 | #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ |
157 | #define USR2_TXDC (1<<3) /* Transmitter complete */ | 157 | #define USR2_TXDC (1<<3) /* Transmitter complete */ |
158 | #define USR2_BRCD (1<<2) /* Break condition */ | 158 | #define USR2_BRCD (1<<2) /* Break condition */ |
159 | #define USR2_ORE (1<<1) /* Overrun error */ | 159 | #define USR2_ORE (1<<1) /* Overrun error */ |
160 | #define USR2_RDR (1<<0) /* Recv data ready */ | 160 | #define USR2_RDR (1<<0) /* Recv data ready */ |
161 | #define UTS_FRCPERR (1<<13) /* Force parity error */ | 161 | #define UTS_FRCPERR (1<<13) /* Force parity error */ |
162 | #define UTS_LOOP (1<<12) /* Loop tx and rx */ | 162 | #define UTS_LOOP (1<<12) /* Loop tx and rx */ |
163 | #define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ | 163 | #define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ |
164 | #define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ | 164 | #define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ |
165 | #define UTS_TXFULL (1<<4) /* TxFIFO full */ | 165 | #define UTS_TXFULL (1<<4) /* TxFIFO full */ |
166 | #define UTS_RXFULL (1<<3) /* RxFIFO full */ | 166 | #define UTS_RXFULL (1<<3) /* RxFIFO full */ |
167 | #define UTS_SOFTRST (1<<0) /* Software reset */ | 167 | #define UTS_SOFTRST (1<<0) /* Software reset */ |
168 | 168 | ||
169 | /* We've been assigned a range on the "Low-density serial ports" major */ | 169 | /* We've been assigned a range on the "Low-density serial ports" major */ |
170 | #define SERIAL_IMX_MAJOR 207 | 170 | #define SERIAL_IMX_MAJOR 207 |
171 | #define MINOR_START 16 | 171 | #define MINOR_START 16 |
172 | #define DEV_NAME "ttymxc" | 172 | #define DEV_NAME "ttymxc" |
173 | 173 | ||
174 | /* | 174 | /* |
@@ -199,7 +199,7 @@ struct imx_port { | |||
199 | struct uart_port port; | 199 | struct uart_port port; |
200 | struct timer_list timer; | 200 | struct timer_list timer; |
201 | unsigned int old_status; | 201 | unsigned int old_status; |
202 | int txirq,rxirq,rtsirq; | 202 | int txirq, rxirq, rtsirq; |
203 | unsigned int have_rtscts:1; | 203 | unsigned int have_rtscts:1; |
204 | unsigned int use_irda:1; | 204 | unsigned int use_irda:1; |
205 | unsigned int irda_inv_rx:1; | 205 | unsigned int irda_inv_rx:1; |
@@ -397,7 +397,7 @@ static void imx_stop_rx(struct uart_port *port) | |||
397 | unsigned long temp; | 397 | unsigned long temp; |
398 | 398 | ||
399 | temp = readl(sport->port.membase + UCR2); | 399 | temp = readl(sport->port.membase + UCR2); |
400 | writel(temp &~ UCR2_RXEN, sport->port.membase + UCR2); | 400 | writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2); |
401 | } | 401 | } |
402 | 402 | ||
403 | /* | 403 | /* |
@@ -490,9 +490,8 @@ static irqreturn_t imx_txint(int irq, void *dev_id) | |||
490 | struct circ_buf *xmit = &sport->port.state->xmit; | 490 | struct circ_buf *xmit = &sport->port.state->xmit; |
491 | unsigned long flags; | 491 | unsigned long flags; |
492 | 492 | ||
493 | spin_lock_irqsave(&sport->port.lock,flags); | 493 | spin_lock_irqsave(&sport->port.lock, flags); |
494 | if (sport->port.x_char) | 494 | if (sport->port.x_char) { |
495 | { | ||
496 | /* Send next char */ | 495 | /* Send next char */ |
497 | writel(sport->port.x_char, sport->port.membase + URTX0); | 496 | writel(sport->port.x_char, sport->port.membase + URTX0); |
498 | goto out; | 497 | goto out; |
@@ -509,18 +508,18 @@ static irqreturn_t imx_txint(int irq, void *dev_id) | |||
509 | uart_write_wakeup(&sport->port); | 508 | uart_write_wakeup(&sport->port); |
510 | 509 | ||
511 | out: | 510 | out: |
512 | spin_unlock_irqrestore(&sport->port.lock,flags); | 511 | spin_unlock_irqrestore(&sport->port.lock, flags); |
513 | return IRQ_HANDLED; | 512 | return IRQ_HANDLED; |
514 | } | 513 | } |
515 | 514 | ||
516 | static irqreturn_t imx_rxint(int irq, void *dev_id) | 515 | static irqreturn_t imx_rxint(int irq, void *dev_id) |
517 | { | 516 | { |
518 | struct imx_port *sport = dev_id; | 517 | struct imx_port *sport = dev_id; |
519 | unsigned int rx,flg,ignored = 0; | 518 | unsigned int rx, flg, ignored = 0; |
520 | struct tty_struct *tty = sport->port.state->port.tty; | 519 | struct tty_port *port = &sport->port.state->port; |
521 | unsigned long flags, temp; | 520 | unsigned long flags, temp; |
522 | 521 | ||
523 | spin_lock_irqsave(&sport->port.lock,flags); | 522 | spin_lock_irqsave(&sport->port.lock, flags); |
524 | 523 | ||
525 | while (readl(sport->port.membase + USR2) & USR2_RDR) { | 524 | while (readl(sport->port.membase + USR2) & USR2_RDR) { |
526 | flg = TTY_NORMAL; | 525 | flg = TTY_NORMAL; |
@@ -570,12 +569,12 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
570 | #endif | 569 | #endif |
571 | } | 570 | } |
572 | 571 | ||
573 | tty_insert_flip_char(tty, rx, flg); | 572 | tty_insert_flip_char(port, rx, flg); |
574 | } | 573 | } |
575 | 574 | ||
576 | out: | 575 | out: |
577 | spin_unlock_irqrestore(&sport->port.lock,flags); | 576 | spin_unlock_irqrestore(&sport->port.lock, flags); |
578 | tty_flip_buffer_push(tty); | 577 | tty_flip_buffer_push(port); |
579 | return IRQ_HANDLED; | 578 | return IRQ_HANDLED; |
580 | } | 579 | } |
581 | 580 | ||
@@ -654,7 +653,7 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
654 | 653 | ||
655 | temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK; | 654 | temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK; |
656 | 655 | ||
657 | if ( break_state != 0 ) | 656 | if (break_state != 0) |
658 | temp |= UCR1_SNDBRK; | 657 | temp |= UCR1_SNDBRK; |
659 | 658 | ||
660 | writel(temp, sport->port.membase + UCR1); | 659 | writel(temp, sport->port.membase + UCR1); |
@@ -696,8 +695,8 @@ static int imx_startup(struct uart_port *port) | |||
696 | temp |= UCR4_IRSC; | 695 | temp |= UCR4_IRSC; |
697 | 696 | ||
698 | /* set the trigger level for CTS */ | 697 | /* set the trigger level for CTS */ |
699 | temp &= ~(UCR4_CTSTL_MASK<< UCR4_CTSTL_SHF); | 698 | temp &= ~(UCR4_CTSTL_MASK << UCR4_CTSTL_SHF); |
700 | temp |= CTSTL<< UCR4_CTSTL_SHF; | 699 | temp |= CTSTL << UCR4_CTSTL_SHF; |
701 | 700 | ||
702 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); | 701 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); |
703 | 702 | ||
@@ -799,7 +798,7 @@ static int imx_startup(struct uart_port *port) | |||
799 | * Enable modem status interrupts | 798 | * Enable modem status interrupts |
800 | */ | 799 | */ |
801 | imx_enable_ms(&sport->port); | 800 | imx_enable_ms(&sport->port); |
802 | spin_unlock_irqrestore(&sport->port.lock,flags); | 801 | spin_unlock_irqrestore(&sport->port.lock, flags); |
803 | 802 | ||
804 | if (USE_IRDA(sport)) { | 803 | if (USE_IRDA(sport)) { |
805 | struct imxuart_platform_data *pdata; | 804 | struct imxuart_platform_data *pdata; |
@@ -909,7 +908,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
909 | ucr2 = UCR2_SRST | UCR2_IRTS; | 908 | ucr2 = UCR2_SRST | UCR2_IRTS; |
910 | 909 | ||
911 | if (termios->c_cflag & CRTSCTS) { | 910 | if (termios->c_cflag & CRTSCTS) { |
912 | if( sport->have_rtscts ) { | 911 | if (sport->have_rtscts) { |
913 | ucr2 &= ~UCR2_IRTS; | 912 | ucr2 &= ~UCR2_IRTS; |
914 | ucr2 |= UCR2_CTSC; | 913 | ucr2 |= UCR2_CTSC; |
915 | } else { | 914 | } else { |
@@ -969,12 +968,12 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
969 | writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), | 968 | writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), |
970 | sport->port.membase + UCR1); | 969 | sport->port.membase + UCR1); |
971 | 970 | ||
972 | while ( !(readl(sport->port.membase + USR2) & USR2_TXDC)) | 971 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)) |
973 | barrier(); | 972 | barrier(); |
974 | 973 | ||
975 | /* then, disable everything */ | 974 | /* then, disable everything */ |
976 | old_txrxen = readl(sport->port.membase + UCR2); | 975 | old_txrxen = readl(sport->port.membase + UCR2); |
977 | writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN), | 976 | writel(old_txrxen & ~(UCR2_TXEN | UCR2_RXEN), |
978 | sport->port.membase + UCR2); | 977 | sport->port.membase + UCR2); |
979 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); | 978 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); |
980 | 979 | ||
@@ -1212,9 +1211,15 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1212 | struct imx_port *sport = imx_ports[co->index]; | 1211 | struct imx_port *sport = imx_ports[co->index]; |
1213 | struct imx_port_ucrs old_ucr; | 1212 | struct imx_port_ucrs old_ucr; |
1214 | unsigned int ucr1; | 1213 | unsigned int ucr1; |
1215 | unsigned long flags; | 1214 | unsigned long flags = 0; |
1215 | int locked = 1; | ||
1216 | 1216 | ||
1217 | spin_lock_irqsave(&sport->port.lock, flags); | 1217 | if (sport->port.sysrq) |
1218 | locked = 0; | ||
1219 | else if (oops_in_progress) | ||
1220 | locked = spin_trylock_irqsave(&sport->port.lock, flags); | ||
1221 | else | ||
1222 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1218 | 1223 | ||
1219 | /* | 1224 | /* |
1220 | * First, save UCR1/2/3 and then disable interrupts | 1225 | * First, save UCR1/2/3 and then disable interrupts |
@@ -1241,7 +1246,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1241 | 1246 | ||
1242 | imx_port_ucrs_restore(&sport->port, &old_ucr); | 1247 | imx_port_ucrs_restore(&sport->port, &old_ucr); |
1243 | 1248 | ||
1244 | spin_unlock_irqrestore(&sport->port.lock, flags); | 1249 | if (locked) |
1250 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1245 | } | 1251 | } |
1246 | 1252 | ||
1247 | /* | 1253 | /* |
@@ -1255,7 +1261,7 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
1255 | 1261 | ||
1256 | if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) { | 1262 | if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) { |
1257 | /* ok, the port was enabled */ | 1263 | /* ok, the port was enabled */ |
1258 | unsigned int ucr2, ubir,ubmr, uartclk; | 1264 | unsigned int ucr2, ubir, ubmr, uartclk; |
1259 | unsigned int baud_raw; | 1265 | unsigned int baud_raw; |
1260 | unsigned int ucfr_rfdiv; | 1266 | unsigned int ucfr_rfdiv; |
1261 | 1267 | ||
@@ -1301,8 +1307,8 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
1301 | *baud = (baud_raw + 50) / 100 * 100; | 1307 | *baud = (baud_raw + 50) / 100 * 100; |
1302 | } | 1308 | } |
1303 | 1309 | ||
1304 | if(*baud != baud_raw) | 1310 | if (*baud != baud_raw) |
1305 | printk(KERN_INFO "Serial: Console IMX rounded baud rate from %d to %d\n", | 1311 | pr_info("Console IMX rounded baud rate from %d to %d\n", |
1306 | baud_raw, *baud); | 1312 | baud_raw, *baud); |
1307 | } | 1313 | } |
1308 | } | 1314 | } |
@@ -1324,7 +1330,7 @@ imx_console_setup(struct console *co, char *options) | |||
1324 | if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) | 1330 | if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) |
1325 | co->index = 0; | 1331 | co->index = 0; |
1326 | sport = imx_ports[co->index]; | 1332 | sport = imx_ports[co->index]; |
1327 | if(sport == NULL) | 1333 | if (sport == NULL) |
1328 | return -ENODEV; | 1334 | return -ENODEV; |
1329 | 1335 | ||
1330 | if (options) | 1336 | if (options) |
@@ -1462,7 +1468,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1462 | struct resource *res; | 1468 | struct resource *res; |
1463 | struct pinctrl *pinctrl; | 1469 | struct pinctrl *pinctrl; |
1464 | 1470 | ||
1465 | sport = kzalloc(sizeof(*sport), GFP_KERNEL); | 1471 | sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); |
1466 | if (!sport) | 1472 | if (!sport) |
1467 | return -ENOMEM; | 1473 | return -ENOMEM; |
1468 | 1474 | ||
@@ -1470,19 +1476,15 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1470 | if (ret > 0) | 1476 | if (ret > 0) |
1471 | serial_imx_probe_pdata(sport, pdev); | 1477 | serial_imx_probe_pdata(sport, pdev); |
1472 | else if (ret < 0) | 1478 | else if (ret < 0) |
1473 | goto free; | 1479 | return ret; |
1474 | 1480 | ||
1475 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1481 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1476 | if (!res) { | 1482 | if (!res) |
1477 | ret = -ENODEV; | 1483 | return -ENODEV; |
1478 | goto free; | ||
1479 | } | ||
1480 | 1484 | ||
1481 | base = ioremap(res->start, PAGE_SIZE); | 1485 | base = devm_ioremap(&pdev->dev, res->start, PAGE_SIZE); |
1482 | if (!base) { | 1486 | if (!base) |
1483 | ret = -ENOMEM; | 1487 | return -ENOMEM; |
1484 | goto free; | ||
1485 | } | ||
1486 | 1488 | ||
1487 | sport->port.dev = &pdev->dev; | 1489 | sport->port.dev = &pdev->dev; |
1488 | sport->port.mapbase = res->start; | 1490 | sport->port.mapbase = res->start; |
@@ -1504,21 +1506,21 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1504 | if (IS_ERR(pinctrl)) { | 1506 | if (IS_ERR(pinctrl)) { |
1505 | ret = PTR_ERR(pinctrl); | 1507 | ret = PTR_ERR(pinctrl); |
1506 | dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); | 1508 | dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); |
1507 | goto unmap; | 1509 | return ret; |
1508 | } | 1510 | } |
1509 | 1511 | ||
1510 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1512 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
1511 | if (IS_ERR(sport->clk_ipg)) { | 1513 | if (IS_ERR(sport->clk_ipg)) { |
1512 | ret = PTR_ERR(sport->clk_ipg); | 1514 | ret = PTR_ERR(sport->clk_ipg); |
1513 | dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret); | 1515 | dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret); |
1514 | goto unmap; | 1516 | return ret; |
1515 | } | 1517 | } |
1516 | 1518 | ||
1517 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); | 1519 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); |
1518 | if (IS_ERR(sport->clk_per)) { | 1520 | if (IS_ERR(sport->clk_per)) { |
1519 | ret = PTR_ERR(sport->clk_per); | 1521 | ret = PTR_ERR(sport->clk_per); |
1520 | dev_err(&pdev->dev, "failed to get per clk: %d\n", ret); | 1522 | dev_err(&pdev->dev, "failed to get per clk: %d\n", ret); |
1521 | goto unmap; | 1523 | return ret; |
1522 | } | 1524 | } |
1523 | 1525 | ||
1524 | clk_prepare_enable(sport->clk_per); | 1526 | clk_prepare_enable(sport->clk_per); |
@@ -1547,11 +1549,6 @@ deinit: | |||
1547 | clkput: | 1549 | clkput: |
1548 | clk_disable_unprepare(sport->clk_per); | 1550 | clk_disable_unprepare(sport->clk_per); |
1549 | clk_disable_unprepare(sport->clk_ipg); | 1551 | clk_disable_unprepare(sport->clk_ipg); |
1550 | unmap: | ||
1551 | iounmap(sport->port.membase); | ||
1552 | free: | ||
1553 | kfree(sport); | ||
1554 | |||
1555 | return ret; | 1552 | return ret; |
1556 | } | 1553 | } |
1557 | 1554 | ||
@@ -1572,9 +1569,6 @@ static int serial_imx_remove(struct platform_device *pdev) | |||
1572 | if (pdata && pdata->exit) | 1569 | if (pdata && pdata->exit) |
1573 | pdata->exit(pdev); | 1570 | pdata->exit(pdev); |
1574 | 1571 | ||
1575 | iounmap(sport->port.membase); | ||
1576 | kfree(sport); | ||
1577 | |||
1578 | return 0; | 1572 | return 0; |
1579 | } | 1573 | } |
1580 | 1574 | ||
@@ -1596,7 +1590,7 @@ static int __init imx_serial_init(void) | |||
1596 | { | 1590 | { |
1597 | int ret; | 1591 | int ret; |
1598 | 1592 | ||
1599 | printk(KERN_INFO "Serial: IMX driver\n"); | 1593 | pr_info("Serial: IMX driver\n"); |
1600 | 1594 | ||
1601 | ret = uart_register_driver(&imx_reg); | 1595 | ret = uart_register_driver(&imx_reg); |
1602 | if (ret) | 1596 | if (ret) |
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index d8f1d1d54471..6e4c715c5d26 100644 --- a/drivers/tty/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c | |||
@@ -1000,7 +1000,7 @@ ioc3_change_speed(struct uart_port *the_port, | |||
1000 | 1000 | ||
1001 | the_port->ignore_status_mask = N_ALL_INPUT; | 1001 | the_port->ignore_status_mask = N_ALL_INPUT; |
1002 | 1002 | ||
1003 | state->port.tty->low_latency = 1; | 1003 | state->port.low_latency = 1; |
1004 | 1004 | ||
1005 | if (iflag & IGNPAR) | 1005 | if (iflag & IGNPAR) |
1006 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR | 1006 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR |
@@ -1393,7 +1393,6 @@ static inline int do_read(struct uart_port *the_port, char *buf, int len) | |||
1393 | */ | 1393 | */ |
1394 | static int receive_chars(struct uart_port *the_port) | 1394 | static int receive_chars(struct uart_port *the_port) |
1395 | { | 1395 | { |
1396 | struct tty_struct *tty; | ||
1397 | unsigned char ch[MAX_CHARS]; | 1396 | unsigned char ch[MAX_CHARS]; |
1398 | int read_count = 0, read_room, flip = 0; | 1397 | int read_count = 0, read_room, flip = 0; |
1399 | struct uart_state *state = the_port->state; | 1398 | struct uart_state *state = the_port->state; |
@@ -1403,25 +1402,23 @@ static int receive_chars(struct uart_port *the_port) | |||
1403 | /* Make sure all the pointers are "good" ones */ | 1402 | /* Make sure all the pointers are "good" ones */ |
1404 | if (!state) | 1403 | if (!state) |
1405 | return 0; | 1404 | return 0; |
1406 | if (!state->port.tty) | ||
1407 | return 0; | ||
1408 | 1405 | ||
1409 | if (!(port->ip_flags & INPUT_ENABLE)) | 1406 | if (!(port->ip_flags & INPUT_ENABLE)) |
1410 | return 0; | 1407 | return 0; |
1411 | 1408 | ||
1412 | spin_lock_irqsave(&the_port->lock, pflags); | 1409 | spin_lock_irqsave(&the_port->lock, pflags); |
1413 | tty = state->port.tty; | ||
1414 | 1410 | ||
1415 | read_count = do_read(the_port, ch, MAX_CHARS); | 1411 | read_count = do_read(the_port, ch, MAX_CHARS); |
1416 | if (read_count > 0) { | 1412 | if (read_count > 0) { |
1417 | flip = 1; | 1413 | flip = 1; |
1418 | read_room = tty_insert_flip_string(tty, ch, read_count); | 1414 | read_room = tty_insert_flip_string(&state->port, ch, |
1415 | read_count); | ||
1419 | the_port->icount.rx += read_count; | 1416 | the_port->icount.rx += read_count; |
1420 | } | 1417 | } |
1421 | spin_unlock_irqrestore(&the_port->lock, pflags); | 1418 | spin_unlock_irqrestore(&the_port->lock, pflags); |
1422 | 1419 | ||
1423 | if (flip) | 1420 | if (flip) |
1424 | tty_flip_buffer_push(tty); | 1421 | tty_flip_buffer_push(&state->port); |
1425 | 1422 | ||
1426 | return read_count; | 1423 | return read_count; |
1427 | } | 1424 | } |
diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index 3e7da10cebba..e2520abcb1c4 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c | |||
@@ -1740,7 +1740,7 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1740 | 1740 | ||
1741 | the_port->ignore_status_mask = N_ALL_INPUT; | 1741 | the_port->ignore_status_mask = N_ALL_INPUT; |
1742 | 1742 | ||
1743 | state->port.tty->low_latency = 1; | 1743 | state->port.low_latency = 1; |
1744 | 1744 | ||
1745 | if (iflag & IGNPAR) | 1745 | if (iflag & IGNPAR) |
1746 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR | 1746 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR |
@@ -2340,7 +2340,6 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf, | |||
2340 | */ | 2340 | */ |
2341 | static void receive_chars(struct uart_port *the_port) | 2341 | static void receive_chars(struct uart_port *the_port) |
2342 | { | 2342 | { |
2343 | struct tty_struct *tty; | ||
2344 | unsigned char ch[IOC4_MAX_CHARS]; | 2343 | unsigned char ch[IOC4_MAX_CHARS]; |
2345 | int read_count, request_count = IOC4_MAX_CHARS; | 2344 | int read_count, request_count = IOC4_MAX_CHARS; |
2346 | struct uart_icount *icount; | 2345 | struct uart_icount *icount; |
@@ -2350,26 +2349,23 @@ static void receive_chars(struct uart_port *the_port) | |||
2350 | /* Make sure all the pointers are "good" ones */ | 2349 | /* Make sure all the pointers are "good" ones */ |
2351 | if (!state) | 2350 | if (!state) |
2352 | return; | 2351 | return; |
2353 | if (!state->port.tty) | ||
2354 | return; | ||
2355 | 2352 | ||
2356 | spin_lock_irqsave(&the_port->lock, pflags); | 2353 | spin_lock_irqsave(&the_port->lock, pflags); |
2357 | tty = state->port.tty; | ||
2358 | 2354 | ||
2359 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS); | 2355 | request_count = tty_buffer_request_room(&state->port, IOC4_MAX_CHARS); |
2360 | 2356 | ||
2361 | if (request_count > 0) { | 2357 | if (request_count > 0) { |
2362 | icount = &the_port->icount; | 2358 | icount = &the_port->icount; |
2363 | read_count = do_read(the_port, ch, request_count); | 2359 | read_count = do_read(the_port, ch, request_count); |
2364 | if (read_count > 0) { | 2360 | if (read_count > 0) { |
2365 | tty_insert_flip_string(tty, ch, read_count); | 2361 | tty_insert_flip_string(&state->port, ch, read_count); |
2366 | icount->rx += read_count; | 2362 | icount->rx += read_count; |
2367 | } | 2363 | } |
2368 | } | 2364 | } |
2369 | 2365 | ||
2370 | spin_unlock_irqrestore(&the_port->lock, pflags); | 2366 | spin_unlock_irqrestore(&the_port->lock, pflags); |
2371 | 2367 | ||
2372 | tty_flip_buffer_push(tty); | 2368 | tty_flip_buffer_push(&state->port); |
2373 | } | 2369 | } |
2374 | 2370 | ||
2375 | /** | 2371 | /** |
@@ -2883,6 +2879,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) | |||
2883 | /* error exits that give back resources */ | 2879 | /* error exits that give back resources */ |
2884 | out5: | 2880 | out5: |
2885 | ioc4_serial_remove_one(idd); | 2881 | ioc4_serial_remove_one(idd); |
2882 | return ret; | ||
2886 | out4: | 2883 | out4: |
2887 | kfree(soft); | 2884 | kfree(soft); |
2888 | out3: | 2885 | out3: |
diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 7b1cda59ebb5..cb3c81eb0996 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c | |||
@@ -248,17 +248,12 @@ static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up, | |||
248 | #define Rx_BRK 0x0100 /* BREAK event software flag. */ | 248 | #define Rx_BRK 0x0100 /* BREAK event software flag. */ |
249 | #define Rx_SYS 0x0200 /* SysRq event software flag. */ | 249 | #define Rx_SYS 0x0200 /* SysRq event software flag. */ |
250 | 250 | ||
251 | static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | 251 | static bool ip22zilog_receive_chars(struct uart_ip22zilog_port *up, |
252 | struct zilog_channel *channel) | 252 | struct zilog_channel *channel) |
253 | { | 253 | { |
254 | struct tty_struct *tty; | ||
255 | unsigned char ch, flag; | 254 | unsigned char ch, flag; |
256 | unsigned int r1; | 255 | unsigned int r1; |
257 | 256 | bool push = up->port.state != NULL; | |
258 | tty = NULL; | ||
259 | if (up->port.state != NULL && | ||
260 | up->port.state->port.tty != NULL) | ||
261 | tty = up->port.state->port.tty; | ||
262 | 257 | ||
263 | for (;;) { | 258 | for (;;) { |
264 | ch = readb(&channel->control); | 259 | ch = readb(&channel->control); |
@@ -312,10 +307,10 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up | |||
312 | if (uart_handle_sysrq_char(&up->port, ch)) | 307 | if (uart_handle_sysrq_char(&up->port, ch)) |
313 | continue; | 308 | continue; |
314 | 309 | ||
315 | if (tty) | 310 | if (push) |
316 | uart_insert_char(&up->port, r1, Rx_OVR, ch, flag); | 311 | uart_insert_char(&up->port, r1, Rx_OVR, ch, flag); |
317 | } | 312 | } |
318 | return tty; | 313 | return push; |
319 | } | 314 | } |
320 | 315 | ||
321 | static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, | 316 | static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, |
@@ -438,21 +433,20 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
438 | while (up) { | 433 | while (up) { |
439 | struct zilog_channel *channel | 434 | struct zilog_channel *channel |
440 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | 435 | = ZILOG_CHANNEL_FROM_PORT(&up->port); |
441 | struct tty_struct *tty; | ||
442 | unsigned char r3; | 436 | unsigned char r3; |
437 | bool push = false; | ||
443 | 438 | ||
444 | spin_lock(&up->port.lock); | 439 | spin_lock(&up->port.lock); |
445 | r3 = read_zsreg(channel, R3); | 440 | r3 = read_zsreg(channel, R3); |
446 | 441 | ||
447 | /* Channel A */ | 442 | /* Channel A */ |
448 | tty = NULL; | ||
449 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 443 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
450 | writeb(RES_H_IUS, &channel->control); | 444 | writeb(RES_H_IUS, &channel->control); |
451 | ZSDELAY(); | 445 | ZSDELAY(); |
452 | ZS_WSYNC(channel); | 446 | ZS_WSYNC(channel); |
453 | 447 | ||
454 | if (r3 & CHARxIP) | 448 | if (r3 & CHARxIP) |
455 | tty = ip22zilog_receive_chars(up, channel); | 449 | push = ip22zilog_receive_chars(up, channel); |
456 | if (r3 & CHAEXT) | 450 | if (r3 & CHAEXT) |
457 | ip22zilog_status_handle(up, channel); | 451 | ip22zilog_status_handle(up, channel); |
458 | if (r3 & CHATxIP) | 452 | if (r3 & CHATxIP) |
@@ -460,22 +454,22 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
460 | } | 454 | } |
461 | spin_unlock(&up->port.lock); | 455 | spin_unlock(&up->port.lock); |
462 | 456 | ||
463 | if (tty) | 457 | if (push) |
464 | tty_flip_buffer_push(tty); | 458 | tty_flip_buffer_push(&up->port.state->port); |
465 | 459 | ||
466 | /* Channel B */ | 460 | /* Channel B */ |
467 | up = up->next; | 461 | up = up->next; |
468 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | 462 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); |
463 | push = false; | ||
469 | 464 | ||
470 | spin_lock(&up->port.lock); | 465 | spin_lock(&up->port.lock); |
471 | tty = NULL; | ||
472 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 466 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
473 | writeb(RES_H_IUS, &channel->control); | 467 | writeb(RES_H_IUS, &channel->control); |
474 | ZSDELAY(); | 468 | ZSDELAY(); |
475 | ZS_WSYNC(channel); | 469 | ZS_WSYNC(channel); |
476 | 470 | ||
477 | if (r3 & CHBRxIP) | 471 | if (r3 & CHBRxIP) |
478 | tty = ip22zilog_receive_chars(up, channel); | 472 | push = ip22zilog_receive_chars(up, channel); |
479 | if (r3 & CHBEXT) | 473 | if (r3 & CHBEXT) |
480 | ip22zilog_status_handle(up, channel); | 474 | ip22zilog_status_handle(up, channel); |
481 | if (r3 & CHBTxIP) | 475 | if (r3 & CHBTxIP) |
@@ -483,8 +477,8 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
483 | } | 477 | } |
484 | spin_unlock(&up->port.lock); | 478 | spin_unlock(&up->port.lock); |
485 | 479 | ||
486 | if (tty) | 480 | if (push) |
487 | tty_flip_buffer_push(tty); | 481 | tty_flip_buffer_push(&up->port.state->port); |
488 | 482 | ||
489 | up = up->next; | 483 | up = up->next; |
490 | } | 484 | } |
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 4c00c5550b1a..00f250ae14c5 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c | |||
@@ -521,6 +521,7 @@ void jsm_input(struct jsm_channel *ch) | |||
521 | { | 521 | { |
522 | struct jsm_board *bd; | 522 | struct jsm_board *bd; |
523 | struct tty_struct *tp; | 523 | struct tty_struct *tp; |
524 | struct tty_port *port; | ||
524 | u32 rmask; | 525 | u32 rmask; |
525 | u16 head; | 526 | u16 head; |
526 | u16 tail; | 527 | u16 tail; |
@@ -536,7 +537,8 @@ void jsm_input(struct jsm_channel *ch) | |||
536 | if (!ch) | 537 | if (!ch) |
537 | return; | 538 | return; |
538 | 539 | ||
539 | tp = ch->uart_port.state->port.tty; | 540 | port = &ch->uart_port.state->port; |
541 | tp = port->tty; | ||
540 | 542 | ||
541 | bd = ch->ch_bd; | 543 | bd = ch->ch_bd; |
542 | if(!bd) | 544 | if(!bd) |
@@ -600,7 +602,7 @@ void jsm_input(struct jsm_channel *ch) | |||
600 | return; | 602 | return; |
601 | } | 603 | } |
602 | 604 | ||
603 | len = tty_buffer_request_room(tp, data_len); | 605 | len = tty_buffer_request_room(port, data_len); |
604 | n = len; | 606 | n = len; |
605 | 607 | ||
606 | /* | 608 | /* |
@@ -629,16 +631,16 @@ void jsm_input(struct jsm_channel *ch) | |||
629 | * format it likes. | 631 | * format it likes. |
630 | */ | 632 | */ |
631 | if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) | 633 | if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) |
632 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_BREAK); | 634 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_BREAK); |
633 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) | 635 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) |
634 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY); | 636 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_PARITY); |
635 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) | 637 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) |
636 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME); | 638 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_FRAME); |
637 | else | 639 | else |
638 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL); | 640 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_NORMAL); |
639 | } | 641 | } |
640 | } else { | 642 | } else { |
641 | tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; | 643 | tty_insert_flip_string(port, ch->ch_rqueue + tail, s); |
642 | } | 644 | } |
643 | tail += s; | 645 | tail += s; |
644 | n -= s; | 646 | n -= s; |
@@ -652,7 +654,7 @@ void jsm_input(struct jsm_channel *ch) | |||
652 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 654 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); |
653 | 655 | ||
654 | /* Tell the tty layer its okay to "eat" the data now */ | 656 | /* Tell the tty layer its okay to "eat" the data now */ |
655 | tty_flip_buffer_push(tp); | 657 | tty_flip_buffer_push(port); |
656 | 658 | ||
657 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); | 659 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); |
658 | } | 660 | } |
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 6ac2b797a764..5dafcf1c227b 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
24 | #include <linux/tty_driver.h> | 24 | #include <linux/tty_driver.h> |
25 | #include <linux/tty_flip.h> | 25 | #include <linux/tty_flip.h> |
26 | #include <linux/serial_core.h> | ||
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
27 | #include <linux/hrtimer.h> | 28 | #include <linux/hrtimer.h> |
28 | #include <linux/tick.h> | 29 | #include <linux/tick.h> |
@@ -202,7 +203,6 @@ bool kgdb_nmi_poll_knock(void) | |||
202 | static void kgdb_nmi_tty_receiver(unsigned long data) | 203 | static void kgdb_nmi_tty_receiver(unsigned long data) |
203 | { | 204 | { |
204 | struct kgdb_nmi_tty_priv *priv = (void *)data; | 205 | struct kgdb_nmi_tty_priv *priv = (void *)data; |
205 | struct tty_struct *tty; | ||
206 | char ch; | 206 | char ch; |
207 | 207 | ||
208 | tasklet_schedule(&priv->tlet); | 208 | tasklet_schedule(&priv->tlet); |
@@ -210,16 +210,9 @@ static void kgdb_nmi_tty_receiver(unsigned long data) | |||
210 | if (likely(!kgdb_nmi_tty_enabled || !kfifo_len(&priv->fifo))) | 210 | if (likely(!kgdb_nmi_tty_enabled || !kfifo_len(&priv->fifo))) |
211 | return; | 211 | return; |
212 | 212 | ||
213 | /* Port is there, but tty might be hung up, check. */ | ||
214 | tty = tty_port_tty_get(kgdb_nmi_port); | ||
215 | if (!tty) | ||
216 | return; | ||
217 | |||
218 | while (kfifo_out(&priv->fifo, &ch, 1)) | 213 | while (kfifo_out(&priv->fifo, &ch, 1)) |
219 | tty_insert_flip_char(priv->port.tty, ch, TTY_NORMAL); | 214 | tty_insert_flip_char(&priv->port, ch, TTY_NORMAL); |
220 | tty_flip_buffer_push(priv->port.tty); | 215 | tty_flip_buffer_push(&priv->port); |
221 | |||
222 | tty_kref_put(tty); | ||
223 | } | 216 | } |
224 | 217 | ||
225 | static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty) | 218 | static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty) |
diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 02da071fe1e7..15733da757c6 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c | |||
@@ -162,21 +162,16 @@ lqasc_enable_ms(struct uart_port *port) | |||
162 | static int | 162 | static int |
163 | lqasc_rx_chars(struct uart_port *port) | 163 | lqasc_rx_chars(struct uart_port *port) |
164 | { | 164 | { |
165 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 165 | struct tty_port *tport = &port->state->port; |
166 | unsigned int ch = 0, rsr = 0, fifocnt; | 166 | unsigned int ch = 0, rsr = 0, fifocnt; |
167 | 167 | ||
168 | if (!tty) { | 168 | fifocnt = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; |
169 | dev_dbg(port->dev, "%s:tty is busy now", __func__); | ||
170 | return -EBUSY; | ||
171 | } | ||
172 | fifocnt = | ||
173 | ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; | ||
174 | while (fifocnt--) { | 169 | while (fifocnt--) { |
175 | u8 flag = TTY_NORMAL; | 170 | u8 flag = TTY_NORMAL; |
176 | ch = ltq_r8(port->membase + LTQ_ASC_RBUF); | 171 | ch = ltq_r8(port->membase + LTQ_ASC_RBUF); |
177 | rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) | 172 | rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) |
178 | & ASCSTATE_ANY) | UART_DUMMY_UER_RX; | 173 | & ASCSTATE_ANY) | UART_DUMMY_UER_RX; |
179 | tty_flip_buffer_push(tty); | 174 | tty_flip_buffer_push(tport); |
180 | port->icount.rx++; | 175 | port->icount.rx++; |
181 | 176 | ||
182 | /* | 177 | /* |
@@ -208,7 +203,7 @@ lqasc_rx_chars(struct uart_port *port) | |||
208 | } | 203 | } |
209 | 204 | ||
210 | if ((rsr & port->ignore_status_mask) == 0) | 205 | if ((rsr & port->ignore_status_mask) == 0) |
211 | tty_insert_flip_char(tty, ch, flag); | 206 | tty_insert_flip_char(tport, ch, flag); |
212 | 207 | ||
213 | if (rsr & ASCSTATE_ROE) | 208 | if (rsr & ASCSTATE_ROE) |
214 | /* | 209 | /* |
@@ -216,11 +211,12 @@ lqasc_rx_chars(struct uart_port *port) | |||
216 | * immediately, and doesn't affect the current | 211 | * immediately, and doesn't affect the current |
217 | * character | 212 | * character |
218 | */ | 213 | */ |
219 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 214 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
220 | } | 215 | } |
216 | |||
221 | if (ch != 0) | 217 | if (ch != 0) |
222 | tty_flip_buffer_push(tty); | 218 | tty_flip_buffer_push(tport); |
223 | tty_kref_put(tty); | 219 | |
224 | return 0; | 220 | return 0; |
225 | } | 221 | } |
226 | 222 | ||
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index 0e86bff3fe2a..dffea6b2cd7d 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c | |||
@@ -257,17 +257,8 @@ static void __serial_uart_flush(struct uart_port *port) | |||
257 | 257 | ||
258 | static void __serial_lpc32xx_rx(struct uart_port *port) | 258 | static void __serial_lpc32xx_rx(struct uart_port *port) |
259 | { | 259 | { |
260 | struct tty_port *tport = &port->state->port; | ||
260 | unsigned int tmp, flag; | 261 | unsigned int tmp, flag; |
261 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
262 | |||
263 | if (!tty) { | ||
264 | /* Discard data: no tty available */ | ||
265 | while (!(readl(LPC32XX_HSUART_FIFO(port->membase)) & | ||
266 | LPC32XX_HSU_RX_EMPTY)) | ||
267 | ; | ||
268 | |||
269 | return; | ||
270 | } | ||
271 | 262 | ||
272 | /* Read data from FIFO and push into terminal */ | 263 | /* Read data from FIFO and push into terminal */ |
273 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | 264 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); |
@@ -281,15 +272,14 @@ static void __serial_lpc32xx_rx(struct uart_port *port) | |||
281 | LPC32XX_HSUART_IIR(port->membase)); | 272 | LPC32XX_HSUART_IIR(port->membase)); |
282 | port->icount.frame++; | 273 | port->icount.frame++; |
283 | flag = TTY_FRAME; | 274 | flag = TTY_FRAME; |
284 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 275 | tty_insert_flip_char(tport, 0, TTY_FRAME); |
285 | } | 276 | } |
286 | 277 | ||
287 | tty_insert_flip_char(tty, (tmp & 0xFF), flag); | 278 | tty_insert_flip_char(tport, (tmp & 0xFF), flag); |
288 | 279 | ||
289 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | 280 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); |
290 | } | 281 | } |
291 | tty_flip_buffer_push(tty); | 282 | tty_flip_buffer_push(tport); |
292 | tty_kref_put(tty); | ||
293 | } | 283 | } |
294 | 284 | ||
295 | static void __serial_lpc32xx_tx(struct uart_port *port) | 285 | static void __serial_lpc32xx_tx(struct uart_port *port) |
@@ -332,7 +322,7 @@ exit_tx: | |||
332 | static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | 322 | static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) |
333 | { | 323 | { |
334 | struct uart_port *port = dev_id; | 324 | struct uart_port *port = dev_id; |
335 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 325 | struct tty_port *tport = &port->state->port; |
336 | u32 status; | 326 | u32 status; |
337 | 327 | ||
338 | spin_lock(&port->lock); | 328 | spin_lock(&port->lock); |
@@ -356,17 +346,14 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | |||
356 | writel(LPC32XX_HSU_RX_OE_INT, | 346 | writel(LPC32XX_HSU_RX_OE_INT, |
357 | LPC32XX_HSUART_IIR(port->membase)); | 347 | LPC32XX_HSUART_IIR(port->membase)); |
358 | port->icount.overrun++; | 348 | port->icount.overrun++; |
359 | if (tty) { | 349 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
360 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 350 | tty_schedule_flip(tport); |
361 | tty_schedule_flip(tty); | ||
362 | } | ||
363 | } | 351 | } |
364 | 352 | ||
365 | /* Data received? */ | 353 | /* Data received? */ |
366 | if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { | 354 | if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { |
367 | __serial_lpc32xx_rx(port); | 355 | __serial_lpc32xx_rx(port); |
368 | if (tty) | 356 | tty_flip_buffer_push(tport); |
369 | tty_flip_buffer_push(tty); | ||
370 | } | 357 | } |
371 | 358 | ||
372 | /* Transmit data request? */ | 359 | /* Transmit data request? */ |
@@ -376,7 +363,6 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | |||
376 | } | 363 | } |
377 | 364 | ||
378 | spin_unlock(&port->lock); | 365 | spin_unlock(&port->lock); |
379 | tty_kref_put(tty); | ||
380 | 366 | ||
381 | return IRQ_HANDLED; | 367 | return IRQ_HANDLED; |
382 | } | 368 | } |
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index b13949ad3408..bb1afa0922e1 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
@@ -300,7 +300,7 @@ static void m32r_sio_enable_ms(struct uart_port *port) | |||
300 | 300 | ||
301 | static void receive_chars(struct uart_sio_port *up, int *status) | 301 | static void receive_chars(struct uart_sio_port *up, int *status) |
302 | { | 302 | { |
303 | struct tty_struct *tty = up->port.state->port.tty; | 303 | struct tty_port *port = &up->port.state->port; |
304 | unsigned char ch; | 304 | unsigned char ch; |
305 | unsigned char flag; | 305 | unsigned char flag; |
306 | int max_count = 256; | 306 | int max_count = 256; |
@@ -355,7 +355,7 @@ static void receive_chars(struct uart_sio_port *up, int *status) | |||
355 | if (uart_handle_sysrq_char(&up->port, ch)) | 355 | if (uart_handle_sysrq_char(&up->port, ch)) |
356 | goto ignore_char; | 356 | goto ignore_char; |
357 | if ((*status & up->port.ignore_status_mask) == 0) | 357 | if ((*status & up->port.ignore_status_mask) == 0) |
358 | tty_insert_flip_char(tty, ch, flag); | 358 | tty_insert_flip_char(port, ch, flag); |
359 | 359 | ||
360 | if (*status & UART_LSR_OE) { | 360 | if (*status & UART_LSR_OE) { |
361 | /* | 361 | /* |
@@ -363,12 +363,12 @@ static void receive_chars(struct uart_sio_port *up, int *status) | |||
363 | * immediately, and doesn't affect the current | 363 | * immediately, and doesn't affect the current |
364 | * character. | 364 | * character. |
365 | */ | 365 | */ |
366 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 366 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
367 | } | 367 | } |
368 | ignore_char: | 368 | ignore_char: |
369 | *status = serial_in(up, UART_LSR); | 369 | *status = serial_in(up, UART_LSR); |
370 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 370 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
371 | tty_flip_buffer_push(tty); | 371 | tty_flip_buffer_push(port); |
372 | } | 372 | } |
373 | 373 | ||
374 | static void transmit_chars(struct uart_sio_port *up) | 374 | static void transmit_chars(struct uart_sio_port *up) |
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index dd6277eb5a38..32517d4bceab 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
@@ -310,8 +310,8 @@ static void max3100_work(struct work_struct *w) | |||
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
313 | if (rxchars > 16 && s->port.state->port.tty != NULL) { | 313 | if (rxchars > 16) { |
314 | tty_flip_buffer_push(s->port.state->port.tty); | 314 | tty_flip_buffer_push(&s->port.state->port); |
315 | rxchars = 0; | 315 | rxchars = 0; |
316 | } | 316 | } |
317 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 317 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -323,8 +323,8 @@ static void max3100_work(struct work_struct *w) | |||
323 | (!uart_circ_empty(xmit) && | 323 | (!uart_circ_empty(xmit) && |
324 | !uart_tx_stopped(&s->port)))); | 324 | !uart_tx_stopped(&s->port)))); |
325 | 325 | ||
326 | if (rxchars > 0 && s->port.state->port.tty != NULL) | 326 | if (rxchars > 0) |
327 | tty_flip_buffer_push(s->port.state->port.tty); | 327 | tty_flip_buffer_push(&s->port.state->port); |
328 | } | 328 | } |
329 | 329 | ||
330 | static irqreturn_t max3100_irq(int irqno, void *dev_id) | 330 | static irqreturn_t max3100_irq(int irqno, void *dev_id) |
@@ -529,7 +529,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, | |||
529 | MAX3100_STATUS_OE; | 529 | MAX3100_STATUS_OE; |
530 | 530 | ||
531 | /* we are sending char from a workqueue so enable */ | 531 | /* we are sending char from a workqueue so enable */ |
532 | s->port.state->port.tty->low_latency = 1; | 532 | s->port.state->port.low_latency = 1; |
533 | 533 | ||
534 | if (s->poll_time > 0) | 534 | if (s->poll_time > 0) |
535 | del_timer_sync(&s->timer); | 535 | del_timer_sync(&s->timer); |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index a801f6872cad..0c2422cb04ea 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -460,10 +460,6 @@ static int max310x_set_ref_clk(struct max310x_port *s) | |||
460 | static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) | 460 | static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) |
461 | { | 461 | { |
462 | unsigned int sts = 0, ch = 0, flag; | 462 | unsigned int sts = 0, ch = 0, flag; |
463 | struct tty_struct *tty = tty_port_tty_get(&s->port.state->port); | ||
464 | |||
465 | if (!tty) | ||
466 | return; | ||
467 | 463 | ||
468 | if (unlikely(rxlen >= MAX310X_FIFO_SIZE)) { | 464 | if (unlikely(rxlen >= MAX310X_FIFO_SIZE)) { |
469 | dev_warn(s->port.dev, "Possible RX FIFO overrun %d\n", rxlen); | 465 | dev_warn(s->port.dev, "Possible RX FIFO overrun %d\n", rxlen); |
@@ -516,9 +512,7 @@ static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) | |||
516 | ch, flag); | 512 | ch, flag); |
517 | } | 513 | } |
518 | 514 | ||
519 | tty_flip_buffer_push(tty); | 515 | tty_flip_buffer_push(&s->port.state->port); |
520 | |||
521 | tty_kref_put(tty); | ||
522 | } | 516 | } |
523 | 517 | ||
524 | static void max310x_handle_tx(struct max310x_port *s) | 518 | static void max310x_handle_tx(struct max310x_port *s) |
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index fcd56ab6053f..e956377a38fe 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
24 | #include <linux/serial_core.h> | 24 | #include <linux/serial_core.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/uaccess.h> | ||
26 | #include <asm/coldfire.h> | 27 | #include <asm/coldfire.h> |
27 | #include <asm/mcfsim.h> | 28 | #include <asm/mcfsim.h> |
28 | #include <asm/mcfuart.h> | 29 | #include <asm/mcfuart.h> |
@@ -55,6 +56,7 @@ struct mcf_uart { | |||
55 | struct uart_port port; | 56 | struct uart_port port; |
56 | unsigned int sigs; /* Local copy of line sigs */ | 57 | unsigned int sigs; /* Local copy of line sigs */ |
57 | unsigned char imr; /* Local IMR mirror */ | 58 | unsigned char imr; /* Local IMR mirror */ |
59 | struct serial_rs485 rs485; /* RS485 settings */ | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | /****************************************************************************/ | 62 | /****************************************************************************/ |
@@ -101,6 +103,12 @@ static void mcf_start_tx(struct uart_port *port) | |||
101 | { | 103 | { |
102 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 104 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
103 | 105 | ||
106 | if (pp->rs485.flags & SER_RS485_ENABLED) { | ||
107 | /* Enable Transmitter */ | ||
108 | writeb(MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); | ||
109 | /* Manually assert RTS */ | ||
110 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); | ||
111 | } | ||
104 | pp->imr |= MCFUART_UIR_TXREADY; | 112 | pp->imr |= MCFUART_UIR_TXREADY; |
105 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 113 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
106 | } | 114 | } |
@@ -196,6 +204,7 @@ static void mcf_shutdown(struct uart_port *port) | |||
196 | static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | 204 | static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, |
197 | struct ktermios *old) | 205 | struct ktermios *old) |
198 | { | 206 | { |
207 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
199 | unsigned long flags; | 208 | unsigned long flags; |
200 | unsigned int baud, baudclk; | 209 | unsigned int baud, baudclk; |
201 | #if defined(CONFIG_M5272) | 210 | #if defined(CONFIG_M5272) |
@@ -248,6 +257,11 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | |||
248 | mr2 |= MCFUART_MR2_TXCTS; | 257 | mr2 |= MCFUART_MR2_TXCTS; |
249 | } | 258 | } |
250 | 259 | ||
260 | if (pp->rs485.flags & SER_RS485_ENABLED) { | ||
261 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
262 | mr2 |= MCFUART_MR2_TXRTS; | ||
263 | } | ||
264 | |||
251 | spin_lock_irqsave(&port->lock, flags); | 265 | spin_lock_irqsave(&port->lock, flags); |
252 | uart_update_timeout(port, termios->c_cflag, baud); | 266 | uart_update_timeout(port, termios->c_cflag, baud); |
253 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); | 267 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); |
@@ -310,7 +324,7 @@ static void mcf_rx_chars(struct mcf_uart *pp) | |||
310 | uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); | 324 | uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); |
311 | } | 325 | } |
312 | 326 | ||
313 | tty_flip_buffer_push(port->state->port.tty); | 327 | tty_flip_buffer_push(&port->state->port); |
314 | } | 328 | } |
315 | 329 | ||
316 | /****************************************************************************/ | 330 | /****************************************************************************/ |
@@ -342,6 +356,10 @@ static void mcf_tx_chars(struct mcf_uart *pp) | |||
342 | if (xmit->head == xmit->tail) { | 356 | if (xmit->head == xmit->tail) { |
343 | pp->imr &= ~MCFUART_UIR_TXREADY; | 357 | pp->imr &= ~MCFUART_UIR_TXREADY; |
344 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 358 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
359 | /* Disable TX to negate RTS automatically */ | ||
360 | if (pp->rs485.flags & SER_RS485_ENABLED) | ||
361 | writeb(MCFUART_UCR_TXDISABLE, | ||
362 | port->membase + MCFUART_UCR); | ||
345 | } | 363 | } |
346 | } | 364 | } |
347 | 365 | ||
@@ -418,6 +436,58 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
418 | 436 | ||
419 | /****************************************************************************/ | 437 | /****************************************************************************/ |
420 | 438 | ||
439 | /* Enable or disable the RS485 support */ | ||
440 | static void mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) | ||
441 | { | ||
442 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
443 | unsigned long flags; | ||
444 | unsigned char mr1, mr2; | ||
445 | |||
446 | spin_lock_irqsave(&port->lock, flags); | ||
447 | /* Get mode registers */ | ||
448 | mr1 = readb(port->membase + MCFUART_UMR); | ||
449 | mr2 = readb(port->membase + MCFUART_UMR); | ||
450 | if (rs485->flags & SER_RS485_ENABLED) { | ||
451 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
452 | /* Automatically negate RTS after TX completes */ | ||
453 | mr2 |= MCFUART_MR2_TXRTS; | ||
454 | } else { | ||
455 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
456 | mr2 &= ~MCFUART_MR2_TXRTS; | ||
457 | } | ||
458 | writeb(mr1, port->membase + MCFUART_UMR); | ||
459 | writeb(mr2, port->membase + MCFUART_UMR); | ||
460 | pp->rs485 = *rs485; | ||
461 | spin_unlock_irqrestore(&port->lock, flags); | ||
462 | } | ||
463 | |||
464 | static int mcf_ioctl(struct uart_port *port, unsigned int cmd, | ||
465 | unsigned long arg) | ||
466 | { | ||
467 | switch (cmd) { | ||
468 | case TIOCSRS485: { | ||
469 | struct serial_rs485 rs485; | ||
470 | if (copy_from_user(&rs485, (struct serial_rs485 *)arg, | ||
471 | sizeof(struct serial_rs485))) | ||
472 | return -EFAULT; | ||
473 | mcf_config_rs485(port, &rs485); | ||
474 | break; | ||
475 | } | ||
476 | case TIOCGRS485: { | ||
477 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
478 | if (copy_to_user((struct serial_rs485 *)arg, &pp->rs485, | ||
479 | sizeof(struct serial_rs485))) | ||
480 | return -EFAULT; | ||
481 | break; | ||
482 | } | ||
483 | default: | ||
484 | return -ENOIOCTLCMD; | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | /****************************************************************************/ | ||
490 | |||
421 | /* | 491 | /* |
422 | * Define the basic serial functions we support. | 492 | * Define the basic serial functions we support. |
423 | */ | 493 | */ |
@@ -438,6 +508,7 @@ static const struct uart_ops mcf_uart_ops = { | |||
438 | .release_port = mcf_release_port, | 508 | .release_port = mcf_release_port, |
439 | .config_port = mcf_config_port, | 509 | .config_port = mcf_config_port, |
440 | .verify_port = mcf_verify_port, | 510 | .verify_port = mcf_verify_port, |
511 | .ioctl = mcf_ioctl, | ||
441 | }; | 512 | }; |
442 | 513 | ||
443 | static struct mcf_uart mcf_ports[4]; | 514 | static struct mcf_uart mcf_ports[4]; |
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 2c01344dc332..5f4765a7a5c5 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c | |||
@@ -387,12 +387,9 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
387 | struct hsu_dma_buffer *dbuf = &up->rxbuf; | 387 | struct hsu_dma_buffer *dbuf = &up->rxbuf; |
388 | struct hsu_dma_chan *chan = up->rxc; | 388 | struct hsu_dma_chan *chan = up->rxc; |
389 | struct uart_port *port = &up->port; | 389 | struct uart_port *port = &up->port; |
390 | struct tty_struct *tty = port->state->port.tty; | 390 | struct tty_port *tport = &port->state->port; |
391 | int count; | 391 | int count; |
392 | 392 | ||
393 | if (!tty) | ||
394 | return; | ||
395 | |||
396 | /* | 393 | /* |
397 | * First need to know how many is already transferred, | 394 | * First need to know how many is already transferred, |
398 | * then check if its a timeout DMA irq, and return | 395 | * then check if its a timeout DMA irq, and return |
@@ -423,7 +420,7 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
423 | * explicitly set tail to 0. So head will | 420 | * explicitly set tail to 0. So head will |
424 | * always be greater than tail. | 421 | * always be greater than tail. |
425 | */ | 422 | */ |
426 | tty_insert_flip_string(tty, dbuf->buf, count); | 423 | tty_insert_flip_string(tport, dbuf->buf, count); |
427 | port->icount.rx += count; | 424 | port->icount.rx += count; |
428 | 425 | ||
429 | dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, | 426 | dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, |
@@ -437,7 +434,7 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
437 | | (0x1 << 16) | 434 | | (0x1 << 16) |
438 | | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ | 435 | | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ |
439 | ); | 436 | ); |
440 | tty_flip_buffer_push(tty); | 437 | tty_flip_buffer_push(tport); |
441 | 438 | ||
442 | chan_writel(chan, HSU_CH_CR, 0x3); | 439 | chan_writel(chan, HSU_CH_CR, 0x3); |
443 | 440 | ||
@@ -460,13 +457,9 @@ static void serial_hsu_stop_rx(struct uart_port *port) | |||
460 | 457 | ||
461 | static inline void receive_chars(struct uart_hsu_port *up, int *status) | 458 | static inline void receive_chars(struct uart_hsu_port *up, int *status) |
462 | { | 459 | { |
463 | struct tty_struct *tty = up->port.state->port.tty; | ||
464 | unsigned int ch, flag; | 460 | unsigned int ch, flag; |
465 | unsigned int max_count = 256; | 461 | unsigned int max_count = 256; |
466 | 462 | ||
467 | if (!tty) | ||
468 | return; | ||
469 | |||
470 | do { | 463 | do { |
471 | ch = serial_in(up, UART_RX); | 464 | ch = serial_in(up, UART_RX); |
472 | flag = TTY_NORMAL; | 465 | flag = TTY_NORMAL; |
@@ -522,7 +515,7 @@ static inline void receive_chars(struct uart_hsu_port *up, int *status) | |||
522 | ignore_char: | 515 | ignore_char: |
523 | *status = serial_in(up, UART_LSR); | 516 | *status = serial_in(up, UART_LSR); |
524 | } while ((*status & UART_LSR_DR) && max_count--); | 517 | } while ((*status & UART_LSR_DR) && max_count--); |
525 | tty_flip_buffer_push(tty); | 518 | tty_flip_buffer_push(&up->port.state->port); |
526 | } | 519 | } |
527 | 520 | ||
528 | static void transmit_chars(struct uart_hsu_port *up) | 521 | static void transmit_chars(struct uart_hsu_port *up) |
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 7c23c4f4c58d..c0e1fad51be7 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -941,7 +941,7 @@ static struct uart_ops mpc52xx_uart_ops = { | |||
941 | static inline int | 941 | static inline int |
942 | mpc52xx_uart_int_rx_chars(struct uart_port *port) | 942 | mpc52xx_uart_int_rx_chars(struct uart_port *port) |
943 | { | 943 | { |
944 | struct tty_struct *tty = port->state->port.tty; | 944 | struct tty_port *tport = &port->state->port; |
945 | unsigned char ch, flag; | 945 | unsigned char ch, flag; |
946 | unsigned short status; | 946 | unsigned short status; |
947 | 947 | ||
@@ -986,20 +986,20 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
986 | out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); | 986 | out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); |
987 | 987 | ||
988 | } | 988 | } |
989 | tty_insert_flip_char(tty, ch, flag); | 989 | tty_insert_flip_char(tport, ch, flag); |
990 | if (status & MPC52xx_PSC_SR_OE) { | 990 | if (status & MPC52xx_PSC_SR_OE) { |
991 | /* | 991 | /* |
992 | * Overrun is special, since it's | 992 | * Overrun is special, since it's |
993 | * reported immediately, and doesn't | 993 | * reported immediately, and doesn't |
994 | * affect the current character | 994 | * affect the current character |
995 | */ | 995 | */ |
996 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 996 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
997 | port->icount.overrun++; | 997 | port->icount.overrun++; |
998 | } | 998 | } |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | spin_unlock(&port->lock); | 1001 | spin_unlock(&port->lock); |
1002 | tty_flip_buffer_push(tty); | 1002 | tty_flip_buffer_push(tport); |
1003 | spin_lock(&port->lock); | 1003 | spin_lock(&port->lock); |
1004 | 1004 | ||
1005 | return psc_ops->raw_rx_rdy(port); | 1005 | return psc_ops->raw_rx_rdy(port); |
diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index 6a9c6605666a..bc24f4931670 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c | |||
@@ -937,7 +937,7 @@ static int serial_polled; | |||
937 | static int mpsc_rx_intr(struct mpsc_port_info *pi) | 937 | static int mpsc_rx_intr(struct mpsc_port_info *pi) |
938 | { | 938 | { |
939 | struct mpsc_rx_desc *rxre; | 939 | struct mpsc_rx_desc *rxre; |
940 | struct tty_struct *tty = pi->port.state->port.tty; | 940 | struct tty_port *port = &pi->port.state->port; |
941 | u32 cmdstat, bytes_in, i; | 941 | u32 cmdstat, bytes_in, i; |
942 | int rc = 0; | 942 | int rc = 0; |
943 | u8 *bp; | 943 | u8 *bp; |
@@ -968,10 +968,9 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) | |||
968 | } | 968 | } |
969 | #endif | 969 | #endif |
970 | /* Following use of tty struct directly is deprecated */ | 970 | /* Following use of tty struct directly is deprecated */ |
971 | if (unlikely(tty_buffer_request_room(tty, bytes_in) | 971 | if (tty_buffer_request_room(port, bytes_in) < bytes_in) { |
972 | < bytes_in)) { | 972 | if (port->low_latency) |
973 | if (tty->low_latency) | 973 | tty_flip_buffer_push(port); |
974 | tty_flip_buffer_push(tty); | ||
975 | /* | 974 | /* |
976 | * If this failed then we will throw away the bytes | 975 | * If this failed then we will throw away the bytes |
977 | * but must do so to clear interrupts. | 976 | * but must do so to clear interrupts. |
@@ -1040,10 +1039,10 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) | |||
1040 | | SDMA_DESC_CMDSTAT_FR | 1039 | | SDMA_DESC_CMDSTAT_FR |
1041 | | SDMA_DESC_CMDSTAT_OR))) | 1040 | | SDMA_DESC_CMDSTAT_OR))) |
1042 | && !(cmdstat & pi->port.ignore_status_mask)) { | 1041 | && !(cmdstat & pi->port.ignore_status_mask)) { |
1043 | tty_insert_flip_char(tty, *bp, flag); | 1042 | tty_insert_flip_char(port, *bp, flag); |
1044 | } else { | 1043 | } else { |
1045 | for (i=0; i<bytes_in; i++) | 1044 | for (i=0; i<bytes_in; i++) |
1046 | tty_insert_flip_char(tty, *bp++, TTY_NORMAL); | 1045 | tty_insert_flip_char(port, *bp++, TTY_NORMAL); |
1047 | 1046 | ||
1048 | pi->port.icount.rx += bytes_in; | 1047 | pi->port.icount.rx += bytes_in; |
1049 | } | 1048 | } |
@@ -1081,7 +1080,7 @@ next_frame: | |||
1081 | if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) | 1080 | if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) |
1082 | mpsc_start_rx(pi); | 1081 | mpsc_start_rx(pi); |
1083 | 1082 | ||
1084 | tty_flip_buffer_push(tty); | 1083 | tty_flip_buffer_push(port); |
1085 | return rc; | 1084 | return rc; |
1086 | } | 1085 | } |
1087 | 1086 | ||
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 58734d7e746d..f641c232beca 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c | |||
@@ -339,7 +339,7 @@ static int | |||
339 | receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | 339 | receive_chars(struct uart_max3110 *max, unsigned short *str, int len) |
340 | { | 340 | { |
341 | struct uart_port *port = &max->port; | 341 | struct uart_port *port = &max->port; |
342 | struct tty_struct *tty; | 342 | struct tty_port *tport; |
343 | char buf[M3110_RX_FIFO_DEPTH]; | 343 | char buf[M3110_RX_FIFO_DEPTH]; |
344 | int r, w, usable; | 344 | int r, w, usable; |
345 | 345 | ||
@@ -347,9 +347,7 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | |||
347 | if (!port->state) | 347 | if (!port->state) |
348 | return 0; | 348 | return 0; |
349 | 349 | ||
350 | tty = tty_port_tty_get(&port->state->port); | 350 | tport = &port->state->port; |
351 | if (!tty) | ||
352 | return 0; | ||
353 | 351 | ||
354 | for (r = 0, w = 0; r < len; r++) { | 352 | for (r = 0, w = 0; r < len; r++) { |
355 | if (str[r] & MAX3110_BREAK && | 353 | if (str[r] & MAX3110_BREAK && |
@@ -364,20 +362,17 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | |||
364 | } | 362 | } |
365 | } | 363 | } |
366 | 364 | ||
367 | if (!w) { | 365 | if (!w) |
368 | tty_kref_put(tty); | ||
369 | return 0; | 366 | return 0; |
370 | } | ||
371 | 367 | ||
372 | for (r = 0; w; r += usable, w -= usable) { | 368 | for (r = 0; w; r += usable, w -= usable) { |
373 | usable = tty_buffer_request_room(tty, w); | 369 | usable = tty_buffer_request_room(tport, w); |
374 | if (usable) { | 370 | if (usable) { |
375 | tty_insert_flip_string(tty, buf + r, usable); | 371 | tty_insert_flip_string(tport, buf + r, usable); |
376 | port->icount.rx += usable; | 372 | port->icount.rx += usable; |
377 | } | 373 | } |
378 | } | 374 | } |
379 | tty_flip_buffer_push(tty); | 375 | tty_flip_buffer_push(tport); |
380 | tty_kref_put(tty); | ||
381 | 376 | ||
382 | return r; | 377 | return r; |
383 | } | 378 | } |
@@ -493,7 +488,7 @@ static int serial_m3110_startup(struct uart_port *port) | |||
493 | | WC_BAUD_DR2; | 488 | | WC_BAUD_DR2; |
494 | 489 | ||
495 | /* as we use thread to handle tx/rx, need set low latency */ | 490 | /* as we use thread to handle tx/rx, need set low latency */ |
496 | port->state->port.tty->low_latency = 1; | 491 | port->state->port.low_latency = 1; |
497 | 492 | ||
498 | if (max->irq) { | 493 | if (max->irq) { |
499 | max->read_thread = NULL; | 494 | max->read_thread = NULL; |
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 95fd39be2934..b11e99797fd8 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -91,14 +91,14 @@ static void msm_enable_ms(struct uart_port *port) | |||
91 | 91 | ||
92 | static void handle_rx_dm(struct uart_port *port, unsigned int misr) | 92 | static void handle_rx_dm(struct uart_port *port, unsigned int misr) |
93 | { | 93 | { |
94 | struct tty_struct *tty = port->state->port.tty; | 94 | struct tty_port *tport = &port->state->port; |
95 | unsigned int sr; | 95 | unsigned int sr; |
96 | int count = 0; | 96 | int count = 0; |
97 | struct msm_port *msm_port = UART_TO_MSM(port); | 97 | struct msm_port *msm_port = UART_TO_MSM(port); |
98 | 98 | ||
99 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { | 99 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { |
100 | port->icount.overrun++; | 100 | port->icount.overrun++; |
101 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 101 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
102 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); | 102 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); |
103 | } | 103 | } |
104 | 104 | ||
@@ -132,12 +132,12 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) | |||
132 | port->icount.frame++; | 132 | port->icount.frame++; |
133 | 133 | ||
134 | /* TODO: handle sysrq */ | 134 | /* TODO: handle sysrq */ |
135 | tty_insert_flip_string(tty, (char *) &c, | 135 | tty_insert_flip_string(tport, (char *)&c, |
136 | (count > 4) ? 4 : count); | 136 | (count > 4) ? 4 : count); |
137 | count -= 4; | 137 | count -= 4; |
138 | } | 138 | } |
139 | 139 | ||
140 | tty_flip_buffer_push(tty); | 140 | tty_flip_buffer_push(tport); |
141 | if (misr & (UART_IMR_RXSTALE)) | 141 | if (misr & (UART_IMR_RXSTALE)) |
142 | msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); | 142 | msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); |
143 | msm_write(port, 0xFFFFFF, UARTDM_DMRX); | 143 | msm_write(port, 0xFFFFFF, UARTDM_DMRX); |
@@ -146,7 +146,7 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) | |||
146 | 146 | ||
147 | static void handle_rx(struct uart_port *port) | 147 | static void handle_rx(struct uart_port *port) |
148 | { | 148 | { |
149 | struct tty_struct *tty = port->state->port.tty; | 149 | struct tty_port *tport = &port->state->port; |
150 | unsigned int sr; | 150 | unsigned int sr; |
151 | 151 | ||
152 | /* | 152 | /* |
@@ -155,7 +155,7 @@ static void handle_rx(struct uart_port *port) | |||
155 | */ | 155 | */ |
156 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { | 156 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { |
157 | port->icount.overrun++; | 157 | port->icount.overrun++; |
158 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 158 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
159 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); | 159 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); |
160 | } | 160 | } |
161 | 161 | ||
@@ -186,10 +186,10 @@ static void handle_rx(struct uart_port *port) | |||
186 | } | 186 | } |
187 | 187 | ||
188 | if (!uart_handle_sysrq_char(port, c)) | 188 | if (!uart_handle_sysrq_char(port, c)) |
189 | tty_insert_flip_char(tty, c, flag); | 189 | tty_insert_flip_char(tport, c, flag); |
190 | } | 190 | } |
191 | 191 | ||
192 | tty_flip_buffer_push(tty); | 192 | tty_flip_buffer_push(tport); |
193 | } | 193 | } |
194 | 194 | ||
195 | static void reset_dm_count(struct uart_port *port) | 195 | static void reset_dm_count(struct uart_port *port) |
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 1fa92284ade0..4a942c78347e 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c | |||
@@ -908,6 +908,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
908 | unsigned long flags; | 908 | unsigned long flags; |
909 | unsigned int flush; | 909 | unsigned int flush; |
910 | struct tty_struct *tty; | 910 | struct tty_struct *tty; |
911 | struct tty_port *port; | ||
911 | struct uart_port *uport; | 912 | struct uart_port *uport; |
912 | struct msm_hs_port *msm_uport; | 913 | struct msm_hs_port *msm_uport; |
913 | 914 | ||
@@ -917,7 +918,8 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
917 | spin_lock_irqsave(&uport->lock, flags); | 918 | spin_lock_irqsave(&uport->lock, flags); |
918 | clk_enable(msm_uport->clk); | 919 | clk_enable(msm_uport->clk); |
919 | 920 | ||
920 | tty = uport->state->port.tty; | 921 | port = &uport->state->port; |
922 | tty = port->tty; | ||
921 | 923 | ||
922 | msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); | 924 | msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); |
923 | 925 | ||
@@ -926,7 +928,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
926 | /* overflow is not connect to data in a FIFO */ | 928 | /* overflow is not connect to data in a FIFO */ |
927 | if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) && | 929 | if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) && |
928 | (uport->read_status_mask & CREAD))) { | 930 | (uport->read_status_mask & CREAD))) { |
929 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 931 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
930 | uport->icount.buf_overrun++; | 932 | uport->icount.buf_overrun++; |
931 | error_f = 1; | 933 | error_f = 1; |
932 | } | 934 | } |
@@ -939,7 +941,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
939 | uport->icount.parity++; | 941 | uport->icount.parity++; |
940 | error_f = 1; | 942 | error_f = 1; |
941 | if (uport->ignore_status_mask & IGNPAR) | 943 | if (uport->ignore_status_mask & IGNPAR) |
942 | tty_insert_flip_char(tty, 0, TTY_PARITY); | 944 | tty_insert_flip_char(port, 0, TTY_PARITY); |
943 | } | 945 | } |
944 | 946 | ||
945 | if (error_f) | 947 | if (error_f) |
@@ -959,7 +961,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
959 | rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR); | 961 | rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR); |
960 | 962 | ||
961 | if (0 != (uport->read_status_mask & CREAD)) { | 963 | if (0 != (uport->read_status_mask & CREAD)) { |
962 | retval = tty_insert_flip_string(tty, msm_uport->rx.buffer, | 964 | retval = tty_insert_flip_string(port, msm_uport->rx.buffer, |
963 | rx_count); | 965 | rx_count); |
964 | BUG_ON(retval != rx_count); | 966 | BUG_ON(retval != rx_count); |
965 | } | 967 | } |
@@ -979,9 +981,8 @@ static void msm_hs_tty_flip_buffer_work(struct work_struct *work) | |||
979 | { | 981 | { |
980 | struct msm_hs_port *msm_uport = | 982 | struct msm_hs_port *msm_uport = |
981 | container_of(work, struct msm_hs_port, rx.tty_work); | 983 | container_of(work, struct msm_hs_port, rx.tty_work); |
982 | struct tty_struct *tty = msm_uport->uport.state->port.tty; | ||
983 | 984 | ||
984 | tty_flip_buffer_push(tty); | 985 | tty_flip_buffer_push(&msm_uport->uport.state->port); |
985 | } | 986 | } |
986 | 987 | ||
987 | /* | 988 | /* |
@@ -1344,7 +1345,6 @@ static irqreturn_t msm_hs_rx_wakeup_isr(int irq, void *dev) | |||
1344 | unsigned long flags; | 1345 | unsigned long flags; |
1345 | struct msm_hs_port *msm_uport = dev; | 1346 | struct msm_hs_port *msm_uport = dev; |
1346 | struct uart_port *uport = &msm_uport->uport; | 1347 | struct uart_port *uport = &msm_uport->uport; |
1347 | struct tty_struct *tty = NULL; | ||
1348 | 1348 | ||
1349 | spin_lock_irqsave(&uport->lock, flags); | 1349 | spin_lock_irqsave(&uport->lock, flags); |
1350 | if (msm_uport->clk_state == MSM_HS_CLK_OFF) { | 1350 | if (msm_uport->clk_state == MSM_HS_CLK_OFF) { |
@@ -1361,8 +1361,7 @@ static irqreturn_t msm_hs_rx_wakeup_isr(int irq, void *dev) | |||
1361 | * optionally inject char into tty rx */ | 1361 | * optionally inject char into tty rx */ |
1362 | msm_hs_request_clock_on_locked(uport); | 1362 | msm_hs_request_clock_on_locked(uport); |
1363 | if (msm_uport->rx_wakeup.inject_rx) { | 1363 | if (msm_uport->rx_wakeup.inject_rx) { |
1364 | tty = uport->state->port.tty; | 1364 | tty_insert_flip_char(&uport->state->port, |
1365 | tty_insert_flip_char(tty, | ||
1366 | msm_uport->rx_wakeup.rx_to_inject, | 1365 | msm_uport->rx_wakeup.rx_to_inject, |
1367 | TTY_NORMAL); | 1366 | TTY_NORMAL); |
1368 | queue_work(msm_hs_workqueue, &msm_uport->rx.tty_work); | 1367 | queue_work(msm_hs_workqueue, &msm_uport->rx.tty_work); |
@@ -1400,7 +1399,7 @@ static int msm_hs_startup(struct uart_port *uport) | |||
1400 | 1399 | ||
1401 | /* do not let tty layer execute RX in global workqueue, use a | 1400 | /* do not let tty layer execute RX in global workqueue, use a |
1402 | * dedicated workqueue managed by this driver */ | 1401 | * dedicated workqueue managed by this driver */ |
1403 | uport->state->port.tty->low_latency = 1; | 1402 | uport->state->port.low_latency = 1; |
1404 | 1403 | ||
1405 | /* turn on uart clk */ | 1404 | /* turn on uart clk */ |
1406 | ret = msm_hs_init_clk_locked(uport); | 1405 | ret = msm_hs_init_clk_locked(uport); |
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index 925d1fa153db..e722ff163d91 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c | |||
@@ -70,7 +70,7 @@ static void smd_tty_notify(void *priv, unsigned event) | |||
70 | if (avail == 0) | 70 | if (avail == 0) |
71 | break; | 71 | break; |
72 | 72 | ||
73 | avail = tty_prepare_flip_string(tty, &ptr, avail); | 73 | avail = tty_prepare_flip_string(&info->port, &ptr, avail); |
74 | 74 | ||
75 | if (smd_read(info->ch, ptr, avail) != avail) { | 75 | if (smd_read(info->ch, ptr, avail) != avail) { |
76 | /* shouldn't be possible since we're in interrupt | 76 | /* shouldn't be possible since we're in interrupt |
@@ -80,7 +80,7 @@ static void smd_tty_notify(void *priv, unsigned event) | |||
80 | pr_err("OOPS - smd_tty_buffer mismatch?!"); | 80 | pr_err("OOPS - smd_tty_buffer mismatch?!"); |
81 | } | 81 | } |
82 | 82 | ||
83 | tty_flip_buffer_push(tty); | 83 | tty_flip_buffer_push(&info->port); |
84 | } | 84 | } |
85 | 85 | ||
86 | /* XXX only when writable and necessary */ | 86 | /* XXX only when writable and necessary */ |
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index e2775b6df5a5..7fd6aaaacd8e 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c | |||
@@ -242,8 +242,8 @@ static void mux_write(struct uart_port *port) | |||
242 | */ | 242 | */ |
243 | static void mux_read(struct uart_port *port) | 243 | static void mux_read(struct uart_port *port) |
244 | { | 244 | { |
245 | struct tty_port *tport = &port->state->port; | ||
245 | int data; | 246 | int data; |
246 | struct tty_struct *tty = port->state->port.tty; | ||
247 | __u32 start_count = port->icount.rx; | 247 | __u32 start_count = port->icount.rx; |
248 | 248 | ||
249 | while(1) { | 249 | while(1) { |
@@ -266,12 +266,11 @@ static void mux_read(struct uart_port *port) | |||
266 | if (uart_handle_sysrq_char(port, data & 0xffu)) | 266 | if (uart_handle_sysrq_char(port, data & 0xffu)) |
267 | continue; | 267 | continue; |
268 | 268 | ||
269 | tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); | 269 | tty_insert_flip_char(tport, data & 0xFF, TTY_NORMAL); |
270 | } | 270 | } |
271 | 271 | ||
272 | if (start_count != port->icount.rx) { | 272 | if (start_count != port->icount.rx) |
273 | tty_flip_buffer_push(tty); | 273 | tty_flip_buffer_push(tport); |
274 | } | ||
275 | } | 274 | } |
276 | 275 | ||
277 | /** | 276 | /** |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index e55615eb34ad..d549fe1fa42a 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -364,7 +364,6 @@ out: | |||
364 | 364 | ||
365 | static void mxs_auart_rx_chars(struct mxs_auart_port *s) | 365 | static void mxs_auart_rx_chars(struct mxs_auart_port *s) |
366 | { | 366 | { |
367 | struct tty_struct *tty = s->port.state->port.tty; | ||
368 | u32 stat = 0; | 367 | u32 stat = 0; |
369 | 368 | ||
370 | for (;;) { | 369 | for (;;) { |
@@ -375,7 +374,7 @@ static void mxs_auart_rx_chars(struct mxs_auart_port *s) | |||
375 | } | 374 | } |
376 | 375 | ||
377 | writel(stat, s->port.membase + AUART_STAT); | 376 | writel(stat, s->port.membase + AUART_STAT); |
378 | tty_flip_buffer_push(tty); | 377 | tty_flip_buffer_push(&s->port.state->port); |
379 | } | 378 | } |
380 | 379 | ||
381 | static int mxs_auart_request_port(struct uart_port *u) | 380 | static int mxs_auart_request_port(struct uart_port *u) |
@@ -459,7 +458,7 @@ static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); | |||
459 | static void dma_rx_callback(void *arg) | 458 | static void dma_rx_callback(void *arg) |
460 | { | 459 | { |
461 | struct mxs_auart_port *s = (struct mxs_auart_port *) arg; | 460 | struct mxs_auart_port *s = (struct mxs_auart_port *) arg; |
462 | struct tty_struct *tty = s->port.state->port.tty; | 461 | struct tty_port *port = &s->port.state->port; |
463 | int count; | 462 | int count; |
464 | u32 stat; | 463 | u32 stat; |
465 | 464 | ||
@@ -470,10 +469,10 @@ static void dma_rx_callback(void *arg) | |||
470 | AUART_STAT_PERR | AUART_STAT_FERR); | 469 | AUART_STAT_PERR | AUART_STAT_FERR); |
471 | 470 | ||
472 | count = stat & AUART_STAT_RXCOUNT_MASK; | 471 | count = stat & AUART_STAT_RXCOUNT_MASK; |
473 | tty_insert_flip_string(tty, s->rx_dma_buf, count); | 472 | tty_insert_flip_string(port, s->rx_dma_buf, count); |
474 | 473 | ||
475 | writel(stat, s->port.membase + AUART_STAT); | 474 | writel(stat, s->port.membase + AUART_STAT); |
476 | tty_flip_buffer_push(tty); | 475 | tty_flip_buffer_push(port); |
477 | 476 | ||
478 | /* start the next DMA for RX. */ | 477 | /* start the next DMA for RX. */ |
479 | mxs_auart_dma_prep_rx(s); | 478 | mxs_auart_dma_prep_rx(s); |
@@ -552,7 +551,7 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s) | |||
552 | return 0; | 551 | return 0; |
553 | 552 | ||
554 | /* We do not get the right DMA channels. */ | 553 | /* We do not get the right DMA channels. */ |
555 | if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1) | 554 | if (s->dma_channel_rx == -1 || s->dma_channel_tx == -1) |
556 | return -EINVAL; | 555 | return -EINVAL; |
557 | 556 | ||
558 | /* init for RX */ | 557 | /* init for RX */ |
diff --git a/drivers/tty/serial/netx-serial.c b/drivers/tty/serial/netx-serial.c index d40da78e7c85..b9a40ed70be2 100644 --- a/drivers/tty/serial/netx-serial.c +++ b/drivers/tty/serial/netx-serial.c | |||
@@ -199,7 +199,6 @@ static void netx_txint(struct uart_port *port) | |||
199 | static void netx_rxint(struct uart_port *port) | 199 | static void netx_rxint(struct uart_port *port) |
200 | { | 200 | { |
201 | unsigned char rx, flg, status; | 201 | unsigned char rx, flg, status; |
202 | struct tty_struct *tty = port->state->port.tty; | ||
203 | 202 | ||
204 | while (!(readl(port->membase + UART_FR) & FR_RXFE)) { | 203 | while (!(readl(port->membase + UART_FR) & FR_RXFE)) { |
205 | rx = readl(port->membase + UART_DR); | 204 | rx = readl(port->membase + UART_DR); |
@@ -237,8 +236,7 @@ static void netx_rxint(struct uart_port *port) | |||
237 | uart_insert_char(port, status, SR_OE, rx, flg); | 236 | uart_insert_char(port, status, SR_OE, rx, flg); |
238 | } | 237 | } |
239 | 238 | ||
240 | tty_flip_buffer_push(tty); | 239 | tty_flip_buffer_push(&port->state->port); |
241 | return; | ||
242 | } | 240 | } |
243 | 241 | ||
244 | static irqreturn_t netx_int(int irq, void *dev_id) | 242 | static irqreturn_t netx_int(int irq, void *dev_id) |
diff --git a/drivers/tty/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c index dd4c31d1aee5..77287c54f331 100644 --- a/drivers/tty/serial/nwpserial.c +++ b/drivers/tty/serial/nwpserial.c | |||
@@ -128,7 +128,7 @@ static void nwpserial_config_port(struct uart_port *port, int flags) | |||
128 | static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) | 128 | static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) |
129 | { | 129 | { |
130 | struct nwpserial_port *up = dev_id; | 130 | struct nwpserial_port *up = dev_id; |
131 | struct tty_struct *tty = up->port.state->port.tty; | 131 | struct tty_port *port = &up->port.state->port; |
132 | irqreturn_t ret; | 132 | irqreturn_t ret; |
133 | unsigned int iir; | 133 | unsigned int iir; |
134 | unsigned char ch; | 134 | unsigned char ch; |
@@ -146,10 +146,10 @@ static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) | |||
146 | up->port.icount.rx++; | 146 | up->port.icount.rx++; |
147 | ch = dcr_read(up->dcr_host, UART_RX); | 147 | ch = dcr_read(up->dcr_host, UART_RX); |
148 | if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) | 148 | if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) |
149 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 149 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
150 | } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); | 150 | } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); |
151 | 151 | ||
152 | tty_flip_buffer_push(tty); | 152 | tty_flip_buffer_push(port); |
153 | ret = IRQ_HANDLED; | 153 | ret = IRQ_HANDLED; |
154 | 154 | ||
155 | /* clear interrupt */ | 155 | /* clear interrupt */ |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index e7cae1c2d7d2..d5874605682b 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/serial_reg.h> | 18 | #include <linux/serial_reg.h> |
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_irq.h> | 20 | #include <linux/of_irq.h> |
21 | #include <linux/of_serial.h> | ||
22 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
23 | #include <linux/nwpserial.h> | 22 | #include <linux/nwpserial.h> |
24 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
@@ -45,8 +44,10 @@ void tegra_serial_handle_break(struct uart_port *p) | |||
45 | udelay(1); | 44 | udelay(1); |
46 | } while (1); | 45 | } while (1); |
47 | } | 46 | } |
48 | /* FIXME remove this export when tegra finishes conversion to open firmware */ | 47 | #else |
49 | EXPORT_SYMBOL_GPL(tegra_serial_handle_break); | 48 | static inline void tegra_serial_handle_break(struct uart_port *port) |
49 | { | ||
50 | } | ||
50 | #endif | 51 | #endif |
51 | 52 | ||
52 | /* | 53 | /* |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 57d6b29c039c..4dc41408ecb7 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -59,6 +59,7 @@ | |||
59 | 59 | ||
60 | /* SCR register bitmasks */ | 60 | /* SCR register bitmasks */ |
61 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) | 61 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) |
62 | #define OMAP_UART_SCR_TX_TRIG_GRANU1_MASK (1 << 6) | ||
62 | #define OMAP_UART_SCR_TX_EMPTY (1 << 3) | 63 | #define OMAP_UART_SCR_TX_EMPTY (1 << 3) |
63 | 64 | ||
64 | /* FCR register bitmasks */ | 65 | /* FCR register bitmasks */ |
@@ -232,24 +233,42 @@ static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | |||
232 | } | 233 | } |
233 | 234 | ||
234 | /* | 235 | /* |
236 | * serial_omap_baud_is_mode16 - check if baud rate is MODE16X | ||
237 | * @port: uart port info | ||
238 | * @baud: baudrate for which mode needs to be determined | ||
239 | * | ||
240 | * Returns true if baud rate is MODE16X and false if MODE13X | ||
241 | * Original table in OMAP TRM named "UART Mode Baud Rates, Divisor Values, | ||
242 | * and Error Rates" determines modes not for all common baud rates. | ||
243 | * E.g. for 1000000 baud rate mode must be 16x, but according to that | ||
244 | * table it's determined as 13x. | ||
245 | */ | ||
246 | static bool | ||
247 | serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud) | ||
248 | { | ||
249 | unsigned int n13 = port->uartclk / (13 * baud); | ||
250 | unsigned int n16 = port->uartclk / (16 * baud); | ||
251 | int baudAbsDiff13 = baud - (port->uartclk / (13 * n13)); | ||
252 | int baudAbsDiff16 = baud - (port->uartclk / (16 * n16)); | ||
253 | if(baudAbsDiff13 < 0) | ||
254 | baudAbsDiff13 = -baudAbsDiff13; | ||
255 | if(baudAbsDiff16 < 0) | ||
256 | baudAbsDiff16 = -baudAbsDiff16; | ||
257 | |||
258 | return (baudAbsDiff13 > baudAbsDiff16); | ||
259 | } | ||
260 | |||
261 | /* | ||
235 | * serial_omap_get_divisor - calculate divisor value | 262 | * serial_omap_get_divisor - calculate divisor value |
236 | * @port: uart port info | 263 | * @port: uart port info |
237 | * @baud: baudrate for which divisor needs to be calculated. | 264 | * @baud: baudrate for which divisor needs to be calculated. |
238 | * | ||
239 | * We have written our own function to get the divisor so as to support | ||
240 | * 13x mode. 3Mbps Baudrate as an different divisor. | ||
241 | * Reference OMAP TRM Chapter 17: | ||
242 | * Table 17-1. UART Mode Baud Rates, Divisor Values, and Error Rates | ||
243 | * referring to oversampling - divisor value | ||
244 | * baudrate 460,800 to 3,686,400 all have divisor 13 | ||
245 | * except 3,000,000 which has divisor value 16 | ||
246 | */ | 265 | */ |
247 | static unsigned int | 266 | static unsigned int |
248 | serial_omap_get_divisor(struct uart_port *port, unsigned int baud) | 267 | serial_omap_get_divisor(struct uart_port *port, unsigned int baud) |
249 | { | 268 | { |
250 | unsigned int divisor; | 269 | unsigned int divisor; |
251 | 270 | ||
252 | if (baud > OMAP_MODE13X_SPEED && baud != 3000000) | 271 | if (!serial_omap_baud_is_mode16(port, baud)) |
253 | divisor = 13; | 272 | divisor = 13; |
254 | else | 273 | else |
255 | divisor = 16; | 274 | divisor = 16; |
@@ -302,9 +321,6 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) | |||
302 | struct circ_buf *xmit = &up->port.state->xmit; | 321 | struct circ_buf *xmit = &up->port.state->xmit; |
303 | int count; | 322 | int count; |
304 | 323 | ||
305 | if (!(lsr & UART_LSR_THRE)) | ||
306 | return; | ||
307 | |||
308 | if (up->port.x_char) { | 324 | if (up->port.x_char) { |
309 | serial_out(up, UART_TX, up->port.x_char); | 325 | serial_out(up, UART_TX, up->port.x_char); |
310 | up->port.icount.tx++; | 326 | up->port.icount.tx++; |
@@ -483,7 +499,6 @@ static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) | |||
483 | static irqreturn_t serial_omap_irq(int irq, void *dev_id) | 499 | static irqreturn_t serial_omap_irq(int irq, void *dev_id) |
484 | { | 500 | { |
485 | struct uart_omap_port *up = dev_id; | 501 | struct uart_omap_port *up = dev_id; |
486 | struct tty_struct *tty = up->port.state->port.tty; | ||
487 | unsigned int iir, lsr; | 502 | unsigned int iir, lsr; |
488 | unsigned int type; | 503 | unsigned int type; |
489 | irqreturn_t ret = IRQ_NONE; | 504 | irqreturn_t ret = IRQ_NONE; |
@@ -530,7 +545,7 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) | |||
530 | 545 | ||
531 | spin_unlock(&up->port.lock); | 546 | spin_unlock(&up->port.lock); |
532 | 547 | ||
533 | tty_flip_buffer_push(tty); | 548 | tty_flip_buffer_push(&up->port.state->port); |
534 | 549 | ||
535 | pm_runtime_mark_last_busy(up->dev); | 550 | pm_runtime_mark_last_busy(up->dev); |
536 | pm_runtime_put_autosuspend(up->dev); | 551 | pm_runtime_put_autosuspend(up->dev); |
@@ -776,6 +791,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
776 | cval |= UART_LCR_PARITY; | 791 | cval |= UART_LCR_PARITY; |
777 | if (!(termios->c_cflag & PARODD)) | 792 | if (!(termios->c_cflag & PARODD)) |
778 | cval |= UART_LCR_EPAR; | 793 | cval |= UART_LCR_EPAR; |
794 | if (termios->c_cflag & CMSPAR) | ||
795 | cval |= UART_LCR_SPAR; | ||
779 | 796 | ||
780 | /* | 797 | /* |
781 | * Ask the core to calculate the divisor for us. | 798 | * Ask the core to calculate the divisor for us. |
@@ -845,7 +862,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
845 | serial_out(up, UART_IER, up->ier); | 862 | serial_out(up, UART_IER, up->ier); |
846 | serial_out(up, UART_LCR, cval); /* reset DLAB */ | 863 | serial_out(up, UART_LCR, cval); /* reset DLAB */ |
847 | up->lcr = cval; | 864 | up->lcr = cval; |
848 | up->scr = OMAP_UART_SCR_TX_EMPTY; | 865 | up->scr = 0; |
849 | 866 | ||
850 | /* FIFOs and DMA Settings */ | 867 | /* FIFOs and DMA Settings */ |
851 | 868 | ||
@@ -869,8 +886,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
869 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); | 886 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); |
870 | /* FIFO ENABLE, DMA MODE */ | 887 | /* FIFO ENABLE, DMA MODE */ |
871 | 888 | ||
872 | up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; | ||
873 | |||
874 | /* Set receive FIFO threshold to 16 characters and | 889 | /* Set receive FIFO threshold to 16 characters and |
875 | * transmit FIFO threshold to 16 spaces | 890 | * transmit FIFO threshold to 16 spaces |
876 | */ | 891 | */ |
@@ -915,7 +930,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
915 | serial_out(up, UART_EFR, up->efr); | 930 | serial_out(up, UART_EFR, up->efr); |
916 | serial_out(up, UART_LCR, cval); | 931 | serial_out(up, UART_LCR, cval); |
917 | 932 | ||
918 | if (baud > 230400 && baud != 3000000) | 933 | if (!serial_omap_baud_is_mode16(port, baud)) |
919 | up->mdr1 = UART_OMAP_MDR1_13X_MODE; | 934 | up->mdr1 = UART_OMAP_MDR1_13X_MODE; |
920 | else | 935 | else |
921 | up->mdr1 = UART_OMAP_MDR1_16X_MODE; | 936 | up->mdr1 = UART_OMAP_MDR1_16X_MODE; |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 8318925fbf6b..7a6c989924b3 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -14,18 +14,21 @@ | |||
14 | *along with this program; if not, write to the Free Software | 14 | *along with this program; if not, write to the Free Software |
15 | *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 15 | *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
16 | */ | 16 | */ |
17 | #if defined(CONFIG_SERIAL_PCH_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
18 | #define SUPPORT_SYSRQ | ||
19 | #endif | ||
17 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
18 | #include <linux/serial_reg.h> | 21 | #include <linux/serial_reg.h> |
19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
20 | #include <linux/module.h> | 23 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
25 | #include <linux/console.h> | ||
22 | #include <linux/serial_core.h> | 26 | #include <linux/serial_core.h> |
23 | #include <linux/tty.h> | 27 | #include <linux/tty.h> |
24 | #include <linux/tty_flip.h> | 28 | #include <linux/tty_flip.h> |
25 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
26 | #include <linux/io.h> | 30 | #include <linux/io.h> |
27 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
28 | #include <linux/console.h> | ||
29 | #include <linux/nmi.h> | 32 | #include <linux/nmi.h> |
30 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
31 | 34 | ||
@@ -553,12 +556,26 @@ static int pch_uart_hal_read(struct eg20t_port *priv, unsigned char *buf, | |||
553 | { | 556 | { |
554 | int i; | 557 | int i; |
555 | u8 rbr, lsr; | 558 | u8 rbr, lsr; |
559 | struct uart_port *port = &priv->port; | ||
556 | 560 | ||
557 | lsr = ioread8(priv->membase + UART_LSR); | 561 | lsr = ioread8(priv->membase + UART_LSR); |
558 | for (i = 0, lsr = ioread8(priv->membase + UART_LSR); | 562 | for (i = 0, lsr = ioread8(priv->membase + UART_LSR); |
559 | i < rx_size && lsr & UART_LSR_DR; | 563 | i < rx_size && lsr & (UART_LSR_DR | UART_LSR_BI); |
560 | lsr = ioread8(priv->membase + UART_LSR)) { | 564 | lsr = ioread8(priv->membase + UART_LSR)) { |
561 | rbr = ioread8(priv->membase + PCH_UART_RBR); | 565 | rbr = ioread8(priv->membase + PCH_UART_RBR); |
566 | |||
567 | if (lsr & UART_LSR_BI) { | ||
568 | port->icount.brk++; | ||
569 | if (uart_handle_break(port)) | ||
570 | continue; | ||
571 | } | ||
572 | #ifdef SUPPORT_SYSRQ | ||
573 | if (port->sysrq) { | ||
574 | if (uart_handle_sysrq_char(port, rbr)) | ||
575 | continue; | ||
576 | } | ||
577 | #endif | ||
578 | |||
562 | buf[i++] = rbr; | 579 | buf[i++] = rbr; |
563 | } | 580 | } |
564 | return i; | 581 | return i; |
@@ -591,19 +608,11 @@ static void pch_uart_hal_set_break(struct eg20t_port *priv, int on) | |||
591 | static int push_rx(struct eg20t_port *priv, const unsigned char *buf, | 608 | static int push_rx(struct eg20t_port *priv, const unsigned char *buf, |
592 | int size) | 609 | int size) |
593 | { | 610 | { |
594 | struct uart_port *port; | 611 | struct uart_port *port = &priv->port; |
595 | struct tty_struct *tty; | 612 | struct tty_port *tport = &port->state->port; |
596 | |||
597 | port = &priv->port; | ||
598 | tty = tty_port_tty_get(&port->state->port); | ||
599 | if (!tty) { | ||
600 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | ||
601 | return -EBUSY; | ||
602 | } | ||
603 | 613 | ||
604 | tty_insert_flip_string(tty, buf, size); | 614 | tty_insert_flip_string(tport, buf, size); |
605 | tty_flip_buffer_push(tty); | 615 | tty_flip_buffer_push(tport); |
606 | tty_kref_put(tty); | ||
607 | 616 | ||
608 | return 0; | 617 | return 0; |
609 | } | 618 | } |
@@ -629,15 +638,16 @@ static int dma_push_rx(struct eg20t_port *priv, int size) | |||
629 | struct tty_struct *tty; | 638 | struct tty_struct *tty; |
630 | int room; | 639 | int room; |
631 | struct uart_port *port = &priv->port; | 640 | struct uart_port *port = &priv->port; |
641 | struct tty_port *tport = &port->state->port; | ||
632 | 642 | ||
633 | port = &priv->port; | 643 | port = &priv->port; |
634 | tty = tty_port_tty_get(&port->state->port); | 644 | tty = tty_port_tty_get(tport); |
635 | if (!tty) { | 645 | if (!tty) { |
636 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | 646 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); |
637 | return 0; | 647 | return 0; |
638 | } | 648 | } |
639 | 649 | ||
640 | room = tty_buffer_request_room(tty, size); | 650 | room = tty_buffer_request_room(tport, size); |
641 | 651 | ||
642 | if (room < size) | 652 | if (room < size) |
643 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | 653 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", |
@@ -645,7 +655,7 @@ static int dma_push_rx(struct eg20t_port *priv, int size) | |||
645 | if (!room) | 655 | if (!room) |
646 | return room; | 656 | return room; |
647 | 657 | ||
648 | tty_insert_flip_string(tty, sg_virt(&priv->sg_rx), size); | 658 | tty_insert_flip_string(tport, sg_virt(&priv->sg_rx), size); |
649 | 659 | ||
650 | port->icount.rx += room; | 660 | port->icount.rx += room; |
651 | tty_kref_put(tty); | 661 | tty_kref_put(tty); |
@@ -743,19 +753,12 @@ static void pch_dma_rx_complete(void *arg) | |||
743 | { | 753 | { |
744 | struct eg20t_port *priv = arg; | 754 | struct eg20t_port *priv = arg; |
745 | struct uart_port *port = &priv->port; | 755 | struct uart_port *port = &priv->port; |
746 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
747 | int count; | 756 | int count; |
748 | 757 | ||
749 | if (!tty) { | ||
750 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | ||
751 | return; | ||
752 | } | ||
753 | |||
754 | dma_sync_sg_for_cpu(port->dev, &priv->sg_rx, 1, DMA_FROM_DEVICE); | 758 | dma_sync_sg_for_cpu(port->dev, &priv->sg_rx, 1, DMA_FROM_DEVICE); |
755 | count = dma_push_rx(priv, priv->trigger_level); | 759 | count = dma_push_rx(priv, priv->trigger_level); |
756 | if (count) | 760 | if (count) |
757 | tty_flip_buffer_push(tty); | 761 | tty_flip_buffer_push(&port->state->port); |
758 | tty_kref_put(tty); | ||
759 | async_tx_ack(priv->desc_rx); | 762 | async_tx_ack(priv->desc_rx); |
760 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | | 763 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | |
761 | PCH_UART_HAL_RX_ERR_INT); | 764 | PCH_UART_HAL_RX_ERR_INT); |
@@ -1037,23 +1040,33 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) | |||
1037 | 1040 | ||
1038 | static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) | 1041 | static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) |
1039 | { | 1042 | { |
1040 | u8 fcr = ioread8(priv->membase + UART_FCR); | 1043 | struct uart_port *port = &priv->port; |
1041 | 1044 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | |
1042 | /* Reset FIFO */ | 1045 | char *error_msg[5] = {}; |
1043 | fcr |= UART_FCR_CLEAR_RCVR; | 1046 | int i = 0; |
1044 | iowrite8(fcr, priv->membase + UART_FCR); | ||
1045 | 1047 | ||
1046 | if (lsr & PCH_UART_LSR_ERR) | 1048 | if (lsr & PCH_UART_LSR_ERR) |
1047 | dev_err(&priv->pdev->dev, "Error data in FIFO\n"); | 1049 | error_msg[i++] = "Error data in FIFO\n"; |
1048 | 1050 | ||
1049 | if (lsr & UART_LSR_FE) | 1051 | if (lsr & UART_LSR_FE) { |
1050 | dev_err(&priv->pdev->dev, "Framing Error\n"); | 1052 | port->icount.frame++; |
1053 | error_msg[i++] = " Framing Error\n"; | ||
1054 | } | ||
1051 | 1055 | ||
1052 | if (lsr & UART_LSR_PE) | 1056 | if (lsr & UART_LSR_PE) { |
1053 | dev_err(&priv->pdev->dev, "Parity Error\n"); | 1057 | port->icount.parity++; |
1058 | error_msg[i++] = " Parity Error\n"; | ||
1059 | } | ||
1054 | 1060 | ||
1055 | if (lsr & UART_LSR_OE) | 1061 | if (lsr & UART_LSR_OE) { |
1056 | dev_err(&priv->pdev->dev, "Overrun Error\n"); | 1062 | port->icount.overrun++; |
1063 | error_msg[i++] = " Overrun Error\n"; | ||
1064 | } | ||
1065 | |||
1066 | if (tty == NULL) { | ||
1067 | for (i = 0; error_msg[i] != NULL; i++) | ||
1068 | dev_err(&priv->pdev->dev, error_msg[i]); | ||
1069 | } | ||
1057 | } | 1070 | } |
1058 | 1071 | ||
1059 | static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) | 1072 | static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) |
@@ -1564,7 +1577,8 @@ pch_console_write(struct console *co, const char *s, unsigned int count) | |||
1564 | 1577 | ||
1565 | local_irq_save(flags); | 1578 | local_irq_save(flags); |
1566 | if (priv->port.sysrq) { | 1579 | if (priv->port.sysrq) { |
1567 | spin_lock(&priv->lock); | 1580 | /* call to uart_handle_sysrq_char already took the priv lock */ |
1581 | priv_locked = 0; | ||
1568 | /* serial8250_handle_port() already took the port lock */ | 1582 | /* serial8250_handle_port() already took the port lock */ |
1569 | port_locked = 0; | 1583 | port_locked = 0; |
1570 | } else if (oops_in_progress) { | 1584 | } else if (oops_in_progress) { |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 333c8d012b0e..b1785f58b6e3 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -227,19 +227,19 @@ static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable) | |||
227 | write_zsreg(uap, R1, uap->curregs[1]); | 227 | write_zsreg(uap, R1, uap->curregs[1]); |
228 | } | 228 | } |
229 | 229 | ||
230 | static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | 230 | static bool pmz_receive_chars(struct uart_pmac_port *uap) |
231 | { | 231 | { |
232 | struct tty_struct *tty = NULL; | 232 | struct tty_port *port; |
233 | unsigned char ch, r1, drop, error, flag; | 233 | unsigned char ch, r1, drop, error, flag; |
234 | int loops = 0; | 234 | int loops = 0; |
235 | 235 | ||
236 | /* Sanity check, make sure the old bug is no longer happening */ | 236 | /* Sanity check, make sure the old bug is no longer happening */ |
237 | if (uap->port.state == NULL || uap->port.state->port.tty == NULL) { | 237 | if (uap->port.state == NULL) { |
238 | WARN_ON(1); | 238 | WARN_ON(1); |
239 | (void)read_zsdata(uap); | 239 | (void)read_zsdata(uap); |
240 | return NULL; | 240 | return false; |
241 | } | 241 | } |
242 | tty = uap->port.state->port.tty; | 242 | port = &uap->port.state->port; |
243 | 243 | ||
244 | while (1) { | 244 | while (1) { |
245 | error = 0; | 245 | error = 0; |
@@ -309,10 +309,10 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
309 | 309 | ||
310 | if (uap->port.ignore_status_mask == 0xff || | 310 | if (uap->port.ignore_status_mask == 0xff || |
311 | (r1 & uap->port.ignore_status_mask) == 0) { | 311 | (r1 & uap->port.ignore_status_mask) == 0) { |
312 | tty_insert_flip_char(tty, ch, flag); | 312 | tty_insert_flip_char(port, ch, flag); |
313 | } | 313 | } |
314 | if (r1 & Rx_OVR) | 314 | if (r1 & Rx_OVR) |
315 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 315 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
316 | next_char: | 316 | next_char: |
317 | /* We can get stuck in an infinite loop getting char 0 when the | 317 | /* We can get stuck in an infinite loop getting char 0 when the |
318 | * line is in a wrong HW state, we break that here. | 318 | * line is in a wrong HW state, we break that here. |
@@ -328,11 +328,11 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
328 | break; | 328 | break; |
329 | } | 329 | } |
330 | 330 | ||
331 | return tty; | 331 | return true; |
332 | flood: | 332 | flood: |
333 | pmz_interrupt_control(uap, 0); | 333 | pmz_interrupt_control(uap, 0); |
334 | pmz_error("pmz: rx irq flood !\n"); | 334 | pmz_error("pmz: rx irq flood !\n"); |
335 | return tty; | 335 | return true; |
336 | } | 336 | } |
337 | 337 | ||
338 | static void pmz_status_handle(struct uart_pmac_port *uap) | 338 | static void pmz_status_handle(struct uart_pmac_port *uap) |
@@ -453,7 +453,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
453 | struct uart_pmac_port *uap_a; | 453 | struct uart_pmac_port *uap_a; |
454 | struct uart_pmac_port *uap_b; | 454 | struct uart_pmac_port *uap_b; |
455 | int rc = IRQ_NONE; | 455 | int rc = IRQ_NONE; |
456 | struct tty_struct *tty; | 456 | bool push; |
457 | u8 r3; | 457 | u8 r3; |
458 | 458 | ||
459 | uap_a = pmz_get_port_A(uap); | 459 | uap_a = pmz_get_port_A(uap); |
@@ -466,7 +466,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
466 | pmz_debug("irq, r3: %x\n", r3); | 466 | pmz_debug("irq, r3: %x\n", r3); |
467 | #endif | 467 | #endif |
468 | /* Channel A */ | 468 | /* Channel A */ |
469 | tty = NULL; | 469 | push = false; |
470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
471 | if (!ZS_IS_OPEN(uap_a)) { | 471 | if (!ZS_IS_OPEN(uap_a)) { |
472 | pmz_debug("ChanA interrupt while not open !\n"); | 472 | pmz_debug("ChanA interrupt while not open !\n"); |
@@ -477,21 +477,21 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
477 | if (r3 & CHAEXT) | 477 | if (r3 & CHAEXT) |
478 | pmz_status_handle(uap_a); | 478 | pmz_status_handle(uap_a); |
479 | if (r3 & CHARxIP) | 479 | if (r3 & CHARxIP) |
480 | tty = pmz_receive_chars(uap_a); | 480 | push = pmz_receive_chars(uap_a); |
481 | if (r3 & CHATxIP) | 481 | if (r3 & CHATxIP) |
482 | pmz_transmit_chars(uap_a); | 482 | pmz_transmit_chars(uap_a); |
483 | rc = IRQ_HANDLED; | 483 | rc = IRQ_HANDLED; |
484 | } | 484 | } |
485 | skip_a: | 485 | skip_a: |
486 | spin_unlock(&uap_a->port.lock); | 486 | spin_unlock(&uap_a->port.lock); |
487 | if (tty != NULL) | 487 | if (push) |
488 | tty_flip_buffer_push(tty); | 488 | tty_flip_buffer_push(&uap->port.state->port); |
489 | 489 | ||
490 | if (!uap_b) | 490 | if (!uap_b) |
491 | goto out; | 491 | goto out; |
492 | 492 | ||
493 | spin_lock(&uap_b->port.lock); | 493 | spin_lock(&uap_b->port.lock); |
494 | tty = NULL; | 494 | push = false; |
495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
496 | if (!ZS_IS_OPEN(uap_b)) { | 496 | if (!ZS_IS_OPEN(uap_b)) { |
497 | pmz_debug("ChanB interrupt while not open !\n"); | 497 | pmz_debug("ChanB interrupt while not open !\n"); |
@@ -502,15 +502,15 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
502 | if (r3 & CHBEXT) | 502 | if (r3 & CHBEXT) |
503 | pmz_status_handle(uap_b); | 503 | pmz_status_handle(uap_b); |
504 | if (r3 & CHBRxIP) | 504 | if (r3 & CHBRxIP) |
505 | tty = pmz_receive_chars(uap_b); | 505 | push = pmz_receive_chars(uap_b); |
506 | if (r3 & CHBTxIP) | 506 | if (r3 & CHBTxIP) |
507 | pmz_transmit_chars(uap_b); | 507 | pmz_transmit_chars(uap_b); |
508 | rc = IRQ_HANDLED; | 508 | rc = IRQ_HANDLED; |
509 | } | 509 | } |
510 | skip_b: | 510 | skip_b: |
511 | spin_unlock(&uap_b->port.lock); | 511 | spin_unlock(&uap_b->port.lock); |
512 | if (tty != NULL) | 512 | if (push) |
513 | tty_flip_buffer_push(tty); | 513 | tty_flip_buffer_push(&uap->port.state->port); |
514 | 514 | ||
515 | out: | 515 | out: |
516 | return rc; | 516 | return rc; |
diff --git a/drivers/tty/serial/pnx8xxx_uart.c b/drivers/tty/serial/pnx8xxx_uart.c index 0aa75a97531c..7e277a5384a7 100644 --- a/drivers/tty/serial/pnx8xxx_uart.c +++ b/drivers/tty/serial/pnx8xxx_uart.c | |||
@@ -181,7 +181,6 @@ static void pnx8xxx_enable_ms(struct uart_port *port) | |||
181 | 181 | ||
182 | static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) | 182 | static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) |
183 | { | 183 | { |
184 | struct tty_struct *tty = sport->port.state->port.tty; | ||
185 | unsigned int status, ch, flg; | 184 | unsigned int status, ch, flg; |
186 | 185 | ||
187 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | | 186 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | |
@@ -238,7 +237,7 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) | |||
238 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | | 237 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | |
239 | ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); | 238 | ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); |
240 | } | 239 | } |
241 | tty_flip_buffer_push(tty); | 240 | tty_flip_buffer_push(&sport->port.state->port); |
242 | } | 241 | } |
243 | 242 | ||
244 | static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) | 243 | static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 2764828251f5..05f504e0c271 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
@@ -98,7 +98,6 @@ static void serial_pxa_stop_rx(struct uart_port *port) | |||
98 | 98 | ||
99 | static inline void receive_chars(struct uart_pxa_port *up, int *status) | 99 | static inline void receive_chars(struct uart_pxa_port *up, int *status) |
100 | { | 100 | { |
101 | struct tty_struct *tty = up->port.state->port.tty; | ||
102 | unsigned int ch, flag; | 101 | unsigned int ch, flag; |
103 | int max_count = 256; | 102 | int max_count = 256; |
104 | 103 | ||
@@ -168,7 +167,7 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) | |||
168 | ignore_char: | 167 | ignore_char: |
169 | *status = serial_in(up, UART_LSR); | 168 | *status = serial_in(up, UART_LSR); |
170 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 169 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
171 | tty_flip_buffer_push(tty); | 170 | tty_flip_buffer_push(&up->port.state->port); |
172 | 171 | ||
173 | /* work around Errata #20 according to | 172 | /* work around Errata #20 according to |
174 | * Intel(R) PXA27x Processor Family | 173 | * Intel(R) PXA27x Processor Family |
@@ -673,8 +672,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
673 | unsigned long flags; | 672 | unsigned long flags; |
674 | int locked = 1; | 673 | int locked = 1; |
675 | 674 | ||
676 | clk_prepare_enable(up->clk); | 675 | clk_enable(up->clk); |
677 | |||
678 | local_irq_save(flags); | 676 | local_irq_save(flags); |
679 | if (up->port.sysrq) | 677 | if (up->port.sysrq) |
680 | locked = 0; | 678 | locked = 0; |
@@ -701,8 +699,8 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
701 | if (locked) | 699 | if (locked) |
702 | spin_unlock(&up->port.lock); | 700 | spin_unlock(&up->port.lock); |
703 | local_irq_restore(flags); | 701 | local_irq_restore(flags); |
702 | clk_disable(up->clk); | ||
704 | 703 | ||
705 | clk_disable_unprepare(up->clk); | ||
706 | } | 704 | } |
707 | 705 | ||
708 | #ifdef CONFIG_CONSOLE_POLL | 706 | #ifdef CONFIG_CONSOLE_POLL |
@@ -899,6 +897,12 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
899 | goto err_free; | 897 | goto err_free; |
900 | } | 898 | } |
901 | 899 | ||
900 | ret = clk_prepare(sport->clk); | ||
901 | if (ret) { | ||
902 | clk_put(sport->clk); | ||
903 | goto err_free; | ||
904 | } | ||
905 | |||
902 | sport->port.type = PORT_PXA; | 906 | sport->port.type = PORT_PXA; |
903 | sport->port.iotype = UPIO_MEM; | 907 | sport->port.iotype = UPIO_MEM; |
904 | sport->port.mapbase = mmres->start; | 908 | sport->port.mapbase = mmres->start; |
@@ -930,6 +934,7 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
930 | return 0; | 934 | return 0; |
931 | 935 | ||
932 | err_clk: | 936 | err_clk: |
937 | clk_unprepare(sport->clk); | ||
933 | clk_put(sport->clk); | 938 | clk_put(sport->clk); |
934 | err_free: | 939 | err_free: |
935 | kfree(sport); | 940 | kfree(sport); |
@@ -943,6 +948,8 @@ static int serial_pxa_remove(struct platform_device *dev) | |||
943 | platform_set_drvdata(dev, NULL); | 948 | platform_set_drvdata(dev, NULL); |
944 | 949 | ||
945 | uart_remove_one_port(&serial_pxa_reg, &sport->port); | 950 | uart_remove_one_port(&serial_pxa_reg, &sport->port); |
951 | |||
952 | clk_unprepare(sport->clk); | ||
946 | clk_put(sport->clk); | 953 | clk_put(sport->clk); |
947 | kfree(sport); | 954 | kfree(sport); |
948 | 955 | ||
diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c new file mode 100644 index 000000000000..a314a943f124 --- /dev/null +++ b/drivers/tty/serial/rp2.c | |||
@@ -0,0 +1,885 @@ | |||
1 | /* | ||
2 | * Driver for Comtrol RocketPort EXPRESS/INFINITY cards | ||
3 | * | ||
4 | * Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com> | ||
5 | * | ||
6 | * Inspired by, and loosely based on: | ||
7 | * | ||
8 | * ar933x_uart.c | ||
9 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
10 | * | ||
11 | * rocketport_infinity_express-linux-1.20.tar.gz | ||
12 | * Copyright (C) 2004-2011 Comtrol, Inc. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify it | ||
15 | * under the terms of the GNU General Public License version 2 as published | ||
16 | * by the Free Software Foundation. | ||
17 | */ | ||
18 | |||
19 | #include <linux/bitops.h> | ||
20 | #include <linux/compiler.h> | ||
21 | #include <linux/completion.h> | ||
22 | #include <linux/console.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/firmware.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/log2.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/sysrq.h> | ||
37 | #include <linux/tty.h> | ||
38 | #include <linux/tty_flip.h> | ||
39 | #include <linux/types.h> | ||
40 | |||
41 | #define DRV_NAME "rp2" | ||
42 | |||
43 | #define RP2_FW_NAME "rp2.fw" | ||
44 | #define RP2_UCODE_BYTES 0x3f | ||
45 | |||
46 | #define PORTS_PER_ASIC 16 | ||
47 | #define ALL_PORTS_MASK (BIT(PORTS_PER_ASIC) - 1) | ||
48 | |||
49 | #define UART_CLOCK 44236800 | ||
50 | #define DEFAULT_BAUD_DIV (UART_CLOCK / (9600 * 16)) | ||
51 | #define FIFO_SIZE 512 | ||
52 | |||
53 | /* BAR0 registers */ | ||
54 | #define RP2_FPGA_CTL0 0x110 | ||
55 | #define RP2_FPGA_CTL1 0x11c | ||
56 | #define RP2_IRQ_MASK 0x1ec | ||
57 | #define RP2_IRQ_MASK_EN_m BIT(0) | ||
58 | #define RP2_IRQ_STATUS 0x1f0 | ||
59 | |||
60 | /* BAR1 registers */ | ||
61 | #define RP2_ASIC_SPACING 0x1000 | ||
62 | #define RP2_ASIC_OFFSET(i) ((i) << ilog2(RP2_ASIC_SPACING)) | ||
63 | |||
64 | #define RP2_PORT_BASE 0x000 | ||
65 | #define RP2_PORT_SPACING 0x040 | ||
66 | |||
67 | #define RP2_UCODE_BASE 0x400 | ||
68 | #define RP2_UCODE_SPACING 0x80 | ||
69 | |||
70 | #define RP2_CLK_PRESCALER 0xc00 | ||
71 | #define RP2_CH_IRQ_STAT 0xc04 | ||
72 | #define RP2_CH_IRQ_MASK 0xc08 | ||
73 | #define RP2_ASIC_IRQ 0xd00 | ||
74 | #define RP2_ASIC_IRQ_EN_m BIT(20) | ||
75 | #define RP2_GLOBAL_CMD 0xd0c | ||
76 | #define RP2_ASIC_CFG 0xd04 | ||
77 | |||
78 | /* port registers */ | ||
79 | #define RP2_DATA_DWORD 0x000 | ||
80 | |||
81 | #define RP2_DATA_BYTE 0x008 | ||
82 | #define RP2_DATA_BYTE_ERR_PARITY_m BIT(8) | ||
83 | #define RP2_DATA_BYTE_ERR_OVERRUN_m BIT(9) | ||
84 | #define RP2_DATA_BYTE_ERR_FRAMING_m BIT(10) | ||
85 | #define RP2_DATA_BYTE_BREAK_m BIT(11) | ||
86 | |||
87 | /* This lets uart_insert_char() drop bytes received on a !CREAD port */ | ||
88 | #define RP2_DUMMY_READ BIT(16) | ||
89 | |||
90 | #define RP2_DATA_BYTE_EXCEPTION_MASK (RP2_DATA_BYTE_ERR_PARITY_m | \ | ||
91 | RP2_DATA_BYTE_ERR_OVERRUN_m | \ | ||
92 | RP2_DATA_BYTE_ERR_FRAMING_m | \ | ||
93 | RP2_DATA_BYTE_BREAK_m) | ||
94 | |||
95 | #define RP2_RX_FIFO_COUNT 0x00c | ||
96 | #define RP2_TX_FIFO_COUNT 0x00e | ||
97 | |||
98 | #define RP2_CHAN_STAT 0x010 | ||
99 | #define RP2_CHAN_STAT_RXDATA_m BIT(0) | ||
100 | #define RP2_CHAN_STAT_DCD_m BIT(3) | ||
101 | #define RP2_CHAN_STAT_DSR_m BIT(4) | ||
102 | #define RP2_CHAN_STAT_CTS_m BIT(5) | ||
103 | #define RP2_CHAN_STAT_RI_m BIT(6) | ||
104 | #define RP2_CHAN_STAT_OVERRUN_m BIT(13) | ||
105 | #define RP2_CHAN_STAT_DSR_CHANGED_m BIT(16) | ||
106 | #define RP2_CHAN_STAT_CTS_CHANGED_m BIT(17) | ||
107 | #define RP2_CHAN_STAT_CD_CHANGED_m BIT(18) | ||
108 | #define RP2_CHAN_STAT_RI_CHANGED_m BIT(22) | ||
109 | #define RP2_CHAN_STAT_TXEMPTY_m BIT(25) | ||
110 | |||
111 | #define RP2_CHAN_STAT_MS_CHANGED_MASK (RP2_CHAN_STAT_DSR_CHANGED_m | \ | ||
112 | RP2_CHAN_STAT_CTS_CHANGED_m | \ | ||
113 | RP2_CHAN_STAT_CD_CHANGED_m | \ | ||
114 | RP2_CHAN_STAT_RI_CHANGED_m) | ||
115 | |||
116 | #define RP2_TXRX_CTL 0x014 | ||
117 | #define RP2_TXRX_CTL_MSRIRQ_m BIT(0) | ||
118 | #define RP2_TXRX_CTL_RXIRQ_m BIT(2) | ||
119 | #define RP2_TXRX_CTL_RX_TRIG_s 3 | ||
120 | #define RP2_TXRX_CTL_RX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
121 | #define RP2_TXRX_CTL_RX_TRIG_1 (0x1 << RP2_TXRX_CTL_RX_TRIG_s) | ||
122 | #define RP2_TXRX_CTL_RX_TRIG_256 (0x2 << RP2_TXRX_CTL_RX_TRIG_s) | ||
123 | #define RP2_TXRX_CTL_RX_TRIG_448 (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
124 | #define RP2_TXRX_CTL_RX_EN_m BIT(5) | ||
125 | #define RP2_TXRX_CTL_RTSFLOW_m BIT(6) | ||
126 | #define RP2_TXRX_CTL_DTRFLOW_m BIT(7) | ||
127 | #define RP2_TXRX_CTL_TX_TRIG_s 16 | ||
128 | #define RP2_TXRX_CTL_TX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
129 | #define RP2_TXRX_CTL_DSRFLOW_m BIT(18) | ||
130 | #define RP2_TXRX_CTL_TXIRQ_m BIT(19) | ||
131 | #define RP2_TXRX_CTL_CTSFLOW_m BIT(23) | ||
132 | #define RP2_TXRX_CTL_TX_EN_m BIT(24) | ||
133 | #define RP2_TXRX_CTL_RTS_m BIT(25) | ||
134 | #define RP2_TXRX_CTL_DTR_m BIT(26) | ||
135 | #define RP2_TXRX_CTL_LOOP_m BIT(27) | ||
136 | #define RP2_TXRX_CTL_BREAK_m BIT(28) | ||
137 | #define RP2_TXRX_CTL_CMSPAR_m BIT(29) | ||
138 | #define RP2_TXRX_CTL_nPARODD_m BIT(30) | ||
139 | #define RP2_TXRX_CTL_PARENB_m BIT(31) | ||
140 | |||
141 | #define RP2_UART_CTL 0x018 | ||
142 | #define RP2_UART_CTL_MODE_s 0 | ||
143 | #define RP2_UART_CTL_MODE_m (0x7 << RP2_UART_CTL_MODE_s) | ||
144 | #define RP2_UART_CTL_MODE_rs232 (0x1 << RP2_UART_CTL_MODE_s) | ||
145 | #define RP2_UART_CTL_FLUSH_RX_m BIT(3) | ||
146 | #define RP2_UART_CTL_FLUSH_TX_m BIT(4) | ||
147 | #define RP2_UART_CTL_RESET_CH_m BIT(5) | ||
148 | #define RP2_UART_CTL_XMIT_EN_m BIT(6) | ||
149 | #define RP2_UART_CTL_DATABITS_s 8 | ||
150 | #define RP2_UART_CTL_DATABITS_m (0x3 << RP2_UART_CTL_DATABITS_s) | ||
151 | #define RP2_UART_CTL_DATABITS_8 (0x3 << RP2_UART_CTL_DATABITS_s) | ||
152 | #define RP2_UART_CTL_DATABITS_7 (0x2 << RP2_UART_CTL_DATABITS_s) | ||
153 | #define RP2_UART_CTL_DATABITS_6 (0x1 << RP2_UART_CTL_DATABITS_s) | ||
154 | #define RP2_UART_CTL_DATABITS_5 (0x0 << RP2_UART_CTL_DATABITS_s) | ||
155 | #define RP2_UART_CTL_STOPBITS_m BIT(10) | ||
156 | |||
157 | #define RP2_BAUD 0x01c | ||
158 | |||
159 | /* ucode registers */ | ||
160 | #define RP2_TX_SWFLOW 0x02 | ||
161 | #define RP2_TX_SWFLOW_ena 0x81 | ||
162 | #define RP2_TX_SWFLOW_dis 0x9d | ||
163 | |||
164 | #define RP2_RX_SWFLOW 0x0c | ||
165 | #define RP2_RX_SWFLOW_ena 0x81 | ||
166 | #define RP2_RX_SWFLOW_dis 0x8d | ||
167 | |||
168 | #define RP2_RX_FIFO 0x37 | ||
169 | #define RP2_RX_FIFO_ena 0x08 | ||
170 | #define RP2_RX_FIFO_dis 0x81 | ||
171 | |||
172 | static struct uart_driver rp2_uart_driver = { | ||
173 | .owner = THIS_MODULE, | ||
174 | .driver_name = DRV_NAME, | ||
175 | .dev_name = "ttyRP", | ||
176 | .nr = CONFIG_SERIAL_RP2_NR_UARTS, | ||
177 | }; | ||
178 | |||
179 | struct rp2_card; | ||
180 | |||
181 | struct rp2_uart_port { | ||
182 | struct uart_port port; | ||
183 | int idx; | ||
184 | int ignore_rx; | ||
185 | struct rp2_card *card; | ||
186 | void __iomem *asic_base; | ||
187 | void __iomem *base; | ||
188 | void __iomem *ucode; | ||
189 | }; | ||
190 | |||
191 | struct rp2_card { | ||
192 | struct pci_dev *pdev; | ||
193 | struct rp2_uart_port *ports; | ||
194 | int n_ports; | ||
195 | int initialized_ports; | ||
196 | int minor_start; | ||
197 | int smpte; | ||
198 | void __iomem *bar0; | ||
199 | void __iomem *bar1; | ||
200 | spinlock_t card_lock; | ||
201 | struct completion fw_loaded; | ||
202 | }; | ||
203 | |||
204 | #define RP_ID(prod) PCI_VDEVICE(RP, (prod)) | ||
205 | #define RP_CAP(ports, smpte) (((ports) << 8) | ((smpte) << 0)) | ||
206 | |||
207 | static inline void rp2_decode_cap(const struct pci_device_id *id, | ||
208 | int *ports, int *smpte) | ||
209 | { | ||
210 | *ports = id->driver_data >> 8; | ||
211 | *smpte = id->driver_data & 0xff; | ||
212 | } | ||
213 | |||
214 | static DEFINE_SPINLOCK(rp2_minor_lock); | ||
215 | static int rp2_minor_next; | ||
216 | |||
217 | static int rp2_alloc_ports(int n_ports) | ||
218 | { | ||
219 | int ret = -ENOSPC; | ||
220 | |||
221 | spin_lock(&rp2_minor_lock); | ||
222 | if (rp2_minor_next + n_ports <= CONFIG_SERIAL_RP2_NR_UARTS) { | ||
223 | /* sorry, no support for hot unplugging individual cards */ | ||
224 | ret = rp2_minor_next; | ||
225 | rp2_minor_next += n_ports; | ||
226 | } | ||
227 | spin_unlock(&rp2_minor_lock); | ||
228 | |||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | static inline struct rp2_uart_port *port_to_up(struct uart_port *port) | ||
233 | { | ||
234 | return container_of(port, struct rp2_uart_port, port); | ||
235 | } | ||
236 | |||
237 | static void rp2_rmw(struct rp2_uart_port *up, int reg, | ||
238 | u32 clr_bits, u32 set_bits) | ||
239 | { | ||
240 | u32 tmp = readl(up->base + reg); | ||
241 | tmp &= ~clr_bits; | ||
242 | tmp |= set_bits; | ||
243 | writel(tmp, up->base + reg); | ||
244 | } | ||
245 | |||
246 | static void rp2_rmw_clr(struct rp2_uart_port *up, int reg, u32 val) | ||
247 | { | ||
248 | rp2_rmw(up, reg, val, 0); | ||
249 | } | ||
250 | |||
251 | static void rp2_rmw_set(struct rp2_uart_port *up, int reg, u32 val) | ||
252 | { | ||
253 | rp2_rmw(up, reg, 0, val); | ||
254 | } | ||
255 | |||
256 | static void rp2_mask_ch_irq(struct rp2_uart_port *up, int ch_num, | ||
257 | int is_enabled) | ||
258 | { | ||
259 | unsigned long flags, irq_mask; | ||
260 | |||
261 | spin_lock_irqsave(&up->card->card_lock, flags); | ||
262 | |||
263 | irq_mask = readl(up->asic_base + RP2_CH_IRQ_MASK); | ||
264 | if (is_enabled) | ||
265 | irq_mask &= ~BIT(ch_num); | ||
266 | else | ||
267 | irq_mask |= BIT(ch_num); | ||
268 | writel(irq_mask, up->asic_base + RP2_CH_IRQ_MASK); | ||
269 | |||
270 | spin_unlock_irqrestore(&up->card->card_lock, flags); | ||
271 | } | ||
272 | |||
273 | static unsigned int rp2_uart_tx_empty(struct uart_port *port) | ||
274 | { | ||
275 | struct rp2_uart_port *up = port_to_up(port); | ||
276 | unsigned long tx_fifo_bytes, flags; | ||
277 | |||
278 | /* | ||
279 | * This should probably check the transmitter, not the FIFO. | ||
280 | * But the TXEMPTY bit doesn't seem to work unless the TX IRQ is | ||
281 | * enabled. | ||
282 | */ | ||
283 | spin_lock_irqsave(&up->port.lock, flags); | ||
284 | tx_fifo_bytes = readw(up->base + RP2_TX_FIFO_COUNT); | ||
285 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
286 | |||
287 | return tx_fifo_bytes ? 0 : TIOCSER_TEMT; | ||
288 | } | ||
289 | |||
290 | static unsigned int rp2_uart_get_mctrl(struct uart_port *port) | ||
291 | { | ||
292 | struct rp2_uart_port *up = port_to_up(port); | ||
293 | u32 status; | ||
294 | |||
295 | status = readl(up->base + RP2_CHAN_STAT); | ||
296 | return ((status & RP2_CHAN_STAT_DCD_m) ? TIOCM_CAR : 0) | | ||
297 | ((status & RP2_CHAN_STAT_DSR_m) ? TIOCM_DSR : 0) | | ||
298 | ((status & RP2_CHAN_STAT_CTS_m) ? TIOCM_CTS : 0) | | ||
299 | ((status & RP2_CHAN_STAT_RI_m) ? TIOCM_RI : 0); | ||
300 | } | ||
301 | |||
302 | static void rp2_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
303 | { | ||
304 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, | ||
305 | RP2_TXRX_CTL_DTR_m | RP2_TXRX_CTL_RTS_m | RP2_TXRX_CTL_LOOP_m, | ||
306 | ((mctrl & TIOCM_DTR) ? RP2_TXRX_CTL_DTR_m : 0) | | ||
307 | ((mctrl & TIOCM_RTS) ? RP2_TXRX_CTL_RTS_m : 0) | | ||
308 | ((mctrl & TIOCM_LOOP) ? RP2_TXRX_CTL_LOOP_m : 0)); | ||
309 | } | ||
310 | |||
311 | static void rp2_uart_start_tx(struct uart_port *port) | ||
312 | { | ||
313 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); | ||
314 | } | ||
315 | |||
316 | static void rp2_uart_stop_tx(struct uart_port *port) | ||
317 | { | ||
318 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); | ||
319 | } | ||
320 | |||
321 | static void rp2_uart_stop_rx(struct uart_port *port) | ||
322 | { | ||
323 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_RXIRQ_m); | ||
324 | } | ||
325 | |||
326 | static void rp2_uart_break_ctl(struct uart_port *port, int break_state) | ||
327 | { | ||
328 | unsigned long flags; | ||
329 | |||
330 | spin_lock_irqsave(&port->lock, flags); | ||
331 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_BREAK_m, | ||
332 | break_state ? RP2_TXRX_CTL_BREAK_m : 0); | ||
333 | spin_unlock_irqrestore(&port->lock, flags); | ||
334 | } | ||
335 | |||
336 | static void rp2_uart_enable_ms(struct uart_port *port) | ||
337 | { | ||
338 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m); | ||
339 | } | ||
340 | |||
341 | static void __rp2_uart_set_termios(struct rp2_uart_port *up, | ||
342 | unsigned long cfl, | ||
343 | unsigned long ifl, | ||
344 | unsigned int baud_div) | ||
345 | { | ||
346 | /* baud rate divisor (calculated elsewhere). 0 = divide-by-1 */ | ||
347 | writew(baud_div - 1, up->base + RP2_BAUD); | ||
348 | |||
349 | /* data bits and stop bits */ | ||
350 | rp2_rmw(up, RP2_UART_CTL, | ||
351 | RP2_UART_CTL_STOPBITS_m | RP2_UART_CTL_DATABITS_m, | ||
352 | ((cfl & CSTOPB) ? RP2_UART_CTL_STOPBITS_m : 0) | | ||
353 | (((cfl & CSIZE) == CS8) ? RP2_UART_CTL_DATABITS_8 : 0) | | ||
354 | (((cfl & CSIZE) == CS7) ? RP2_UART_CTL_DATABITS_7 : 0) | | ||
355 | (((cfl & CSIZE) == CS6) ? RP2_UART_CTL_DATABITS_6 : 0) | | ||
356 | (((cfl & CSIZE) == CS5) ? RP2_UART_CTL_DATABITS_5 : 0)); | ||
357 | |||
358 | /* parity and hardware flow control */ | ||
359 | rp2_rmw(up, RP2_TXRX_CTL, | ||
360 | RP2_TXRX_CTL_PARENB_m | RP2_TXRX_CTL_nPARODD_m | | ||
361 | RP2_TXRX_CTL_CMSPAR_m | RP2_TXRX_CTL_DTRFLOW_m | | ||
362 | RP2_TXRX_CTL_DSRFLOW_m | RP2_TXRX_CTL_RTSFLOW_m | | ||
363 | RP2_TXRX_CTL_CTSFLOW_m, | ||
364 | ((cfl & PARENB) ? RP2_TXRX_CTL_PARENB_m : 0) | | ||
365 | ((cfl & PARODD) ? 0 : RP2_TXRX_CTL_nPARODD_m) | | ||
366 | ((cfl & CMSPAR) ? RP2_TXRX_CTL_CMSPAR_m : 0) | | ||
367 | ((cfl & CRTSCTS) ? (RP2_TXRX_CTL_RTSFLOW_m | | ||
368 | RP2_TXRX_CTL_CTSFLOW_m) : 0)); | ||
369 | |||
370 | /* XON/XOFF software flow control */ | ||
371 | writeb((ifl & IXON) ? RP2_TX_SWFLOW_ena : RP2_TX_SWFLOW_dis, | ||
372 | up->ucode + RP2_TX_SWFLOW); | ||
373 | writeb((ifl & IXOFF) ? RP2_RX_SWFLOW_ena : RP2_RX_SWFLOW_dis, | ||
374 | up->ucode + RP2_RX_SWFLOW); | ||
375 | } | ||
376 | |||
377 | static void rp2_uart_set_termios(struct uart_port *port, | ||
378 | struct ktermios *new, | ||
379 | struct ktermios *old) | ||
380 | { | ||
381 | struct rp2_uart_port *up = port_to_up(port); | ||
382 | unsigned long flags; | ||
383 | unsigned int baud, baud_div; | ||
384 | |||
385 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | ||
386 | baud_div = uart_get_divisor(port, baud); | ||
387 | |||
388 | if (tty_termios_baud_rate(new)) | ||
389 | tty_termios_encode_baud_rate(new, baud, baud); | ||
390 | |||
391 | spin_lock_irqsave(&port->lock, flags); | ||
392 | |||
393 | /* ignore all characters if CREAD is not set */ | ||
394 | port->ignore_status_mask = (new->c_cflag & CREAD) ? 0 : RP2_DUMMY_READ; | ||
395 | |||
396 | __rp2_uart_set_termios(up, new->c_cflag, new->c_iflag, baud_div); | ||
397 | uart_update_timeout(port, new->c_cflag, baud); | ||
398 | |||
399 | spin_unlock_irqrestore(&port->lock, flags); | ||
400 | } | ||
401 | |||
402 | static void rp2_rx_chars(struct rp2_uart_port *up) | ||
403 | { | ||
404 | u16 bytes = readw(up->base + RP2_RX_FIFO_COUNT); | ||
405 | struct tty_port *port = &up->port.state->port; | ||
406 | |||
407 | for (; bytes != 0; bytes--) { | ||
408 | u32 byte = readw(up->base + RP2_DATA_BYTE) | RP2_DUMMY_READ; | ||
409 | char ch = byte & 0xff; | ||
410 | |||
411 | if (likely(!(byte & RP2_DATA_BYTE_EXCEPTION_MASK))) { | ||
412 | if (!uart_handle_sysrq_char(&up->port, ch)) | ||
413 | uart_insert_char(&up->port, byte, 0, ch, | ||
414 | TTY_NORMAL); | ||
415 | } else { | ||
416 | char flag = TTY_NORMAL; | ||
417 | |||
418 | if (byte & RP2_DATA_BYTE_BREAK_m) | ||
419 | flag = TTY_BREAK; | ||
420 | else if (byte & RP2_DATA_BYTE_ERR_FRAMING_m) | ||
421 | flag = TTY_FRAME; | ||
422 | else if (byte & RP2_DATA_BYTE_ERR_PARITY_m) | ||
423 | flag = TTY_PARITY; | ||
424 | uart_insert_char(&up->port, byte, | ||
425 | RP2_DATA_BYTE_ERR_OVERRUN_m, ch, flag); | ||
426 | } | ||
427 | up->port.icount.rx++; | ||
428 | } | ||
429 | |||
430 | tty_flip_buffer_push(port); | ||
431 | } | ||
432 | |||
433 | static void rp2_tx_chars(struct rp2_uart_port *up) | ||
434 | { | ||
435 | u16 max_tx = FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT); | ||
436 | struct circ_buf *xmit = &up->port.state->xmit; | ||
437 | |||
438 | if (uart_tx_stopped(&up->port)) { | ||
439 | rp2_uart_stop_tx(&up->port); | ||
440 | return; | ||
441 | } | ||
442 | |||
443 | for (; max_tx != 0; max_tx--) { | ||
444 | if (up->port.x_char) { | ||
445 | writeb(up->port.x_char, up->base + RP2_DATA_BYTE); | ||
446 | up->port.x_char = 0; | ||
447 | up->port.icount.tx++; | ||
448 | continue; | ||
449 | } | ||
450 | if (uart_circ_empty(xmit)) { | ||
451 | rp2_uart_stop_tx(&up->port); | ||
452 | break; | ||
453 | } | ||
454 | writeb(xmit->buf[xmit->tail], up->base + RP2_DATA_BYTE); | ||
455 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
456 | up->port.icount.tx++; | ||
457 | } | ||
458 | |||
459 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
460 | uart_write_wakeup(&up->port); | ||
461 | } | ||
462 | |||
463 | static void rp2_ch_interrupt(struct rp2_uart_port *up) | ||
464 | { | ||
465 | u32 status; | ||
466 | |||
467 | spin_lock(&up->port.lock); | ||
468 | |||
469 | /* | ||
470 | * The IRQ status bits are clear-on-write. Other status bits in | ||
471 | * this register aren't, so it's harmless to write to them. | ||
472 | */ | ||
473 | status = readl(up->base + RP2_CHAN_STAT); | ||
474 | writel(status, up->base + RP2_CHAN_STAT); | ||
475 | |||
476 | if (status & RP2_CHAN_STAT_RXDATA_m) | ||
477 | rp2_rx_chars(up); | ||
478 | if (status & RP2_CHAN_STAT_TXEMPTY_m) | ||
479 | rp2_tx_chars(up); | ||
480 | if (status & RP2_CHAN_STAT_MS_CHANGED_MASK) | ||
481 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | ||
482 | |||
483 | spin_unlock(&up->port.lock); | ||
484 | } | ||
485 | |||
486 | static int rp2_asic_interrupt(struct rp2_card *card, unsigned int asic_id) | ||
487 | { | ||
488 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); | ||
489 | int ch, handled = 0; | ||
490 | unsigned long status = readl(base + RP2_CH_IRQ_STAT) & | ||
491 | ~readl(base + RP2_CH_IRQ_MASK); | ||
492 | |||
493 | for_each_set_bit(ch, &status, PORTS_PER_ASIC) { | ||
494 | rp2_ch_interrupt(&card->ports[ch]); | ||
495 | handled++; | ||
496 | } | ||
497 | return handled; | ||
498 | } | ||
499 | |||
500 | static irqreturn_t rp2_uart_interrupt(int irq, void *dev_id) | ||
501 | { | ||
502 | struct rp2_card *card = dev_id; | ||
503 | int handled; | ||
504 | |||
505 | handled = rp2_asic_interrupt(card, 0); | ||
506 | if (card->n_ports >= PORTS_PER_ASIC) | ||
507 | handled += rp2_asic_interrupt(card, 1); | ||
508 | |||
509 | return handled ? IRQ_HANDLED : IRQ_NONE; | ||
510 | } | ||
511 | |||
512 | static inline void rp2_flush_fifos(struct rp2_uart_port *up) | ||
513 | { | ||
514 | rp2_rmw_set(up, RP2_UART_CTL, | ||
515 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); | ||
516 | readl(up->base + RP2_UART_CTL); | ||
517 | udelay(10); | ||
518 | rp2_rmw_clr(up, RP2_UART_CTL, | ||
519 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); | ||
520 | } | ||
521 | |||
522 | static int rp2_uart_startup(struct uart_port *port) | ||
523 | { | ||
524 | struct rp2_uart_port *up = port_to_up(port); | ||
525 | |||
526 | rp2_flush_fifos(up); | ||
527 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m, RP2_TXRX_CTL_RXIRQ_m); | ||
528 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_RX_TRIG_m, | ||
529 | RP2_TXRX_CTL_RX_TRIG_1); | ||
530 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); | ||
531 | rp2_mask_ch_irq(up, up->idx, 1); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static void rp2_uart_shutdown(struct uart_port *port) | ||
537 | { | ||
538 | struct rp2_uart_port *up = port_to_up(port); | ||
539 | unsigned long flags; | ||
540 | |||
541 | rp2_uart_break_ctl(port, 0); | ||
542 | |||
543 | spin_lock_irqsave(&port->lock, flags); | ||
544 | rp2_mask_ch_irq(up, up->idx, 0); | ||
545 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); | ||
546 | spin_unlock_irqrestore(&port->lock, flags); | ||
547 | } | ||
548 | |||
549 | static const char *rp2_uart_type(struct uart_port *port) | ||
550 | { | ||
551 | return (port->type == PORT_RP2) ? "RocketPort 2 UART" : NULL; | ||
552 | } | ||
553 | |||
554 | static void rp2_uart_release_port(struct uart_port *port) | ||
555 | { | ||
556 | /* Nothing to release ... */ | ||
557 | } | ||
558 | |||
559 | static int rp2_uart_request_port(struct uart_port *port) | ||
560 | { | ||
561 | /* UARTs always present */ | ||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static void rp2_uart_config_port(struct uart_port *port, int flags) | ||
566 | { | ||
567 | if (flags & UART_CONFIG_TYPE) | ||
568 | port->type = PORT_RP2; | ||
569 | } | ||
570 | |||
571 | static int rp2_uart_verify_port(struct uart_port *port, | ||
572 | struct serial_struct *ser) | ||
573 | { | ||
574 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_RP2) | ||
575 | return -EINVAL; | ||
576 | |||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | static const struct uart_ops rp2_uart_ops = { | ||
581 | .tx_empty = rp2_uart_tx_empty, | ||
582 | .set_mctrl = rp2_uart_set_mctrl, | ||
583 | .get_mctrl = rp2_uart_get_mctrl, | ||
584 | .stop_tx = rp2_uart_stop_tx, | ||
585 | .start_tx = rp2_uart_start_tx, | ||
586 | .stop_rx = rp2_uart_stop_rx, | ||
587 | .enable_ms = rp2_uart_enable_ms, | ||
588 | .break_ctl = rp2_uart_break_ctl, | ||
589 | .startup = rp2_uart_startup, | ||
590 | .shutdown = rp2_uart_shutdown, | ||
591 | .set_termios = rp2_uart_set_termios, | ||
592 | .type = rp2_uart_type, | ||
593 | .release_port = rp2_uart_release_port, | ||
594 | .request_port = rp2_uart_request_port, | ||
595 | .config_port = rp2_uart_config_port, | ||
596 | .verify_port = rp2_uart_verify_port, | ||
597 | }; | ||
598 | |||
599 | static void rp2_reset_asic(struct rp2_card *card, unsigned int asic_id) | ||
600 | { | ||
601 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); | ||
602 | u32 clk_cfg; | ||
603 | |||
604 | writew(1, base + RP2_GLOBAL_CMD); | ||
605 | readw(base + RP2_GLOBAL_CMD); | ||
606 | msleep(100); | ||
607 | writel(0, base + RP2_CLK_PRESCALER); | ||
608 | |||
609 | /* TDM clock configuration */ | ||
610 | clk_cfg = readw(base + RP2_ASIC_CFG); | ||
611 | clk_cfg = (clk_cfg & ~BIT(8)) | BIT(9); | ||
612 | writew(clk_cfg, base + RP2_ASIC_CFG); | ||
613 | |||
614 | /* IRQ routing */ | ||
615 | writel(ALL_PORTS_MASK, base + RP2_CH_IRQ_MASK); | ||
616 | writel(RP2_ASIC_IRQ_EN_m, base + RP2_ASIC_IRQ); | ||
617 | } | ||
618 | |||
619 | static void rp2_init_card(struct rp2_card *card) | ||
620 | { | ||
621 | writel(4, card->bar0 + RP2_FPGA_CTL0); | ||
622 | writel(0, card->bar0 + RP2_FPGA_CTL1); | ||
623 | |||
624 | rp2_reset_asic(card, 0); | ||
625 | if (card->n_ports >= PORTS_PER_ASIC) | ||
626 | rp2_reset_asic(card, 1); | ||
627 | |||
628 | writel(RP2_IRQ_MASK_EN_m, card->bar0 + RP2_IRQ_MASK); | ||
629 | } | ||
630 | |||
631 | static void rp2_init_port(struct rp2_uart_port *up, const struct firmware *fw) | ||
632 | { | ||
633 | int i; | ||
634 | |||
635 | writel(RP2_UART_CTL_RESET_CH_m, up->base + RP2_UART_CTL); | ||
636 | readl(up->base + RP2_UART_CTL); | ||
637 | udelay(1); | ||
638 | |||
639 | writel(0, up->base + RP2_TXRX_CTL); | ||
640 | writel(0, up->base + RP2_UART_CTL); | ||
641 | readl(up->base + RP2_UART_CTL); | ||
642 | udelay(1); | ||
643 | |||
644 | rp2_flush_fifos(up); | ||
645 | |||
646 | for (i = 0; i < min_t(int, fw->size, RP2_UCODE_BYTES); i++) | ||
647 | writeb(fw->data[i], up->ucode + i); | ||
648 | |||
649 | __rp2_uart_set_termios(up, CS8 | CREAD | CLOCAL, 0, DEFAULT_BAUD_DIV); | ||
650 | rp2_uart_set_mctrl(&up->port, 0); | ||
651 | |||
652 | writeb(RP2_RX_FIFO_ena, up->ucode + RP2_RX_FIFO); | ||
653 | rp2_rmw(up, RP2_UART_CTL, RP2_UART_CTL_MODE_m, | ||
654 | RP2_UART_CTL_XMIT_EN_m | RP2_UART_CTL_MODE_rs232); | ||
655 | rp2_rmw_set(up, RP2_TXRX_CTL, | ||
656 | RP2_TXRX_CTL_TX_EN_m | RP2_TXRX_CTL_RX_EN_m); | ||
657 | } | ||
658 | |||
659 | static void rp2_remove_ports(struct rp2_card *card) | ||
660 | { | ||
661 | int i; | ||
662 | |||
663 | for (i = 0; i < card->initialized_ports; i++) | ||
664 | uart_remove_one_port(&rp2_uart_driver, &card->ports[i].port); | ||
665 | card->initialized_ports = 0; | ||
666 | } | ||
667 | |||
668 | static void rp2_fw_cb(const struct firmware *fw, void *context) | ||
669 | { | ||
670 | struct rp2_card *card = context; | ||
671 | resource_size_t phys_base; | ||
672 | int i, rc = -ENOENT; | ||
673 | |||
674 | if (!fw) { | ||
675 | dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n", | ||
676 | RP2_FW_NAME); | ||
677 | goto no_fw; | ||
678 | } | ||
679 | |||
680 | phys_base = pci_resource_start(card->pdev, 1); | ||
681 | |||
682 | for (i = 0; i < card->n_ports; i++) { | ||
683 | struct rp2_uart_port *rp = &card->ports[i]; | ||
684 | struct uart_port *p; | ||
685 | int j = (unsigned)i % PORTS_PER_ASIC; | ||
686 | |||
687 | rp->asic_base = card->bar1; | ||
688 | rp->base = card->bar1 + RP2_PORT_BASE + j*RP2_PORT_SPACING; | ||
689 | rp->ucode = card->bar1 + RP2_UCODE_BASE + j*RP2_UCODE_SPACING; | ||
690 | rp->card = card; | ||
691 | rp->idx = j; | ||
692 | |||
693 | p = &rp->port; | ||
694 | p->line = card->minor_start + i; | ||
695 | p->dev = &card->pdev->dev; | ||
696 | p->type = PORT_RP2; | ||
697 | p->iotype = UPIO_MEM32; | ||
698 | p->uartclk = UART_CLOCK; | ||
699 | p->regshift = 2; | ||
700 | p->fifosize = FIFO_SIZE; | ||
701 | p->ops = &rp2_uart_ops; | ||
702 | p->irq = card->pdev->irq; | ||
703 | p->membase = rp->base; | ||
704 | p->mapbase = phys_base + RP2_PORT_BASE + j*RP2_PORT_SPACING; | ||
705 | |||
706 | if (i >= PORTS_PER_ASIC) { | ||
707 | rp->asic_base += RP2_ASIC_SPACING; | ||
708 | rp->base += RP2_ASIC_SPACING; | ||
709 | rp->ucode += RP2_ASIC_SPACING; | ||
710 | p->mapbase += RP2_ASIC_SPACING; | ||
711 | } | ||
712 | |||
713 | rp2_init_port(rp, fw); | ||
714 | rc = uart_add_one_port(&rp2_uart_driver, p); | ||
715 | if (rc) { | ||
716 | dev_err(&card->pdev->dev, | ||
717 | "error registering port %d: %d\n", i, rc); | ||
718 | rp2_remove_ports(card); | ||
719 | break; | ||
720 | } | ||
721 | card->initialized_ports++; | ||
722 | } | ||
723 | |||
724 | release_firmware(fw); | ||
725 | no_fw: | ||
726 | /* | ||
727 | * rp2_fw_cb() is called from a workqueue long after rp2_probe() | ||
728 | * has already returned success. So if something failed here, | ||
729 | * we'll just leave the now-dormant device in place until somebody | ||
730 | * unbinds it. | ||
731 | */ | ||
732 | if (rc) | ||
733 | dev_warn(&card->pdev->dev, "driver initialization failed\n"); | ||
734 | |||
735 | complete(&card->fw_loaded); | ||
736 | } | ||
737 | |||
738 | static int rp2_probe(struct pci_dev *pdev, | ||
739 | const struct pci_device_id *id) | ||
740 | { | ||
741 | struct rp2_card *card; | ||
742 | struct rp2_uart_port *ports; | ||
743 | void __iomem * const *bars; | ||
744 | int rc; | ||
745 | |||
746 | card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL); | ||
747 | if (!card) | ||
748 | return -ENOMEM; | ||
749 | pci_set_drvdata(pdev, card); | ||
750 | spin_lock_init(&card->card_lock); | ||
751 | init_completion(&card->fw_loaded); | ||
752 | |||
753 | rc = pcim_enable_device(pdev); | ||
754 | if (rc) | ||
755 | return rc; | ||
756 | |||
757 | rc = pcim_iomap_regions_request_all(pdev, 0x03, DRV_NAME); | ||
758 | if (rc) | ||
759 | return rc; | ||
760 | |||
761 | bars = pcim_iomap_table(pdev); | ||
762 | card->bar0 = bars[0]; | ||
763 | card->bar1 = bars[1]; | ||
764 | card->pdev = pdev; | ||
765 | |||
766 | rp2_decode_cap(id, &card->n_ports, &card->smpte); | ||
767 | dev_info(&pdev->dev, "found new card with %d ports\n", card->n_ports); | ||
768 | |||
769 | card->minor_start = rp2_alloc_ports(card->n_ports); | ||
770 | if (card->minor_start < 0) { | ||
771 | dev_err(&pdev->dev, | ||
772 | "too many ports (try increasing CONFIG_SERIAL_RP2_NR_UARTS)\n"); | ||
773 | return -EINVAL; | ||
774 | } | ||
775 | |||
776 | rp2_init_card(card); | ||
777 | |||
778 | ports = devm_kzalloc(&pdev->dev, sizeof(*ports) * card->n_ports, | ||
779 | GFP_KERNEL); | ||
780 | if (!ports) | ||
781 | return -ENOMEM; | ||
782 | card->ports = ports; | ||
783 | |||
784 | rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, | ||
785 | IRQF_SHARED, DRV_NAME, card); | ||
786 | if (rc) | ||
787 | return rc; | ||
788 | |||
789 | /* | ||
790 | * Only catastrophic errors (e.g. ENOMEM) are reported here. | ||
791 | * If the FW image is missing, we'll find out in rp2_fw_cb() | ||
792 | * and print an error message. | ||
793 | */ | ||
794 | rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev, | ||
795 | GFP_KERNEL, card, rp2_fw_cb); | ||
796 | if (rc) | ||
797 | return rc; | ||
798 | dev_dbg(&pdev->dev, "waiting for firmware blob...\n"); | ||
799 | |||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | static void rp2_remove(struct pci_dev *pdev) | ||
804 | { | ||
805 | struct rp2_card *card = pci_get_drvdata(pdev); | ||
806 | |||
807 | wait_for_completion(&card->fw_loaded); | ||
808 | rp2_remove_ports(card); | ||
809 | } | ||
810 | |||
811 | static DEFINE_PCI_DEVICE_TABLE(rp2_pci_tbl) = { | ||
812 | |||
813 | /* RocketPort INFINITY cards */ | ||
814 | |||
815 | { RP_ID(0x0040), RP_CAP(8, 0) }, /* INF Octa, RJ45, selectable */ | ||
816 | { RP_ID(0x0041), RP_CAP(32, 0) }, /* INF 32, ext interface */ | ||
817 | { RP_ID(0x0042), RP_CAP(8, 0) }, /* INF Octa, ext interface */ | ||
818 | { RP_ID(0x0043), RP_CAP(16, 0) }, /* INF 16, ext interface */ | ||
819 | { RP_ID(0x0044), RP_CAP(4, 0) }, /* INF Quad, DB, selectable */ | ||
820 | { RP_ID(0x0045), RP_CAP(8, 0) }, /* INF Octa, DB, selectable */ | ||
821 | { RP_ID(0x0046), RP_CAP(4, 0) }, /* INF Quad, ext interface */ | ||
822 | { RP_ID(0x0047), RP_CAP(4, 0) }, /* INF Quad, RJ45 */ | ||
823 | { RP_ID(0x004a), RP_CAP(4, 0) }, /* INF Plus, Quad */ | ||
824 | { RP_ID(0x004b), RP_CAP(8, 0) }, /* INF Plus, Octa */ | ||
825 | { RP_ID(0x004c), RP_CAP(8, 0) }, /* INF III, Octa */ | ||
826 | { RP_ID(0x004d), RP_CAP(4, 0) }, /* INF III, Quad */ | ||
827 | { RP_ID(0x004e), RP_CAP(2, 0) }, /* INF Plus, 2, RS232 */ | ||
828 | { RP_ID(0x004f), RP_CAP(2, 1) }, /* INF Plus, 2, SMPTE */ | ||
829 | { RP_ID(0x0050), RP_CAP(4, 0) }, /* INF Plus, Quad, RJ45 */ | ||
830 | { RP_ID(0x0051), RP_CAP(8, 0) }, /* INF Plus, Octa, RJ45 */ | ||
831 | { RP_ID(0x0052), RP_CAP(8, 1) }, /* INF Octa, SMPTE */ | ||
832 | |||
833 | /* RocketPort EXPRESS cards */ | ||
834 | |||
835 | { RP_ID(0x0060), RP_CAP(8, 0) }, /* EXP Octa, RJ45, selectable */ | ||
836 | { RP_ID(0x0061), RP_CAP(32, 0) }, /* EXP 32, ext interface */ | ||
837 | { RP_ID(0x0062), RP_CAP(8, 0) }, /* EXP Octa, ext interface */ | ||
838 | { RP_ID(0x0063), RP_CAP(16, 0) }, /* EXP 16, ext interface */ | ||
839 | { RP_ID(0x0064), RP_CAP(4, 0) }, /* EXP Quad, DB, selectable */ | ||
840 | { RP_ID(0x0065), RP_CAP(8, 0) }, /* EXP Octa, DB, selectable */ | ||
841 | { RP_ID(0x0066), RP_CAP(4, 0) }, /* EXP Quad, ext interface */ | ||
842 | { RP_ID(0x0067), RP_CAP(4, 0) }, /* EXP Quad, RJ45 */ | ||
843 | { RP_ID(0x0068), RP_CAP(8, 0) }, /* EXP Octa, RJ11 */ | ||
844 | { RP_ID(0x0072), RP_CAP(8, 1) }, /* EXP Octa, SMPTE */ | ||
845 | { } | ||
846 | }; | ||
847 | MODULE_DEVICE_TABLE(pci, rp2_pci_tbl); | ||
848 | |||
849 | static struct pci_driver rp2_pci_driver = { | ||
850 | .name = DRV_NAME, | ||
851 | .id_table = rp2_pci_tbl, | ||
852 | .probe = rp2_probe, | ||
853 | .remove = rp2_remove, | ||
854 | }; | ||
855 | |||
856 | static int __init rp2_uart_init(void) | ||
857 | { | ||
858 | int rc; | ||
859 | |||
860 | rc = uart_register_driver(&rp2_uart_driver); | ||
861 | if (rc) | ||
862 | return rc; | ||
863 | |||
864 | rc = pci_register_driver(&rp2_pci_driver); | ||
865 | if (rc) { | ||
866 | uart_unregister_driver(&rp2_uart_driver); | ||
867 | return rc; | ||
868 | } | ||
869 | |||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | static void __exit rp2_uart_exit(void) | ||
874 | { | ||
875 | pci_unregister_driver(&rp2_pci_driver); | ||
876 | uart_unregister_driver(&rp2_uart_driver); | ||
877 | } | ||
878 | |||
879 | module_init(rp2_uart_init); | ||
880 | module_exit(rp2_uart_exit); | ||
881 | |||
882 | MODULE_DESCRIPTION("Comtrol RocketPort EXPRESS/INFINITY driver"); | ||
883 | MODULE_AUTHOR("Kevin Cernekee <cernekee@gmail.com>"); | ||
884 | MODULE_LICENSE("GPL v2"); | ||
885 | MODULE_FIRMWARE(RP2_FW_NAME); | ||
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 5d4b9b449b4a..af6b3e3ad24d 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c | |||
@@ -188,7 +188,6 @@ static void sa1100_enable_ms(struct uart_port *port) | |||
188 | static void | 188 | static void |
189 | sa1100_rx_chars(struct sa1100_port *sport) | 189 | sa1100_rx_chars(struct sa1100_port *sport) |
190 | { | 190 | { |
191 | struct tty_struct *tty = sport->port.state->port.tty; | ||
192 | unsigned int status, ch, flg; | 191 | unsigned int status, ch, flg; |
193 | 192 | ||
194 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 193 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
@@ -233,7 +232,7 @@ sa1100_rx_chars(struct sa1100_port *sport) | |||
233 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 232 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
234 | UTSR0_TO_SM(UART_GET_UTSR0(sport)); | 233 | UTSR0_TO_SM(UART_GET_UTSR0(sport)); |
235 | } | 234 | } |
236 | tty_flip_buffer_push(tty); | 235 | tty_flip_buffer_push(&sport->port.state->port); |
237 | } | 236 | } |
238 | 237 | ||
239 | static void sa1100_tx_chars(struct sa1100_port *sport) | 238 | static void sa1100_tx_chars(struct sa1100_port *sport) |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index e514b3a4dc57..2769a38d15b6 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | 48 | ||
49 | #include <mach/hardware.h> | 49 | #include <mach/hardware.h> |
50 | #include <mach/map.h> | ||
51 | 50 | ||
52 | #include <plat/regs-serial.h> | 51 | #include <plat/regs-serial.h> |
53 | #include <plat/clock.h> | 52 | #include <plat/clock.h> |
@@ -221,7 +220,6 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
221 | { | 220 | { |
222 | struct s3c24xx_uart_port *ourport = dev_id; | 221 | struct s3c24xx_uart_port *ourport = dev_id; |
223 | struct uart_port *port = &ourport->port; | 222 | struct uart_port *port = &ourport->port; |
224 | struct tty_struct *tty = port->state->port.tty; | ||
225 | unsigned int ufcon, ch, flag, ufstat, uerstat; | 223 | unsigned int ufcon, ch, flag, ufstat, uerstat; |
226 | unsigned long flags; | 224 | unsigned long flags; |
227 | int max_count = 64; | 225 | int max_count = 64; |
@@ -299,7 +297,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
299 | ignore_char: | 297 | ignore_char: |
300 | continue; | 298 | continue; |
301 | } | 299 | } |
302 | tty_flip_buffer_push(tty); | 300 | tty_flip_buffer_push(&port->state->port); |
303 | 301 | ||
304 | out: | 302 | out: |
305 | spin_unlock_irqrestore(&port->lock, flags); | 303 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -1143,8 +1141,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1143 | 1141 | ||
1144 | dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); | 1142 | dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); |
1145 | 1143 | ||
1144 | port->membase = devm_ioremap(port->dev, res->start, resource_size(res)); | ||
1145 | if (!port->membase) { | ||
1146 | dev_err(port->dev, "failed to remap controller address\n"); | ||
1147 | return -EBUSY; | ||
1148 | } | ||
1149 | |||
1146 | port->mapbase = res->start; | 1150 | port->mapbase = res->start; |
1147 | port->membase = S3C_VA_UART + (res->start & 0xfffff); | ||
1148 | ret = platform_get_irq(platdev, 0); | 1151 | ret = platform_get_irq(platdev, 0); |
1149 | if (ret < 0) | 1152 | if (ret < 0) |
1150 | port->irq = 0; | 1153 | port->irq = 0; |
@@ -1724,8 +1727,6 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = { | |||
1724 | {}, | 1727 | {}, |
1725 | }; | 1728 | }; |
1726 | MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); | 1729 | MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); |
1727 | #else | ||
1728 | #define s3c24xx_uart_dt_match NULL | ||
1729 | #endif | 1730 | #endif |
1730 | 1731 | ||
1731 | static struct platform_driver samsung_serial_driver = { | 1732 | static struct platform_driver samsung_serial_driver = { |
@@ -1736,7 +1737,7 @@ static struct platform_driver samsung_serial_driver = { | |||
1736 | .name = "samsung-uart", | 1737 | .name = "samsung-uart", |
1737 | .owner = THIS_MODULE, | 1738 | .owner = THIS_MODULE, |
1738 | .pm = SERIAL_SAMSUNG_PM_OPS, | 1739 | .pm = SERIAL_SAMSUNG_PM_OPS, |
1739 | .of_match_table = s3c24xx_uart_dt_match, | 1740 | .of_match_table = of_match_ptr(s3c24xx_uart_dt_match), |
1740 | }, | 1741 | }, |
1741 | }; | 1742 | }; |
1742 | 1743 | ||
diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index f76b1688c5c8..a7cdec2962dd 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c | |||
@@ -384,7 +384,7 @@ static void sbd_receive_chars(struct sbd_port *sport) | |||
384 | uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); | 384 | uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); |
385 | } | 385 | } |
386 | 386 | ||
387 | tty_flip_buffer_push(uport->state->port.tty); | 387 | tty_flip_buffer_push(&uport->state->port); |
388 | } | 388 | } |
389 | 389 | ||
390 | static void sbd_transmit_chars(struct sbd_port *sport) | 390 | static void sbd_transmit_chars(struct sbd_port *sport) |
diff --git a/drivers/tty/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c index aced1dd923d8..c9735680762d 100644 --- a/drivers/tty/serial/sc26xx.c +++ b/drivers/tty/serial/sc26xx.c | |||
@@ -136,16 +136,17 @@ static void sc26xx_disable_irq(struct uart_port *port, int mask) | |||
136 | WRITE_SC(port, IMR, up->imr); | 136 | WRITE_SC(port, IMR, up->imr); |
137 | } | 137 | } |
138 | 138 | ||
139 | static struct tty_struct *receive_chars(struct uart_port *port) | 139 | static bool receive_chars(struct uart_port *port) |
140 | { | 140 | { |
141 | struct tty_struct *tty = NULL; | 141 | struct tty_port *tport = NULL; |
142 | int limit = 10000; | 142 | int limit = 10000; |
143 | unsigned char ch; | 143 | unsigned char ch; |
144 | char flag; | 144 | char flag; |
145 | u8 status; | 145 | u8 status; |
146 | 146 | ||
147 | /* FIXME what is this trying to achieve? */ | ||
147 | if (port->state != NULL) /* Unopened serial console */ | 148 | if (port->state != NULL) /* Unopened serial console */ |
148 | tty = port->state->port.tty; | 149 | tport = &port->state->port; |
149 | 150 | ||
150 | while (limit-- > 0) { | 151 | while (limit-- > 0) { |
151 | status = READ_SC_PORT(port, SR); | 152 | status = READ_SC_PORT(port, SR); |
@@ -185,9 +186,9 @@ static struct tty_struct *receive_chars(struct uart_port *port) | |||
185 | if (status & port->ignore_status_mask) | 186 | if (status & port->ignore_status_mask) |
186 | continue; | 187 | continue; |
187 | 188 | ||
188 | tty_insert_flip_char(tty, ch, flag); | 189 | tty_insert_flip_char(tport, ch, flag); |
189 | } | 190 | } |
190 | return tty; | 191 | return !!tport; |
191 | } | 192 | } |
192 | 193 | ||
193 | static void transmit_chars(struct uart_port *port) | 194 | static void transmit_chars(struct uart_port *port) |
@@ -217,36 +218,36 @@ static void transmit_chars(struct uart_port *port) | |||
217 | static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) | 218 | static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) |
218 | { | 219 | { |
219 | struct uart_sc26xx_port *up = dev_id; | 220 | struct uart_sc26xx_port *up = dev_id; |
220 | struct tty_struct *tty; | ||
221 | unsigned long flags; | 221 | unsigned long flags; |
222 | bool push; | ||
222 | u8 isr; | 223 | u8 isr; |
223 | 224 | ||
224 | spin_lock_irqsave(&up->port[0].lock, flags); | 225 | spin_lock_irqsave(&up->port[0].lock, flags); |
225 | 226 | ||
226 | tty = NULL; | 227 | push = false; |
227 | isr = READ_SC(&up->port[0], ISR); | 228 | isr = READ_SC(&up->port[0], ISR); |
228 | if (isr & ISR_TXRDYA) | 229 | if (isr & ISR_TXRDYA) |
229 | transmit_chars(&up->port[0]); | 230 | transmit_chars(&up->port[0]); |
230 | if (isr & ISR_RXRDYA) | 231 | if (isr & ISR_RXRDYA) |
231 | tty = receive_chars(&up->port[0]); | 232 | push = receive_chars(&up->port[0]); |
232 | 233 | ||
233 | spin_unlock(&up->port[0].lock); | 234 | spin_unlock(&up->port[0].lock); |
234 | 235 | ||
235 | if (tty) | 236 | if (push) |
236 | tty_flip_buffer_push(tty); | 237 | tty_flip_buffer_push(&up->port[0].state->port); |
237 | 238 | ||
238 | spin_lock(&up->port[1].lock); | 239 | spin_lock(&up->port[1].lock); |
239 | 240 | ||
240 | tty = NULL; | 241 | push = false; |
241 | if (isr & ISR_TXRDYB) | 242 | if (isr & ISR_TXRDYB) |
242 | transmit_chars(&up->port[1]); | 243 | transmit_chars(&up->port[1]); |
243 | if (isr & ISR_RXRDYB) | 244 | if (isr & ISR_RXRDYB) |
244 | tty = receive_chars(&up->port[1]); | 245 | push = receive_chars(&up->port[1]); |
245 | 246 | ||
246 | spin_unlock_irqrestore(&up->port[1].lock, flags); | 247 | spin_unlock_irqrestore(&up->port[1].lock, flags); |
247 | 248 | ||
248 | if (tty) | 249 | if (push) |
249 | tty_flip_buffer_push(tty); | 250 | tty_flip_buffer_push(&up->port[1].state->port); |
250 | 251 | ||
251 | return IRQ_HANDLED; | 252 | return IRQ_HANDLED; |
252 | } | 253 | } |
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index e869eab180be..08dbfb88d42c 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c | |||
@@ -24,8 +24,9 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/tty.h> | 25 | #include <linux/tty.h> |
26 | #include <linux/tty_flip.h> | 26 | #include <linux/tty_flip.h> |
27 | #include <linux/spinlock.h> | ||
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | #include <linux/platform_data/sccnxp.h> | 29 | #include <linux/platform_data/serial-sccnxp.h> |
29 | 30 | ||
30 | #define SCCNXP_NAME "uart-sccnxp" | 31 | #define SCCNXP_NAME "uart-sccnxp" |
31 | #define SCCNXP_MAJOR 204 | 32 | #define SCCNXP_MAJOR 204 |
@@ -107,6 +108,7 @@ enum { | |||
107 | struct sccnxp_port { | 108 | struct sccnxp_port { |
108 | struct uart_driver uart; | 109 | struct uart_driver uart; |
109 | struct uart_port port[SCCNXP_MAX_UARTS]; | 110 | struct uart_port port[SCCNXP_MAX_UARTS]; |
111 | bool opened[SCCNXP_MAX_UARTS]; | ||
110 | 112 | ||
111 | const char *name; | 113 | const char *name; |
112 | int irq; | 114 | int irq; |
@@ -123,7 +125,10 @@ struct sccnxp_port { | |||
123 | struct console console; | 125 | struct console console; |
124 | #endif | 126 | #endif |
125 | 127 | ||
126 | struct mutex sccnxp_mutex; | 128 | spinlock_t lock; |
129 | |||
130 | bool poll; | ||
131 | struct timer_list timer; | ||
127 | 132 | ||
128 | struct sccnxp_pdata pdata; | 133 | struct sccnxp_pdata pdata; |
129 | }; | 134 | }; |
@@ -175,14 +180,12 @@ static int sccnxp_update_best_err(int a, int b, int *besterr) | |||
175 | return 1; | 180 | return 1; |
176 | } | 181 | } |
177 | 182 | ||
178 | struct baud_table { | 183 | static const struct { |
179 | u8 csr; | 184 | u8 csr; |
180 | u8 acr; | 185 | u8 acr; |
181 | u8 mr0; | 186 | u8 mr0; |
182 | int baud; | 187 | int baud; |
183 | }; | 188 | } baud_std[] = { |
184 | |||
185 | const struct baud_table baud_std[] = { | ||
186 | { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, }, | 189 | { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, }, |
187 | { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, }, | 190 | { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, }, |
188 | { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, }, | 191 | { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, }, |
@@ -286,10 +289,6 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
286 | { | 289 | { |
287 | u8 sr; | 290 | u8 sr; |
288 | unsigned int ch, flag; | 291 | unsigned int ch, flag; |
289 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
290 | |||
291 | if (!tty) | ||
292 | return; | ||
293 | 292 | ||
294 | for (;;) { | 293 | for (;;) { |
295 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); | 294 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); |
@@ -305,14 +304,19 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
305 | if (unlikely(sr)) { | 304 | if (unlikely(sr)) { |
306 | if (sr & SR_BRK) { | 305 | if (sr & SR_BRK) { |
307 | port->icount.brk++; | 306 | port->icount.brk++; |
307 | sccnxp_port_write(port, SCCNXP_CR_REG, | ||
308 | CR_CMD_BREAK_RESET); | ||
308 | if (uart_handle_break(port)) | 309 | if (uart_handle_break(port)) |
309 | continue; | 310 | continue; |
310 | } else if (sr & SR_PE) | 311 | } else if (sr & SR_PE) |
311 | port->icount.parity++; | 312 | port->icount.parity++; |
312 | else if (sr & SR_FE) | 313 | else if (sr & SR_FE) |
313 | port->icount.frame++; | 314 | port->icount.frame++; |
314 | else if (sr & SR_OVR) | 315 | else if (sr & SR_OVR) { |
315 | port->icount.overrun++; | 316 | port->icount.overrun++; |
317 | sccnxp_port_write(port, SCCNXP_CR_REG, | ||
318 | CR_CMD_STATUS_RESET); | ||
319 | } | ||
316 | 320 | ||
317 | sr &= port->read_status_mask; | 321 | sr &= port->read_status_mask; |
318 | if (sr & SR_BRK) | 322 | if (sr & SR_BRK) |
@@ -334,9 +338,7 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
334 | uart_insert_char(port, sr, SR_OVR, ch, flag); | 338 | uart_insert_char(port, sr, SR_OVR, ch, flag); |
335 | } | 339 | } |
336 | 340 | ||
337 | tty_flip_buffer_push(tty); | 341 | tty_flip_buffer_push(&port->state->port); |
338 | |||
339 | tty_kref_put(tty); | ||
340 | } | 342 | } |
341 | 343 | ||
342 | static void sccnxp_handle_tx(struct uart_port *port) | 344 | static void sccnxp_handle_tx(struct uart_port *port) |
@@ -378,31 +380,48 @@ static void sccnxp_handle_tx(struct uart_port *port) | |||
378 | uart_write_wakeup(port); | 380 | uart_write_wakeup(port); |
379 | } | 381 | } |
380 | 382 | ||
381 | static irqreturn_t sccnxp_ist(int irq, void *dev_id) | 383 | static void sccnxp_handle_events(struct sccnxp_port *s) |
382 | { | 384 | { |
383 | int i; | 385 | int i; |
384 | u8 isr; | 386 | u8 isr; |
385 | struct sccnxp_port *s = (struct sccnxp_port *)dev_id; | ||
386 | |||
387 | mutex_lock(&s->sccnxp_mutex); | ||
388 | 387 | ||
389 | for (;;) { | 388 | do { |
390 | isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG); | 389 | isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG); |
391 | isr &= s->imr; | 390 | isr &= s->imr; |
392 | if (!isr) | 391 | if (!isr) |
393 | break; | 392 | break; |
394 | 393 | ||
395 | dev_dbg(s->port[0].dev, "IRQ status: 0x%02x\n", isr); | ||
396 | |||
397 | for (i = 0; i < s->uart.nr; i++) { | 394 | for (i = 0; i < s->uart.nr; i++) { |
398 | if (isr & ISR_RXRDY(i)) | 395 | if (s->opened[i] && (isr & ISR_RXRDY(i))) |
399 | sccnxp_handle_rx(&s->port[i]); | 396 | sccnxp_handle_rx(&s->port[i]); |
400 | if (isr & ISR_TXRDY(i)) | 397 | if (s->opened[i] && (isr & ISR_TXRDY(i))) |
401 | sccnxp_handle_tx(&s->port[i]); | 398 | sccnxp_handle_tx(&s->port[i]); |
402 | } | 399 | } |
403 | } | 400 | } while (1); |
401 | } | ||
402 | |||
403 | static void sccnxp_timer(unsigned long data) | ||
404 | { | ||
405 | struct sccnxp_port *s = (struct sccnxp_port *)data; | ||
406 | unsigned long flags; | ||
404 | 407 | ||
405 | mutex_unlock(&s->sccnxp_mutex); | 408 | spin_lock_irqsave(&s->lock, flags); |
409 | sccnxp_handle_events(s); | ||
410 | spin_unlock_irqrestore(&s->lock, flags); | ||
411 | |||
412 | if (!timer_pending(&s->timer)) | ||
413 | mod_timer(&s->timer, jiffies + | ||
414 | usecs_to_jiffies(s->pdata.poll_time_us)); | ||
415 | } | ||
416 | |||
417 | static irqreturn_t sccnxp_ist(int irq, void *dev_id) | ||
418 | { | ||
419 | struct sccnxp_port *s = (struct sccnxp_port *)dev_id; | ||
420 | unsigned long flags; | ||
421 | |||
422 | spin_lock_irqsave(&s->lock, flags); | ||
423 | sccnxp_handle_events(s); | ||
424 | spin_unlock_irqrestore(&s->lock, flags); | ||
406 | 425 | ||
407 | return IRQ_HANDLED; | 426 | return IRQ_HANDLED; |
408 | } | 427 | } |
@@ -410,8 +429,9 @@ static irqreturn_t sccnxp_ist(int irq, void *dev_id) | |||
410 | static void sccnxp_start_tx(struct uart_port *port) | 429 | static void sccnxp_start_tx(struct uart_port *port) |
411 | { | 430 | { |
412 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 431 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
432 | unsigned long flags; | ||
413 | 433 | ||
414 | mutex_lock(&s->sccnxp_mutex); | 434 | spin_lock_irqsave(&s->lock, flags); |
415 | 435 | ||
416 | /* Set direction to output */ | 436 | /* Set direction to output */ |
417 | if (s->flags & SCCNXP_HAVE_IO) | 437 | if (s->flags & SCCNXP_HAVE_IO) |
@@ -419,7 +439,7 @@ static void sccnxp_start_tx(struct uart_port *port) | |||
419 | 439 | ||
420 | sccnxp_enable_irq(port, IMR_TXRDY); | 440 | sccnxp_enable_irq(port, IMR_TXRDY); |
421 | 441 | ||
422 | mutex_unlock(&s->sccnxp_mutex); | 442 | spin_unlock_irqrestore(&s->lock, flags); |
423 | } | 443 | } |
424 | 444 | ||
425 | static void sccnxp_stop_tx(struct uart_port *port) | 445 | static void sccnxp_stop_tx(struct uart_port *port) |
@@ -430,20 +450,22 @@ static void sccnxp_stop_tx(struct uart_port *port) | |||
430 | static void sccnxp_stop_rx(struct uart_port *port) | 450 | static void sccnxp_stop_rx(struct uart_port *port) |
431 | { | 451 | { |
432 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 452 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
453 | unsigned long flags; | ||
433 | 454 | ||
434 | mutex_lock(&s->sccnxp_mutex); | 455 | spin_lock_irqsave(&s->lock, flags); |
435 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE); | 456 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE); |
436 | mutex_unlock(&s->sccnxp_mutex); | 457 | spin_unlock_irqrestore(&s->lock, flags); |
437 | } | 458 | } |
438 | 459 | ||
439 | static unsigned int sccnxp_tx_empty(struct uart_port *port) | 460 | static unsigned int sccnxp_tx_empty(struct uart_port *port) |
440 | { | 461 | { |
441 | u8 val; | 462 | u8 val; |
463 | unsigned long flags; | ||
442 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 464 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
443 | 465 | ||
444 | mutex_lock(&s->sccnxp_mutex); | 466 | spin_lock_irqsave(&s->lock, flags); |
445 | val = sccnxp_port_read(port, SCCNXP_SR_REG); | 467 | val = sccnxp_port_read(port, SCCNXP_SR_REG); |
446 | mutex_unlock(&s->sccnxp_mutex); | 468 | spin_unlock_irqrestore(&s->lock, flags); |
447 | 469 | ||
448 | return (val & SR_TXEMT) ? TIOCSER_TEMT : 0; | 470 | return (val & SR_TXEMT) ? TIOCSER_TEMT : 0; |
449 | } | 471 | } |
@@ -456,28 +478,30 @@ static void sccnxp_enable_ms(struct uart_port *port) | |||
456 | static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl) | 478 | static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl) |
457 | { | 479 | { |
458 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 480 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
481 | unsigned long flags; | ||
459 | 482 | ||
460 | if (!(s->flags & SCCNXP_HAVE_IO)) | 483 | if (!(s->flags & SCCNXP_HAVE_IO)) |
461 | return; | 484 | return; |
462 | 485 | ||
463 | mutex_lock(&s->sccnxp_mutex); | 486 | spin_lock_irqsave(&s->lock, flags); |
464 | 487 | ||
465 | sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR); | 488 | sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR); |
466 | sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS); | 489 | sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS); |
467 | 490 | ||
468 | mutex_unlock(&s->sccnxp_mutex); | 491 | spin_unlock_irqrestore(&s->lock, flags); |
469 | } | 492 | } |
470 | 493 | ||
471 | static unsigned int sccnxp_get_mctrl(struct uart_port *port) | 494 | static unsigned int sccnxp_get_mctrl(struct uart_port *port) |
472 | { | 495 | { |
473 | u8 bitmask, ipr; | 496 | u8 bitmask, ipr; |
497 | unsigned long flags; | ||
474 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 498 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
475 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | 499 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; |
476 | 500 | ||
477 | if (!(s->flags & SCCNXP_HAVE_IO)) | 501 | if (!(s->flags & SCCNXP_HAVE_IO)) |
478 | return mctrl; | 502 | return mctrl; |
479 | 503 | ||
480 | mutex_lock(&s->sccnxp_mutex); | 504 | spin_lock_irqsave(&s->lock, flags); |
481 | 505 | ||
482 | ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG); | 506 | ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG); |
483 | 507 | ||
@@ -506,7 +530,7 @@ static unsigned int sccnxp_get_mctrl(struct uart_port *port) | |||
506 | mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0; | 530 | mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0; |
507 | } | 531 | } |
508 | 532 | ||
509 | mutex_unlock(&s->sccnxp_mutex); | 533 | spin_unlock_irqrestore(&s->lock, flags); |
510 | 534 | ||
511 | return mctrl; | 535 | return mctrl; |
512 | } | 536 | } |
@@ -514,21 +538,23 @@ static unsigned int sccnxp_get_mctrl(struct uart_port *port) | |||
514 | static void sccnxp_break_ctl(struct uart_port *port, int break_state) | 538 | static void sccnxp_break_ctl(struct uart_port *port, int break_state) |
515 | { | 539 | { |
516 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 540 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
541 | unsigned long flags; | ||
517 | 542 | ||
518 | mutex_lock(&s->sccnxp_mutex); | 543 | spin_lock_irqsave(&s->lock, flags); |
519 | sccnxp_port_write(port, SCCNXP_CR_REG, break_state ? | 544 | sccnxp_port_write(port, SCCNXP_CR_REG, break_state ? |
520 | CR_CMD_START_BREAK : CR_CMD_STOP_BREAK); | 545 | CR_CMD_START_BREAK : CR_CMD_STOP_BREAK); |
521 | mutex_unlock(&s->sccnxp_mutex); | 546 | spin_unlock_irqrestore(&s->lock, flags); |
522 | } | 547 | } |
523 | 548 | ||
524 | static void sccnxp_set_termios(struct uart_port *port, | 549 | static void sccnxp_set_termios(struct uart_port *port, |
525 | struct ktermios *termios, struct ktermios *old) | 550 | struct ktermios *termios, struct ktermios *old) |
526 | { | 551 | { |
527 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 552 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
553 | unsigned long flags; | ||
528 | u8 mr1, mr2; | 554 | u8 mr1, mr2; |
529 | int baud; | 555 | int baud; |
530 | 556 | ||
531 | mutex_lock(&s->sccnxp_mutex); | 557 | spin_lock_irqsave(&s->lock, flags); |
532 | 558 | ||
533 | /* Mask termios capabilities we don't support */ | 559 | /* Mask termios capabilities we don't support */ |
534 | termios->c_cflag &= ~CMSPAR; | 560 | termios->c_cflag &= ~CMSPAR; |
@@ -595,20 +621,22 @@ static void sccnxp_set_termios(struct uart_port *port, | |||
595 | /* Update timeout according to new baud rate */ | 621 | /* Update timeout according to new baud rate */ |
596 | uart_update_timeout(port, termios->c_cflag, baud); | 622 | uart_update_timeout(port, termios->c_cflag, baud); |
597 | 623 | ||
624 | /* Report actual baudrate back to core */ | ||
598 | if (tty_termios_baud_rate(termios)) | 625 | if (tty_termios_baud_rate(termios)) |
599 | tty_termios_encode_baud_rate(termios, baud, baud); | 626 | tty_termios_encode_baud_rate(termios, baud, baud); |
600 | 627 | ||
601 | /* Enable RX & TX */ | 628 | /* Enable RX & TX */ |
602 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); | 629 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); |
603 | 630 | ||
604 | mutex_unlock(&s->sccnxp_mutex); | 631 | spin_unlock_irqrestore(&s->lock, flags); |
605 | } | 632 | } |
606 | 633 | ||
607 | static int sccnxp_startup(struct uart_port *port) | 634 | static int sccnxp_startup(struct uart_port *port) |
608 | { | 635 | { |
609 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 636 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
637 | unsigned long flags; | ||
610 | 638 | ||
611 | mutex_lock(&s->sccnxp_mutex); | 639 | spin_lock_irqsave(&s->lock, flags); |
612 | 640 | ||
613 | if (s->flags & SCCNXP_HAVE_IO) { | 641 | if (s->flags & SCCNXP_HAVE_IO) { |
614 | /* Outputs are controlled manually */ | 642 | /* Outputs are controlled manually */ |
@@ -627,7 +655,9 @@ static int sccnxp_startup(struct uart_port *port) | |||
627 | /* Enable RX interrupt */ | 655 | /* Enable RX interrupt */ |
628 | sccnxp_enable_irq(port, IMR_RXRDY); | 656 | sccnxp_enable_irq(port, IMR_RXRDY); |
629 | 657 | ||
630 | mutex_unlock(&s->sccnxp_mutex); | 658 | s->opened[port->line] = 1; |
659 | |||
660 | spin_unlock_irqrestore(&s->lock, flags); | ||
631 | 661 | ||
632 | return 0; | 662 | return 0; |
633 | } | 663 | } |
@@ -635,8 +665,11 @@ static int sccnxp_startup(struct uart_port *port) | |||
635 | static void sccnxp_shutdown(struct uart_port *port) | 665 | static void sccnxp_shutdown(struct uart_port *port) |
636 | { | 666 | { |
637 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 667 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
668 | unsigned long flags; | ||
638 | 669 | ||
639 | mutex_lock(&s->sccnxp_mutex); | 670 | spin_lock_irqsave(&s->lock, flags); |
671 | |||
672 | s->opened[port->line] = 0; | ||
640 | 673 | ||
641 | /* Disable interrupts */ | 674 | /* Disable interrupts */ |
642 | sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY); | 675 | sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY); |
@@ -648,7 +681,7 @@ static void sccnxp_shutdown(struct uart_port *port) | |||
648 | if (s->flags & SCCNXP_HAVE_IO) | 681 | if (s->flags & SCCNXP_HAVE_IO) |
649 | sccnxp_set_bit(port, DIR_OP, 0); | 682 | sccnxp_set_bit(port, DIR_OP, 0); |
650 | 683 | ||
651 | mutex_unlock(&s->sccnxp_mutex); | 684 | spin_unlock_irqrestore(&s->lock, flags); |
652 | } | 685 | } |
653 | 686 | ||
654 | static const char *sccnxp_type(struct uart_port *port) | 687 | static const char *sccnxp_type(struct uart_port *port) |
@@ -722,10 +755,11 @@ static void sccnxp_console_write(struct console *co, const char *c, unsigned n) | |||
722 | { | 755 | { |
723 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; | 756 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; |
724 | struct uart_port *port = &s->port[co->index]; | 757 | struct uart_port *port = &s->port[co->index]; |
758 | unsigned long flags; | ||
725 | 759 | ||
726 | mutex_lock(&s->sccnxp_mutex); | 760 | spin_lock_irqsave(&s->lock, flags); |
727 | uart_console_write(port, c, n, sccnxp_console_putchar); | 761 | uart_console_write(port, c, n, sccnxp_console_putchar); |
728 | mutex_unlock(&s->sccnxp_mutex); | 762 | spin_unlock_irqrestore(&s->lock, flags); |
729 | } | 763 | } |
730 | 764 | ||
731 | static int sccnxp_console_setup(struct console *co, char *options) | 765 | static int sccnxp_console_setup(struct console *co, char *options) |
@@ -764,7 +798,7 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
764 | } | 798 | } |
765 | platform_set_drvdata(pdev, s); | 799 | platform_set_drvdata(pdev, s); |
766 | 800 | ||
767 | mutex_init(&s->sccnxp_mutex); | 801 | spin_lock_init(&s->lock); |
768 | 802 | ||
769 | /* Individual chip settings */ | 803 | /* Individual chip settings */ |
770 | switch (chiptype) { | 804 | switch (chiptype) { |
@@ -861,11 +895,19 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
861 | } else | 895 | } else |
862 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); | 896 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); |
863 | 897 | ||
864 | s->irq = platform_get_irq(pdev, 0); | 898 | if (s->pdata.poll_time_us) { |
865 | if (s->irq <= 0) { | 899 | dev_info(&pdev->dev, "Using poll mode, resolution %u usecs\n", |
866 | dev_err(&pdev->dev, "Missing irq resource data\n"); | 900 | s->pdata.poll_time_us); |
867 | ret = -ENXIO; | 901 | s->poll = 1; |
868 | goto err_out; | 902 | } |
903 | |||
904 | if (!s->poll) { | ||
905 | s->irq = platform_get_irq(pdev, 0); | ||
906 | if (s->irq < 0) { | ||
907 | dev_err(&pdev->dev, "Missing irq resource data\n"); | ||
908 | ret = -ENXIO; | ||
909 | goto err_out; | ||
910 | } | ||
869 | } | 911 | } |
870 | 912 | ||
871 | /* Check input frequency */ | 913 | /* Check input frequency */ |
@@ -929,13 +971,23 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
929 | if (s->pdata.init) | 971 | if (s->pdata.init) |
930 | s->pdata.init(); | 972 | s->pdata.init(); |
931 | 973 | ||
932 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, sccnxp_ist, | 974 | if (!s->poll) { |
933 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 975 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, |
934 | dev_name(&pdev->dev), s); | 976 | sccnxp_ist, |
935 | if (!ret) | 977 | IRQF_TRIGGER_FALLING | |
978 | IRQF_ONESHOT, | ||
979 | dev_name(&pdev->dev), s); | ||
980 | if (!ret) | ||
981 | return 0; | ||
982 | |||
983 | dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq); | ||
984 | } else { | ||
985 | init_timer(&s->timer); | ||
986 | setup_timer(&s->timer, sccnxp_timer, (unsigned long)s); | ||
987 | mod_timer(&s->timer, jiffies + | ||
988 | usecs_to_jiffies(s->pdata.poll_time_us)); | ||
936 | return 0; | 989 | return 0; |
937 | 990 | } | |
938 | dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq); | ||
939 | 991 | ||
940 | err_out: | 992 | err_out: |
941 | platform_set_drvdata(pdev, NULL); | 993 | platform_set_drvdata(pdev, NULL); |
@@ -948,7 +1000,10 @@ static int sccnxp_remove(struct platform_device *pdev) | |||
948 | int i; | 1000 | int i; |
949 | struct sccnxp_port *s = platform_get_drvdata(pdev); | 1001 | struct sccnxp_port *s = platform_get_drvdata(pdev); |
950 | 1002 | ||
951 | devm_free_irq(&pdev->dev, s->irq, s); | 1003 | if (!s->poll) |
1004 | devm_free_irq(&pdev->dev, s->irq, s); | ||
1005 | else | ||
1006 | del_timer_sync(&s->timer); | ||
952 | 1007 | ||
953 | for (i = 0; i < s->uart.nr; i++) | 1008 | for (i = 0; i < s->uart.nr; i++) |
954 | uart_remove_one_port(&s->uart, &s->port[i]); | 1009 | uart_remove_one_port(&s->uart, &s->port[i]); |
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c new file mode 100644 index 000000000000..372de8ade76a --- /dev/null +++ b/drivers/tty/serial/serial-tegra.c | |||
@@ -0,0 +1,1401 @@ | |||
1 | /* | ||
2 | * serial_tegra.c | ||
3 | * | ||
4 | * High-speed serial driver for NVIDIA Tegra SoCs | ||
5 | * | ||
6 | * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved. | ||
7 | * | ||
8 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms and conditions of the GNU General Public License, | ||
12 | * version 2, as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | */ | ||
22 | |||
23 | #include <linux/clk.h> | ||
24 | #include <linux/debugfs.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/dmaengine.h> | ||
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/dmapool.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/irq.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/of.h> | ||
33 | #include <linux/of_device.h> | ||
34 | #include <linux/pagemap.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/serial.h> | ||
37 | #include <linux/serial_8250.h> | ||
38 | #include <linux/serial_core.h> | ||
39 | #include <linux/serial_reg.h> | ||
40 | #include <linux/slab.h> | ||
41 | #include <linux/string.h> | ||
42 | #include <linux/termios.h> | ||
43 | #include <linux/tty.h> | ||
44 | #include <linux/tty_flip.h> | ||
45 | |||
46 | #include <linux/clk/tegra.h> | ||
47 | |||
48 | #define TEGRA_UART_TYPE "TEGRA_UART" | ||
49 | #define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE) | ||
50 | #define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3) | ||
51 | |||
52 | #define TEGRA_UART_RX_DMA_BUFFER_SIZE 4096 | ||
53 | #define TEGRA_UART_LSR_TXFIFO_FULL 0x100 | ||
54 | #define TEGRA_UART_IER_EORD 0x20 | ||
55 | #define TEGRA_UART_MCR_RTS_EN 0x40 | ||
56 | #define TEGRA_UART_MCR_CTS_EN 0x20 | ||
57 | #define TEGRA_UART_LSR_ANY (UART_LSR_OE | UART_LSR_BI | \ | ||
58 | UART_LSR_PE | UART_LSR_FE) | ||
59 | #define TEGRA_UART_IRDA_CSR 0x08 | ||
60 | #define TEGRA_UART_SIR_ENABLED 0x80 | ||
61 | |||
62 | #define TEGRA_UART_TX_PIO 1 | ||
63 | #define TEGRA_UART_TX_DMA 2 | ||
64 | #define TEGRA_UART_MIN_DMA 16 | ||
65 | #define TEGRA_UART_FIFO_SIZE 32 | ||
66 | |||
67 | /* | ||
68 | * Tx fifo trigger level setting in tegra uart is in | ||
69 | * reverse way then conventional uart. | ||
70 | */ | ||
71 | #define TEGRA_UART_TX_TRIG_16B 0x00 | ||
72 | #define TEGRA_UART_TX_TRIG_8B 0x10 | ||
73 | #define TEGRA_UART_TX_TRIG_4B 0x20 | ||
74 | #define TEGRA_UART_TX_TRIG_1B 0x30 | ||
75 | |||
76 | #define TEGRA_UART_MAXIMUM 5 | ||
77 | |||
78 | /* Default UART setting when started: 115200 no parity, stop, 8 data bits */ | ||
79 | #define TEGRA_UART_DEFAULT_BAUD 115200 | ||
80 | #define TEGRA_UART_DEFAULT_LSR UART_LCR_WLEN8 | ||
81 | |||
82 | /* Tx transfer mode */ | ||
83 | #define TEGRA_TX_PIO 1 | ||
84 | #define TEGRA_TX_DMA 2 | ||
85 | |||
86 | /** | ||
87 | * tegra_uart_chip_data: SOC specific data. | ||
88 | * | ||
89 | * @tx_fifo_full_status: Status flag available for checking tx fifo full. | ||
90 | * @allow_txfifo_reset_fifo_mode: allow_tx fifo reset with fifo mode or not. | ||
91 | * Tegra30 does not allow this. | ||
92 | * @support_clk_src_div: Clock source support the clock divider. | ||
93 | */ | ||
94 | struct tegra_uart_chip_data { | ||
95 | bool tx_fifo_full_status; | ||
96 | bool allow_txfifo_reset_fifo_mode; | ||
97 | bool support_clk_src_div; | ||
98 | }; | ||
99 | |||
100 | struct tegra_uart_port { | ||
101 | struct uart_port uport; | ||
102 | const struct tegra_uart_chip_data *cdata; | ||
103 | |||
104 | struct clk *uart_clk; | ||
105 | unsigned int current_baud; | ||
106 | |||
107 | /* Register shadow */ | ||
108 | unsigned long fcr_shadow; | ||
109 | unsigned long mcr_shadow; | ||
110 | unsigned long lcr_shadow; | ||
111 | unsigned long ier_shadow; | ||
112 | bool rts_active; | ||
113 | |||
114 | int tx_in_progress; | ||
115 | unsigned int tx_bytes; | ||
116 | |||
117 | bool enable_modem_interrupt; | ||
118 | |||
119 | bool rx_timeout; | ||
120 | int rx_in_progress; | ||
121 | int symb_bit; | ||
122 | int dma_req_sel; | ||
123 | |||
124 | struct dma_chan *rx_dma_chan; | ||
125 | struct dma_chan *tx_dma_chan; | ||
126 | dma_addr_t rx_dma_buf_phys; | ||
127 | dma_addr_t tx_dma_buf_phys; | ||
128 | unsigned char *rx_dma_buf_virt; | ||
129 | unsigned char *tx_dma_buf_virt; | ||
130 | struct dma_async_tx_descriptor *tx_dma_desc; | ||
131 | struct dma_async_tx_descriptor *rx_dma_desc; | ||
132 | dma_cookie_t tx_cookie; | ||
133 | dma_cookie_t rx_cookie; | ||
134 | int tx_bytes_requested; | ||
135 | int rx_bytes_requested; | ||
136 | }; | ||
137 | |||
138 | static void tegra_uart_start_next_tx(struct tegra_uart_port *tup); | ||
139 | static int tegra_uart_start_rx_dma(struct tegra_uart_port *tup); | ||
140 | |||
141 | static inline unsigned long tegra_uart_read(struct tegra_uart_port *tup, | ||
142 | unsigned long reg) | ||
143 | { | ||
144 | return readl(tup->uport.membase + (reg << tup->uport.regshift)); | ||
145 | } | ||
146 | |||
147 | static inline void tegra_uart_write(struct tegra_uart_port *tup, unsigned val, | ||
148 | unsigned long reg) | ||
149 | { | ||
150 | writel(val, tup->uport.membase + (reg << tup->uport.regshift)); | ||
151 | } | ||
152 | |||
153 | static inline struct tegra_uart_port *to_tegra_uport(struct uart_port *u) | ||
154 | { | ||
155 | return container_of(u, struct tegra_uart_port, uport); | ||
156 | } | ||
157 | |||
158 | static unsigned int tegra_uart_get_mctrl(struct uart_port *u) | ||
159 | { | ||
160 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
161 | |||
162 | /* | ||
163 | * RI - Ring detector is active | ||
164 | * CD/DCD/CAR - Carrier detect is always active. For some reason | ||
165 | * linux has different names for carrier detect. | ||
166 | * DSR - Data Set ready is active as the hardware doesn't support it. | ||
167 | * Don't know if the linux support this yet? | ||
168 | * CTS - Clear to send. Always set to active, as the hardware handles | ||
169 | * CTS automatically. | ||
170 | */ | ||
171 | if (tup->enable_modem_interrupt) | ||
172 | return TIOCM_RI | TIOCM_CD | TIOCM_DSR | TIOCM_CTS; | ||
173 | return TIOCM_CTS; | ||
174 | } | ||
175 | |||
176 | static void set_rts(struct tegra_uart_port *tup, bool active) | ||
177 | { | ||
178 | unsigned long mcr; | ||
179 | |||
180 | mcr = tup->mcr_shadow; | ||
181 | if (active) | ||
182 | mcr |= TEGRA_UART_MCR_RTS_EN; | ||
183 | else | ||
184 | mcr &= ~TEGRA_UART_MCR_RTS_EN; | ||
185 | if (mcr != tup->mcr_shadow) { | ||
186 | tegra_uart_write(tup, mcr, UART_MCR); | ||
187 | tup->mcr_shadow = mcr; | ||
188 | } | ||
189 | return; | ||
190 | } | ||
191 | |||
192 | static void set_dtr(struct tegra_uart_port *tup, bool active) | ||
193 | { | ||
194 | unsigned long mcr; | ||
195 | |||
196 | mcr = tup->mcr_shadow; | ||
197 | if (active) | ||
198 | mcr |= UART_MCR_DTR; | ||
199 | else | ||
200 | mcr &= ~UART_MCR_DTR; | ||
201 | if (mcr != tup->mcr_shadow) { | ||
202 | tegra_uart_write(tup, mcr, UART_MCR); | ||
203 | tup->mcr_shadow = mcr; | ||
204 | } | ||
205 | return; | ||
206 | } | ||
207 | |||
208 | static void tegra_uart_set_mctrl(struct uart_port *u, unsigned int mctrl) | ||
209 | { | ||
210 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
211 | unsigned long mcr; | ||
212 | int dtr_enable; | ||
213 | |||
214 | mcr = tup->mcr_shadow; | ||
215 | tup->rts_active = !!(mctrl & TIOCM_RTS); | ||
216 | set_rts(tup, tup->rts_active); | ||
217 | |||
218 | dtr_enable = !!(mctrl & TIOCM_DTR); | ||
219 | set_dtr(tup, dtr_enable); | ||
220 | return; | ||
221 | } | ||
222 | |||
223 | static void tegra_uart_break_ctl(struct uart_port *u, int break_ctl) | ||
224 | { | ||
225 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
226 | unsigned long lcr; | ||
227 | |||
228 | lcr = tup->lcr_shadow; | ||
229 | if (break_ctl) | ||
230 | lcr |= UART_LCR_SBC; | ||
231 | else | ||
232 | lcr &= ~UART_LCR_SBC; | ||
233 | tegra_uart_write(tup, lcr, UART_LCR); | ||
234 | tup->lcr_shadow = lcr; | ||
235 | } | ||
236 | |||
237 | /* Wait for a symbol-time. */ | ||
238 | static void tegra_uart_wait_sym_time(struct tegra_uart_port *tup, | ||
239 | unsigned int syms) | ||
240 | { | ||
241 | if (tup->current_baud) | ||
242 | udelay(DIV_ROUND_UP(syms * tup->symb_bit * 1000000, | ||
243 | tup->current_baud)); | ||
244 | } | ||
245 | |||
246 | static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits) | ||
247 | { | ||
248 | unsigned long fcr = tup->fcr_shadow; | ||
249 | |||
250 | if (tup->cdata->allow_txfifo_reset_fifo_mode) { | ||
251 | fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
252 | tegra_uart_write(tup, fcr, UART_FCR); | ||
253 | } else { | ||
254 | fcr &= ~UART_FCR_ENABLE_FIFO; | ||
255 | tegra_uart_write(tup, fcr, UART_FCR); | ||
256 | udelay(60); | ||
257 | fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
258 | tegra_uart_write(tup, fcr, UART_FCR); | ||
259 | fcr |= UART_FCR_ENABLE_FIFO; | ||
260 | tegra_uart_write(tup, fcr, UART_FCR); | ||
261 | } | ||
262 | |||
263 | /* Dummy read to ensure the write is posted */ | ||
264 | tegra_uart_read(tup, UART_SCR); | ||
265 | |||
266 | /* Wait for the flush to propagate. */ | ||
267 | tegra_uart_wait_sym_time(tup, 1); | ||
268 | } | ||
269 | |||
270 | static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) | ||
271 | { | ||
272 | unsigned long rate; | ||
273 | unsigned int divisor; | ||
274 | unsigned long lcr; | ||
275 | int ret; | ||
276 | |||
277 | if (tup->current_baud == baud) | ||
278 | return 0; | ||
279 | |||
280 | if (tup->cdata->support_clk_src_div) { | ||
281 | rate = baud * 16; | ||
282 | ret = clk_set_rate(tup->uart_clk, rate); | ||
283 | if (ret < 0) { | ||
284 | dev_err(tup->uport.dev, | ||
285 | "clk_set_rate() failed for rate %lu\n", rate); | ||
286 | return ret; | ||
287 | } | ||
288 | divisor = 1; | ||
289 | } else { | ||
290 | rate = clk_get_rate(tup->uart_clk); | ||
291 | divisor = DIV_ROUND_CLOSEST(rate, baud * 16); | ||
292 | } | ||
293 | |||
294 | lcr = tup->lcr_shadow; | ||
295 | lcr |= UART_LCR_DLAB; | ||
296 | tegra_uart_write(tup, lcr, UART_LCR); | ||
297 | |||
298 | tegra_uart_write(tup, divisor & 0xFF, UART_TX); | ||
299 | tegra_uart_write(tup, ((divisor >> 8) & 0xFF), UART_IER); | ||
300 | |||
301 | lcr &= ~UART_LCR_DLAB; | ||
302 | tegra_uart_write(tup, lcr, UART_LCR); | ||
303 | |||
304 | /* Dummy read to ensure the write is posted */ | ||
305 | tegra_uart_read(tup, UART_SCR); | ||
306 | |||
307 | tup->current_baud = baud; | ||
308 | |||
309 | /* wait two character intervals at new rate */ | ||
310 | tegra_uart_wait_sym_time(tup, 2); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup, | ||
315 | unsigned long lsr) | ||
316 | { | ||
317 | char flag = TTY_NORMAL; | ||
318 | |||
319 | if (unlikely(lsr & TEGRA_UART_LSR_ANY)) { | ||
320 | if (lsr & UART_LSR_OE) { | ||
321 | /* Overrrun error */ | ||
322 | flag |= TTY_OVERRUN; | ||
323 | tup->uport.icount.overrun++; | ||
324 | dev_err(tup->uport.dev, "Got overrun errors\n"); | ||
325 | } else if (lsr & UART_LSR_PE) { | ||
326 | /* Parity error */ | ||
327 | flag |= TTY_PARITY; | ||
328 | tup->uport.icount.parity++; | ||
329 | dev_err(tup->uport.dev, "Got Parity errors\n"); | ||
330 | } else if (lsr & UART_LSR_FE) { | ||
331 | flag |= TTY_FRAME; | ||
332 | tup->uport.icount.frame++; | ||
333 | dev_err(tup->uport.dev, "Got frame errors\n"); | ||
334 | } else if (lsr & UART_LSR_BI) { | ||
335 | dev_err(tup->uport.dev, "Got Break\n"); | ||
336 | tup->uport.icount.brk++; | ||
337 | /* If FIFO read error without any data, reset Rx FIFO */ | ||
338 | if (!(lsr & UART_LSR_DR) && (lsr & UART_LSR_FIFOE)) | ||
339 | tegra_uart_fifo_reset(tup, UART_FCR_CLEAR_RCVR); | ||
340 | } | ||
341 | } | ||
342 | return flag; | ||
343 | } | ||
344 | |||
345 | static int tegra_uart_request_port(struct uart_port *u) | ||
346 | { | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static void tegra_uart_release_port(struct uart_port *u) | ||
351 | { | ||
352 | /* Nothing to do here */ | ||
353 | } | ||
354 | |||
355 | static void tegra_uart_fill_tx_fifo(struct tegra_uart_port *tup, int max_bytes) | ||
356 | { | ||
357 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
358 | int i; | ||
359 | |||
360 | for (i = 0; i < max_bytes; i++) { | ||
361 | BUG_ON(uart_circ_empty(xmit)); | ||
362 | if (tup->cdata->tx_fifo_full_status) { | ||
363 | unsigned long lsr = tegra_uart_read(tup, UART_LSR); | ||
364 | if ((lsr & TEGRA_UART_LSR_TXFIFO_FULL)) | ||
365 | break; | ||
366 | } | ||
367 | tegra_uart_write(tup, xmit->buf[xmit->tail], UART_TX); | ||
368 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
369 | tup->uport.icount.tx++; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | static void tegra_uart_start_pio_tx(struct tegra_uart_port *tup, | ||
374 | unsigned int bytes) | ||
375 | { | ||
376 | if (bytes > TEGRA_UART_MIN_DMA) | ||
377 | bytes = TEGRA_UART_MIN_DMA; | ||
378 | |||
379 | tup->tx_in_progress = TEGRA_UART_TX_PIO; | ||
380 | tup->tx_bytes = bytes; | ||
381 | tup->ier_shadow |= UART_IER_THRI; | ||
382 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
383 | } | ||
384 | |||
385 | static void tegra_uart_tx_dma_complete(void *args) | ||
386 | { | ||
387 | struct tegra_uart_port *tup = args; | ||
388 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
389 | struct dma_tx_state state; | ||
390 | unsigned long flags; | ||
391 | int count; | ||
392 | |||
393 | dmaengine_tx_status(tup->tx_dma_chan, tup->rx_cookie, &state); | ||
394 | count = tup->tx_bytes_requested - state.residue; | ||
395 | async_tx_ack(tup->tx_dma_desc); | ||
396 | spin_lock_irqsave(&tup->uport.lock, flags); | ||
397 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
398 | tup->tx_in_progress = 0; | ||
399 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
400 | uart_write_wakeup(&tup->uport); | ||
401 | tegra_uart_start_next_tx(tup); | ||
402 | spin_unlock_irqrestore(&tup->uport.lock, flags); | ||
403 | } | ||
404 | |||
405 | static int tegra_uart_start_tx_dma(struct tegra_uart_port *tup, | ||
406 | unsigned long count) | ||
407 | { | ||
408 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
409 | dma_addr_t tx_phys_addr; | ||
410 | |||
411 | dma_sync_single_for_device(tup->uport.dev, tup->tx_dma_buf_phys, | ||
412 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
413 | |||
414 | tup->tx_bytes = count & ~(0xF); | ||
415 | tx_phys_addr = tup->tx_dma_buf_phys + xmit->tail; | ||
416 | tup->tx_dma_desc = dmaengine_prep_slave_single(tup->tx_dma_chan, | ||
417 | tx_phys_addr, tup->tx_bytes, DMA_MEM_TO_DEV, | ||
418 | DMA_PREP_INTERRUPT); | ||
419 | if (!tup->tx_dma_desc) { | ||
420 | dev_err(tup->uport.dev, "Not able to get desc for Tx\n"); | ||
421 | return -EIO; | ||
422 | } | ||
423 | |||
424 | tup->tx_dma_desc->callback = tegra_uart_tx_dma_complete; | ||
425 | tup->tx_dma_desc->callback_param = tup; | ||
426 | tup->tx_in_progress = TEGRA_UART_TX_DMA; | ||
427 | tup->tx_bytes_requested = tup->tx_bytes; | ||
428 | tup->tx_cookie = dmaengine_submit(tup->tx_dma_desc); | ||
429 | dma_async_issue_pending(tup->tx_dma_chan); | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static void tegra_uart_start_next_tx(struct tegra_uart_port *tup) | ||
434 | { | ||
435 | unsigned long tail; | ||
436 | unsigned long count; | ||
437 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
438 | |||
439 | tail = (unsigned long)&xmit->buf[xmit->tail]; | ||
440 | count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
441 | if (!count) | ||
442 | return; | ||
443 | |||
444 | if (count < TEGRA_UART_MIN_DMA) | ||
445 | tegra_uart_start_pio_tx(tup, count); | ||
446 | else if (BYTES_TO_ALIGN(tail) > 0) | ||
447 | tegra_uart_start_pio_tx(tup, BYTES_TO_ALIGN(tail)); | ||
448 | else | ||
449 | tegra_uart_start_tx_dma(tup, count); | ||
450 | } | ||
451 | |||
452 | /* Called by serial core driver with u->lock taken. */ | ||
453 | static void tegra_uart_start_tx(struct uart_port *u) | ||
454 | { | ||
455 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
456 | struct circ_buf *xmit = &u->state->xmit; | ||
457 | |||
458 | if (!uart_circ_empty(xmit) && !tup->tx_in_progress) | ||
459 | tegra_uart_start_next_tx(tup); | ||
460 | } | ||
461 | |||
462 | static unsigned int tegra_uart_tx_empty(struct uart_port *u) | ||
463 | { | ||
464 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
465 | unsigned int ret = 0; | ||
466 | unsigned long flags; | ||
467 | |||
468 | spin_lock_irqsave(&u->lock, flags); | ||
469 | if (!tup->tx_in_progress) { | ||
470 | unsigned long lsr = tegra_uart_read(tup, UART_LSR); | ||
471 | if ((lsr & TX_EMPTY_STATUS) == TX_EMPTY_STATUS) | ||
472 | ret = TIOCSER_TEMT; | ||
473 | } | ||
474 | spin_unlock_irqrestore(&u->lock, flags); | ||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | static void tegra_uart_stop_tx(struct uart_port *u) | ||
479 | { | ||
480 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
481 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
482 | struct dma_tx_state state; | ||
483 | int count; | ||
484 | |||
485 | dmaengine_terminate_all(tup->tx_dma_chan); | ||
486 | dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); | ||
487 | count = tup->tx_bytes_requested - state.residue; | ||
488 | async_tx_ack(tup->tx_dma_desc); | ||
489 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
490 | tup->tx_in_progress = 0; | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | static void tegra_uart_handle_tx_pio(struct tegra_uart_port *tup) | ||
495 | { | ||
496 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
497 | |||
498 | tegra_uart_fill_tx_fifo(tup, tup->tx_bytes); | ||
499 | tup->tx_in_progress = 0; | ||
500 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
501 | uart_write_wakeup(&tup->uport); | ||
502 | tegra_uart_start_next_tx(tup); | ||
503 | return; | ||
504 | } | ||
505 | |||
506 | static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, | ||
507 | struct tty_port *tty) | ||
508 | { | ||
509 | do { | ||
510 | char flag = TTY_NORMAL; | ||
511 | unsigned long lsr = 0; | ||
512 | unsigned char ch; | ||
513 | |||
514 | lsr = tegra_uart_read(tup, UART_LSR); | ||
515 | if (!(lsr & UART_LSR_DR)) | ||
516 | break; | ||
517 | |||
518 | flag = tegra_uart_decode_rx_error(tup, lsr); | ||
519 | ch = (unsigned char) tegra_uart_read(tup, UART_RX); | ||
520 | tup->uport.icount.rx++; | ||
521 | |||
522 | if (!uart_handle_sysrq_char(&tup->uport, ch) && tty) | ||
523 | tty_insert_flip_char(tty, ch, flag); | ||
524 | } while (1); | ||
525 | |||
526 | return; | ||
527 | } | ||
528 | |||
529 | static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, | ||
530 | struct tty_port *tty, int count) | ||
531 | { | ||
532 | int copied; | ||
533 | |||
534 | tup->uport.icount.rx += count; | ||
535 | if (!tty) { | ||
536 | dev_err(tup->uport.dev, "No tty port\n"); | ||
537 | return; | ||
538 | } | ||
539 | dma_sync_single_for_cpu(tup->uport.dev, tup->rx_dma_buf_phys, | ||
540 | TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE); | ||
541 | copied = tty_insert_flip_string(tty, | ||
542 | ((unsigned char *)(tup->rx_dma_buf_virt)), count); | ||
543 | if (copied != count) { | ||
544 | WARN_ON(1); | ||
545 | dev_err(tup->uport.dev, "RxData copy to tty layer failed\n"); | ||
546 | } | ||
547 | dma_sync_single_for_device(tup->uport.dev, tup->rx_dma_buf_phys, | ||
548 | TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE); | ||
549 | } | ||
550 | |||
551 | static void tegra_uart_rx_dma_complete(void *args) | ||
552 | { | ||
553 | struct tegra_uart_port *tup = args; | ||
554 | struct uart_port *u = &tup->uport; | ||
555 | int count = tup->rx_bytes_requested; | ||
556 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
557 | struct tty_port *port = &u->state->port; | ||
558 | unsigned long flags; | ||
559 | |||
560 | async_tx_ack(tup->rx_dma_desc); | ||
561 | spin_lock_irqsave(&u->lock, flags); | ||
562 | |||
563 | /* Deactivate flow control to stop sender */ | ||
564 | if (tup->rts_active) | ||
565 | set_rts(tup, false); | ||
566 | |||
567 | /* If we are here, DMA is stopped */ | ||
568 | if (count) | ||
569 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
570 | |||
571 | tegra_uart_handle_rx_pio(tup, port); | ||
572 | if (tty) { | ||
573 | tty_flip_buffer_push(port); | ||
574 | tty_kref_put(tty); | ||
575 | } | ||
576 | tegra_uart_start_rx_dma(tup); | ||
577 | |||
578 | /* Activate flow control to start transfer */ | ||
579 | if (tup->rts_active) | ||
580 | set_rts(tup, true); | ||
581 | |||
582 | spin_unlock_irqrestore(&u->lock, flags); | ||
583 | } | ||
584 | |||
585 | static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) | ||
586 | { | ||
587 | struct dma_tx_state state; | ||
588 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
589 | struct tty_port *port = &tup->uport.state->port; | ||
590 | int count; | ||
591 | |||
592 | /* Deactivate flow control to stop sender */ | ||
593 | if (tup->rts_active) | ||
594 | set_rts(tup, false); | ||
595 | |||
596 | dmaengine_terminate_all(tup->rx_dma_chan); | ||
597 | dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); | ||
598 | count = tup->rx_bytes_requested - state.residue; | ||
599 | |||
600 | /* If we are here, DMA is stopped */ | ||
601 | if (count) | ||
602 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
603 | |||
604 | tegra_uart_handle_rx_pio(tup, port); | ||
605 | if (tty) { | ||
606 | tty_flip_buffer_push(port); | ||
607 | tty_kref_put(tty); | ||
608 | } | ||
609 | tegra_uart_start_rx_dma(tup); | ||
610 | |||
611 | if (tup->rts_active) | ||
612 | set_rts(tup, true); | ||
613 | } | ||
614 | |||
615 | static int tegra_uart_start_rx_dma(struct tegra_uart_port *tup) | ||
616 | { | ||
617 | unsigned int count = TEGRA_UART_RX_DMA_BUFFER_SIZE; | ||
618 | |||
619 | tup->rx_dma_desc = dmaengine_prep_slave_single(tup->rx_dma_chan, | ||
620 | tup->rx_dma_buf_phys, count, DMA_DEV_TO_MEM, | ||
621 | DMA_PREP_INTERRUPT); | ||
622 | if (!tup->rx_dma_desc) { | ||
623 | dev_err(tup->uport.dev, "Not able to get desc for Rx\n"); | ||
624 | return -EIO; | ||
625 | } | ||
626 | |||
627 | tup->rx_dma_desc->callback = tegra_uart_rx_dma_complete; | ||
628 | tup->rx_dma_desc->callback_param = tup; | ||
629 | dma_sync_single_for_device(tup->uport.dev, tup->rx_dma_buf_phys, | ||
630 | count, DMA_TO_DEVICE); | ||
631 | tup->rx_bytes_requested = count; | ||
632 | tup->rx_cookie = dmaengine_submit(tup->rx_dma_desc); | ||
633 | dma_async_issue_pending(tup->rx_dma_chan); | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static void tegra_uart_handle_modem_signal_change(struct uart_port *u) | ||
638 | { | ||
639 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
640 | unsigned long msr; | ||
641 | |||
642 | msr = tegra_uart_read(tup, UART_MSR); | ||
643 | if (!(msr & UART_MSR_ANY_DELTA)) | ||
644 | return; | ||
645 | |||
646 | if (msr & UART_MSR_TERI) | ||
647 | tup->uport.icount.rng++; | ||
648 | if (msr & UART_MSR_DDSR) | ||
649 | tup->uport.icount.dsr++; | ||
650 | /* We may only get DDCD when HW init and reset */ | ||
651 | if (msr & UART_MSR_DDCD) | ||
652 | uart_handle_dcd_change(&tup->uport, msr & UART_MSR_DCD); | ||
653 | /* Will start/stop_tx accordingly */ | ||
654 | if (msr & UART_MSR_DCTS) | ||
655 | uart_handle_cts_change(&tup->uport, msr & UART_MSR_CTS); | ||
656 | return; | ||
657 | } | ||
658 | |||
659 | static irqreturn_t tegra_uart_isr(int irq, void *data) | ||
660 | { | ||
661 | struct tegra_uart_port *tup = data; | ||
662 | struct uart_port *u = &tup->uport; | ||
663 | unsigned long iir; | ||
664 | unsigned long ier; | ||
665 | bool is_rx_int = false; | ||
666 | unsigned long flags; | ||
667 | |||
668 | spin_lock_irqsave(&u->lock, flags); | ||
669 | while (1) { | ||
670 | iir = tegra_uart_read(tup, UART_IIR); | ||
671 | if (iir & UART_IIR_NO_INT) { | ||
672 | if (is_rx_int) { | ||
673 | tegra_uart_handle_rx_dma(tup); | ||
674 | if (tup->rx_in_progress) { | ||
675 | ier = tup->ier_shadow; | ||
676 | ier |= (UART_IER_RLSI | UART_IER_RTOIE | | ||
677 | TEGRA_UART_IER_EORD); | ||
678 | tup->ier_shadow = ier; | ||
679 | tegra_uart_write(tup, ier, UART_IER); | ||
680 | } | ||
681 | } | ||
682 | spin_unlock_irqrestore(&u->lock, flags); | ||
683 | return IRQ_HANDLED; | ||
684 | } | ||
685 | |||
686 | switch ((iir >> 1) & 0x7) { | ||
687 | case 0: /* Modem signal change interrupt */ | ||
688 | tegra_uart_handle_modem_signal_change(u); | ||
689 | break; | ||
690 | |||
691 | case 1: /* Transmit interrupt only triggered when using PIO */ | ||
692 | tup->ier_shadow &= ~UART_IER_THRI; | ||
693 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
694 | tegra_uart_handle_tx_pio(tup); | ||
695 | break; | ||
696 | |||
697 | case 4: /* End of data */ | ||
698 | case 6: /* Rx timeout */ | ||
699 | case 2: /* Receive */ | ||
700 | if (!is_rx_int) { | ||
701 | is_rx_int = true; | ||
702 | /* Disable Rx interrupts */ | ||
703 | ier = tup->ier_shadow; | ||
704 | ier |= UART_IER_RDI; | ||
705 | tegra_uart_write(tup, ier, UART_IER); | ||
706 | ier &= ~(UART_IER_RDI | UART_IER_RLSI | | ||
707 | UART_IER_RTOIE | TEGRA_UART_IER_EORD); | ||
708 | tup->ier_shadow = ier; | ||
709 | tegra_uart_write(tup, ier, UART_IER); | ||
710 | } | ||
711 | break; | ||
712 | |||
713 | case 3: /* Receive error */ | ||
714 | tegra_uart_decode_rx_error(tup, | ||
715 | tegra_uart_read(tup, UART_LSR)); | ||
716 | break; | ||
717 | |||
718 | case 5: /* break nothing to handle */ | ||
719 | case 7: /* break nothing to handle */ | ||
720 | break; | ||
721 | } | ||
722 | } | ||
723 | } | ||
724 | |||
725 | static void tegra_uart_stop_rx(struct uart_port *u) | ||
726 | { | ||
727 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
728 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
729 | struct tty_port *port = &u->state->port; | ||
730 | struct dma_tx_state state; | ||
731 | unsigned long ier; | ||
732 | int count; | ||
733 | |||
734 | if (tup->rts_active) | ||
735 | set_rts(tup, false); | ||
736 | |||
737 | if (!tup->rx_in_progress) | ||
738 | return; | ||
739 | |||
740 | tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ | ||
741 | |||
742 | ier = tup->ier_shadow; | ||
743 | ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | | ||
744 | TEGRA_UART_IER_EORD); | ||
745 | tup->ier_shadow = ier; | ||
746 | tegra_uart_write(tup, ier, UART_IER); | ||
747 | tup->rx_in_progress = 0; | ||
748 | if (tup->rx_dma_chan) { | ||
749 | dmaengine_terminate_all(tup->rx_dma_chan); | ||
750 | dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); | ||
751 | async_tx_ack(tup->rx_dma_desc); | ||
752 | count = tup->rx_bytes_requested - state.residue; | ||
753 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
754 | tegra_uart_handle_rx_pio(tup, port); | ||
755 | } else { | ||
756 | tegra_uart_handle_rx_pio(tup, port); | ||
757 | } | ||
758 | if (tty) { | ||
759 | tty_flip_buffer_push(port); | ||
760 | tty_kref_put(tty); | ||
761 | } | ||
762 | return; | ||
763 | } | ||
764 | |||
765 | static void tegra_uart_hw_deinit(struct tegra_uart_port *tup) | ||
766 | { | ||
767 | unsigned long flags; | ||
768 | unsigned long char_time = DIV_ROUND_UP(10000000, tup->current_baud); | ||
769 | unsigned long fifo_empty_time = tup->uport.fifosize * char_time; | ||
770 | unsigned long wait_time; | ||
771 | unsigned long lsr; | ||
772 | unsigned long msr; | ||
773 | unsigned long mcr; | ||
774 | |||
775 | /* Disable interrupts */ | ||
776 | tegra_uart_write(tup, 0, UART_IER); | ||
777 | |||
778 | lsr = tegra_uart_read(tup, UART_LSR); | ||
779 | if ((lsr & UART_LSR_TEMT) != UART_LSR_TEMT) { | ||
780 | msr = tegra_uart_read(tup, UART_MSR); | ||
781 | mcr = tegra_uart_read(tup, UART_MCR); | ||
782 | if ((mcr & TEGRA_UART_MCR_CTS_EN) && (msr & UART_MSR_CTS)) | ||
783 | dev_err(tup->uport.dev, | ||
784 | "Tx Fifo not empty, CTS disabled, waiting\n"); | ||
785 | |||
786 | /* Wait for Tx fifo to be empty */ | ||
787 | while ((lsr & UART_LSR_TEMT) != UART_LSR_TEMT) { | ||
788 | wait_time = min(fifo_empty_time, 100lu); | ||
789 | udelay(wait_time); | ||
790 | fifo_empty_time -= wait_time; | ||
791 | if (!fifo_empty_time) { | ||
792 | msr = tegra_uart_read(tup, UART_MSR); | ||
793 | mcr = tegra_uart_read(tup, UART_MCR); | ||
794 | if ((mcr & TEGRA_UART_MCR_CTS_EN) && | ||
795 | (msr & UART_MSR_CTS)) | ||
796 | dev_err(tup->uport.dev, | ||
797 | "Slave not ready\n"); | ||
798 | break; | ||
799 | } | ||
800 | lsr = tegra_uart_read(tup, UART_LSR); | ||
801 | } | ||
802 | } | ||
803 | |||
804 | spin_lock_irqsave(&tup->uport.lock, flags); | ||
805 | /* Reset the Rx and Tx FIFOs */ | ||
806 | tegra_uart_fifo_reset(tup, UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); | ||
807 | tup->current_baud = 0; | ||
808 | spin_unlock_irqrestore(&tup->uport.lock, flags); | ||
809 | |||
810 | clk_disable_unprepare(tup->uart_clk); | ||
811 | } | ||
812 | |||
813 | static int tegra_uart_hw_init(struct tegra_uart_port *tup) | ||
814 | { | ||
815 | int ret; | ||
816 | |||
817 | tup->fcr_shadow = 0; | ||
818 | tup->mcr_shadow = 0; | ||
819 | tup->lcr_shadow = 0; | ||
820 | tup->ier_shadow = 0; | ||
821 | tup->current_baud = 0; | ||
822 | |||
823 | clk_prepare_enable(tup->uart_clk); | ||
824 | |||
825 | /* Reset the UART controller to clear all previous status.*/ | ||
826 | tegra_periph_reset_assert(tup->uart_clk); | ||
827 | udelay(10); | ||
828 | tegra_periph_reset_deassert(tup->uart_clk); | ||
829 | |||
830 | tup->rx_in_progress = 0; | ||
831 | tup->tx_in_progress = 0; | ||
832 | |||
833 | /* | ||
834 | * Set the trigger level | ||
835 | * | ||
836 | * For PIO mode: | ||
837 | * | ||
838 | * For receive, this will interrupt the CPU after that many number of | ||
839 | * bytes are received, for the remaining bytes the receive timeout | ||
840 | * interrupt is received. Rx high watermark is set to 4. | ||
841 | * | ||
842 | * For transmit, if the trasnmit interrupt is enabled, this will | ||
843 | * interrupt the CPU when the number of entries in the FIFO reaches the | ||
844 | * low watermark. Tx low watermark is set to 16 bytes. | ||
845 | * | ||
846 | * For DMA mode: | ||
847 | * | ||
848 | * Set the Tx trigger to 16. This should match the DMA burst size that | ||
849 | * programmed in the DMA registers. | ||
850 | */ | ||
851 | tup->fcr_shadow = UART_FCR_ENABLE_FIFO; | ||
852 | tup->fcr_shadow |= UART_FCR_R_TRIG_01; | ||
853 | tup->fcr_shadow |= TEGRA_UART_TX_TRIG_16B; | ||
854 | tegra_uart_write(tup, tup->fcr_shadow, UART_FCR); | ||
855 | |||
856 | /* | ||
857 | * Initialize the UART with default configuration | ||
858 | * (115200, N, 8, 1) so that the receive DMA buffer may be | ||
859 | * enqueued | ||
860 | */ | ||
861 | tup->lcr_shadow = TEGRA_UART_DEFAULT_LSR; | ||
862 | tegra_set_baudrate(tup, TEGRA_UART_DEFAULT_BAUD); | ||
863 | tup->fcr_shadow |= UART_FCR_DMA_SELECT; | ||
864 | tegra_uart_write(tup, tup->fcr_shadow, UART_FCR); | ||
865 | |||
866 | ret = tegra_uart_start_rx_dma(tup); | ||
867 | if (ret < 0) { | ||
868 | dev_err(tup->uport.dev, "Not able to start Rx DMA\n"); | ||
869 | return ret; | ||
870 | } | ||
871 | tup->rx_in_progress = 1; | ||
872 | |||
873 | /* | ||
874 | * Enable IE_RXS for the receive status interrupts like line errros. | ||
875 | * Enable IE_RX_TIMEOUT to get the bytes which cannot be DMA'd. | ||
876 | * | ||
877 | * If using DMA mode, enable EORD instead of receive interrupt which | ||
878 | * will interrupt after the UART is done with the receive instead of | ||
879 | * the interrupt when the FIFO "threshold" is reached. | ||
880 | * | ||
881 | * EORD is different interrupt than RX_TIMEOUT - RX_TIMEOUT occurs when | ||
882 | * the DATA is sitting in the FIFO and couldn't be transferred to the | ||
883 | * DMA as the DMA size alignment(4 bytes) is not met. EORD will be | ||
884 | * triggered when there is a pause of the incomming data stream for 4 | ||
885 | * characters long. | ||
886 | * | ||
887 | * For pauses in the data which is not aligned to 4 bytes, we get | ||
888 | * both the EORD as well as RX_TIMEOUT - SW sees RX_TIMEOUT first | ||
889 | * then the EORD. | ||
890 | */ | ||
891 | tup->ier_shadow = UART_IER_RLSI | UART_IER_RTOIE | TEGRA_UART_IER_EORD; | ||
892 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, | ||
897 | bool dma_to_memory) | ||
898 | { | ||
899 | struct dma_chan *dma_chan; | ||
900 | unsigned char *dma_buf; | ||
901 | dma_addr_t dma_phys; | ||
902 | int ret; | ||
903 | struct dma_slave_config dma_sconfig; | ||
904 | dma_cap_mask_t mask; | ||
905 | |||
906 | dma_cap_zero(mask); | ||
907 | dma_cap_set(DMA_SLAVE, mask); | ||
908 | dma_chan = dma_request_channel(mask, NULL, NULL); | ||
909 | if (!dma_chan) { | ||
910 | dev_err(tup->uport.dev, | ||
911 | "Dma channel is not available, will try later\n"); | ||
912 | return -EPROBE_DEFER; | ||
913 | } | ||
914 | |||
915 | if (dma_to_memory) { | ||
916 | dma_buf = dma_alloc_coherent(tup->uport.dev, | ||
917 | TEGRA_UART_RX_DMA_BUFFER_SIZE, | ||
918 | &dma_phys, GFP_KERNEL); | ||
919 | if (!dma_buf) { | ||
920 | dev_err(tup->uport.dev, | ||
921 | "Not able to allocate the dma buffer\n"); | ||
922 | dma_release_channel(dma_chan); | ||
923 | return -ENOMEM; | ||
924 | } | ||
925 | } else { | ||
926 | dma_phys = dma_map_single(tup->uport.dev, | ||
927 | tup->uport.state->xmit.buf, UART_XMIT_SIZE, | ||
928 | DMA_TO_DEVICE); | ||
929 | dma_buf = tup->uport.state->xmit.buf; | ||
930 | } | ||
931 | |||
932 | dma_sconfig.slave_id = tup->dma_req_sel; | ||
933 | if (dma_to_memory) { | ||
934 | dma_sconfig.src_addr = tup->uport.mapbase; | ||
935 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
936 | dma_sconfig.src_maxburst = 4; | ||
937 | } else { | ||
938 | dma_sconfig.dst_addr = tup->uport.mapbase; | ||
939 | dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
940 | dma_sconfig.dst_maxburst = 16; | ||
941 | } | ||
942 | |||
943 | ret = dmaengine_slave_config(dma_chan, &dma_sconfig); | ||
944 | if (ret < 0) { | ||
945 | dev_err(tup->uport.dev, | ||
946 | "Dma slave config failed, err = %d\n", ret); | ||
947 | goto scrub; | ||
948 | } | ||
949 | |||
950 | if (dma_to_memory) { | ||
951 | tup->rx_dma_chan = dma_chan; | ||
952 | tup->rx_dma_buf_virt = dma_buf; | ||
953 | tup->rx_dma_buf_phys = dma_phys; | ||
954 | } else { | ||
955 | tup->tx_dma_chan = dma_chan; | ||
956 | tup->tx_dma_buf_virt = dma_buf; | ||
957 | tup->tx_dma_buf_phys = dma_phys; | ||
958 | } | ||
959 | return 0; | ||
960 | |||
961 | scrub: | ||
962 | dma_release_channel(dma_chan); | ||
963 | return ret; | ||
964 | } | ||
965 | |||
966 | static void tegra_uart_dma_channel_free(struct tegra_uart_port *tup, | ||
967 | bool dma_to_memory) | ||
968 | { | ||
969 | struct dma_chan *dma_chan; | ||
970 | |||
971 | if (dma_to_memory) { | ||
972 | dma_free_coherent(tup->uport.dev, TEGRA_UART_RX_DMA_BUFFER_SIZE, | ||
973 | tup->rx_dma_buf_virt, tup->rx_dma_buf_phys); | ||
974 | dma_chan = tup->rx_dma_chan; | ||
975 | tup->rx_dma_chan = NULL; | ||
976 | tup->rx_dma_buf_phys = 0; | ||
977 | tup->rx_dma_buf_virt = NULL; | ||
978 | } else { | ||
979 | dma_unmap_single(tup->uport.dev, tup->tx_dma_buf_phys, | ||
980 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
981 | dma_chan = tup->tx_dma_chan; | ||
982 | tup->tx_dma_chan = NULL; | ||
983 | tup->tx_dma_buf_phys = 0; | ||
984 | tup->tx_dma_buf_virt = NULL; | ||
985 | } | ||
986 | dma_release_channel(dma_chan); | ||
987 | } | ||
988 | |||
989 | static int tegra_uart_startup(struct uart_port *u) | ||
990 | { | ||
991 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
992 | int ret; | ||
993 | |||
994 | ret = tegra_uart_dma_channel_allocate(tup, false); | ||
995 | if (ret < 0) { | ||
996 | dev_err(u->dev, "Tx Dma allocation failed, err = %d\n", ret); | ||
997 | return ret; | ||
998 | } | ||
999 | |||
1000 | ret = tegra_uart_dma_channel_allocate(tup, true); | ||
1001 | if (ret < 0) { | ||
1002 | dev_err(u->dev, "Rx Dma allocation failed, err = %d\n", ret); | ||
1003 | goto fail_rx_dma; | ||
1004 | } | ||
1005 | |||
1006 | ret = tegra_uart_hw_init(tup); | ||
1007 | if (ret < 0) { | ||
1008 | dev_err(u->dev, "Uart HW init failed, err = %d\n", ret); | ||
1009 | goto fail_hw_init; | ||
1010 | } | ||
1011 | |||
1012 | ret = request_irq(u->irq, tegra_uart_isr, IRQF_DISABLED, | ||
1013 | dev_name(u->dev), tup); | ||
1014 | if (ret < 0) { | ||
1015 | dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq); | ||
1016 | goto fail_hw_init; | ||
1017 | } | ||
1018 | return 0; | ||
1019 | |||
1020 | fail_hw_init: | ||
1021 | tegra_uart_dma_channel_free(tup, true); | ||
1022 | fail_rx_dma: | ||
1023 | tegra_uart_dma_channel_free(tup, false); | ||
1024 | return ret; | ||
1025 | } | ||
1026 | |||
1027 | static void tegra_uart_shutdown(struct uart_port *u) | ||
1028 | { | ||
1029 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1030 | |||
1031 | tegra_uart_hw_deinit(tup); | ||
1032 | |||
1033 | tup->rx_in_progress = 0; | ||
1034 | tup->tx_in_progress = 0; | ||
1035 | |||
1036 | tegra_uart_dma_channel_free(tup, true); | ||
1037 | tegra_uart_dma_channel_free(tup, false); | ||
1038 | free_irq(u->irq, tup); | ||
1039 | } | ||
1040 | |||
1041 | static void tegra_uart_enable_ms(struct uart_port *u) | ||
1042 | { | ||
1043 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1044 | |||
1045 | if (tup->enable_modem_interrupt) { | ||
1046 | tup->ier_shadow |= UART_IER_MSI; | ||
1047 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | static void tegra_uart_set_termios(struct uart_port *u, | ||
1052 | struct ktermios *termios, struct ktermios *oldtermios) | ||
1053 | { | ||
1054 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1055 | unsigned int baud; | ||
1056 | unsigned long flags; | ||
1057 | unsigned int lcr; | ||
1058 | int symb_bit = 1; | ||
1059 | struct clk *parent_clk = clk_get_parent(tup->uart_clk); | ||
1060 | unsigned long parent_clk_rate = clk_get_rate(parent_clk); | ||
1061 | int max_divider = (tup->cdata->support_clk_src_div) ? 0x7FFF : 0xFFFF; | ||
1062 | |||
1063 | max_divider *= 16; | ||
1064 | spin_lock_irqsave(&u->lock, flags); | ||
1065 | |||
1066 | /* Changing configuration, it is safe to stop any rx now */ | ||
1067 | if (tup->rts_active) | ||
1068 | set_rts(tup, false); | ||
1069 | |||
1070 | /* Clear all interrupts as configuration is going to be change */ | ||
1071 | tegra_uart_write(tup, tup->ier_shadow | UART_IER_RDI, UART_IER); | ||
1072 | tegra_uart_read(tup, UART_IER); | ||
1073 | tegra_uart_write(tup, 0, UART_IER); | ||
1074 | tegra_uart_read(tup, UART_IER); | ||
1075 | |||
1076 | /* Parity */ | ||
1077 | lcr = tup->lcr_shadow; | ||
1078 | lcr &= ~UART_LCR_PARITY; | ||
1079 | |||
1080 | /* CMSPAR isn't supported by this driver */ | ||
1081 | termios->c_cflag &= ~CMSPAR; | ||
1082 | |||
1083 | if ((termios->c_cflag & PARENB) == PARENB) { | ||
1084 | symb_bit++; | ||
1085 | if (termios->c_cflag & PARODD) { | ||
1086 | lcr |= UART_LCR_PARITY; | ||
1087 | lcr &= ~UART_LCR_EPAR; | ||
1088 | lcr &= ~UART_LCR_SPAR; | ||
1089 | } else { | ||
1090 | lcr |= UART_LCR_PARITY; | ||
1091 | lcr |= UART_LCR_EPAR; | ||
1092 | lcr &= ~UART_LCR_SPAR; | ||
1093 | } | ||
1094 | } | ||
1095 | |||
1096 | lcr &= ~UART_LCR_WLEN8; | ||
1097 | switch (termios->c_cflag & CSIZE) { | ||
1098 | case CS5: | ||
1099 | lcr |= UART_LCR_WLEN5; | ||
1100 | symb_bit += 5; | ||
1101 | break; | ||
1102 | case CS6: | ||
1103 | lcr |= UART_LCR_WLEN6; | ||
1104 | symb_bit += 6; | ||
1105 | break; | ||
1106 | case CS7: | ||
1107 | lcr |= UART_LCR_WLEN7; | ||
1108 | symb_bit += 7; | ||
1109 | break; | ||
1110 | default: | ||
1111 | lcr |= UART_LCR_WLEN8; | ||
1112 | symb_bit += 8; | ||
1113 | break; | ||
1114 | } | ||
1115 | |||
1116 | /* Stop bits */ | ||
1117 | if (termios->c_cflag & CSTOPB) { | ||
1118 | lcr |= UART_LCR_STOP; | ||
1119 | symb_bit += 2; | ||
1120 | } else { | ||
1121 | lcr &= ~UART_LCR_STOP; | ||
1122 | symb_bit++; | ||
1123 | } | ||
1124 | |||
1125 | tegra_uart_write(tup, lcr, UART_LCR); | ||
1126 | tup->lcr_shadow = lcr; | ||
1127 | tup->symb_bit = symb_bit; | ||
1128 | |||
1129 | /* Baud rate. */ | ||
1130 | baud = uart_get_baud_rate(u, termios, oldtermios, | ||
1131 | parent_clk_rate/max_divider, | ||
1132 | parent_clk_rate/16); | ||
1133 | spin_unlock_irqrestore(&u->lock, flags); | ||
1134 | tegra_set_baudrate(tup, baud); | ||
1135 | if (tty_termios_baud_rate(termios)) | ||
1136 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
1137 | spin_lock_irqsave(&u->lock, flags); | ||
1138 | |||
1139 | /* Flow control */ | ||
1140 | if (termios->c_cflag & CRTSCTS) { | ||
1141 | tup->mcr_shadow |= TEGRA_UART_MCR_CTS_EN; | ||
1142 | tup->mcr_shadow &= ~TEGRA_UART_MCR_RTS_EN; | ||
1143 | tegra_uart_write(tup, tup->mcr_shadow, UART_MCR); | ||
1144 | /* if top layer has asked to set rts active then do so here */ | ||
1145 | if (tup->rts_active) | ||
1146 | set_rts(tup, true); | ||
1147 | } else { | ||
1148 | tup->mcr_shadow &= ~TEGRA_UART_MCR_CTS_EN; | ||
1149 | tup->mcr_shadow &= ~TEGRA_UART_MCR_RTS_EN; | ||
1150 | tegra_uart_write(tup, tup->mcr_shadow, UART_MCR); | ||
1151 | } | ||
1152 | |||
1153 | /* update the port timeout based on new settings */ | ||
1154 | uart_update_timeout(u, termios->c_cflag, baud); | ||
1155 | |||
1156 | /* Make sure all write has completed */ | ||
1157 | tegra_uart_read(tup, UART_IER); | ||
1158 | |||
1159 | /* Reenable interrupt */ | ||
1160 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
1161 | tegra_uart_read(tup, UART_IER); | ||
1162 | |||
1163 | spin_unlock_irqrestore(&u->lock, flags); | ||
1164 | return; | ||
1165 | } | ||
1166 | |||
1167 | /* | ||
1168 | * Flush any TX data submitted for DMA and PIO. Called when the | ||
1169 | * TX circular buffer is reset. | ||
1170 | */ | ||
1171 | static void tegra_uart_flush_buffer(struct uart_port *u) | ||
1172 | { | ||
1173 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1174 | |||
1175 | tup->tx_bytes = 0; | ||
1176 | if (tup->tx_dma_chan) | ||
1177 | dmaengine_terminate_all(tup->tx_dma_chan); | ||
1178 | return; | ||
1179 | } | ||
1180 | |||
1181 | static const char *tegra_uart_type(struct uart_port *u) | ||
1182 | { | ||
1183 | return TEGRA_UART_TYPE; | ||
1184 | } | ||
1185 | |||
1186 | static struct uart_ops tegra_uart_ops = { | ||
1187 | .tx_empty = tegra_uart_tx_empty, | ||
1188 | .set_mctrl = tegra_uart_set_mctrl, | ||
1189 | .get_mctrl = tegra_uart_get_mctrl, | ||
1190 | .stop_tx = tegra_uart_stop_tx, | ||
1191 | .start_tx = tegra_uart_start_tx, | ||
1192 | .stop_rx = tegra_uart_stop_rx, | ||
1193 | .flush_buffer = tegra_uart_flush_buffer, | ||
1194 | .enable_ms = tegra_uart_enable_ms, | ||
1195 | .break_ctl = tegra_uart_break_ctl, | ||
1196 | .startup = tegra_uart_startup, | ||
1197 | .shutdown = tegra_uart_shutdown, | ||
1198 | .set_termios = tegra_uart_set_termios, | ||
1199 | .type = tegra_uart_type, | ||
1200 | .request_port = tegra_uart_request_port, | ||
1201 | .release_port = tegra_uart_release_port, | ||
1202 | }; | ||
1203 | |||
1204 | static struct uart_driver tegra_uart_driver = { | ||
1205 | .owner = THIS_MODULE, | ||
1206 | .driver_name = "tegra_hsuart", | ||
1207 | .dev_name = "ttyTHS", | ||
1208 | .cons = 0, | ||
1209 | .nr = TEGRA_UART_MAXIMUM, | ||
1210 | }; | ||
1211 | |||
1212 | static int tegra_uart_parse_dt(struct platform_device *pdev, | ||
1213 | struct tegra_uart_port *tup) | ||
1214 | { | ||
1215 | struct device_node *np = pdev->dev.of_node; | ||
1216 | u32 of_dma[2]; | ||
1217 | int port; | ||
1218 | |||
1219 | if (of_property_read_u32_array(np, "nvidia,dma-request-selector", | ||
1220 | of_dma, 2) >= 0) { | ||
1221 | tup->dma_req_sel = of_dma[1]; | ||
1222 | } else { | ||
1223 | dev_err(&pdev->dev, "missing dma requestor in device tree\n"); | ||
1224 | return -EINVAL; | ||
1225 | } | ||
1226 | |||
1227 | port = of_alias_get_id(np, "serial"); | ||
1228 | if (port < 0) { | ||
1229 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port); | ||
1230 | return port; | ||
1231 | } | ||
1232 | tup->uport.line = port; | ||
1233 | |||
1234 | tup->enable_modem_interrupt = of_property_read_bool(np, | ||
1235 | "nvidia,enable-modem-interrupt"); | ||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
1239 | struct tegra_uart_chip_data tegra20_uart_chip_data = { | ||
1240 | .tx_fifo_full_status = false, | ||
1241 | .allow_txfifo_reset_fifo_mode = true, | ||
1242 | .support_clk_src_div = false, | ||
1243 | }; | ||
1244 | |||
1245 | struct tegra_uart_chip_data tegra30_uart_chip_data = { | ||
1246 | .tx_fifo_full_status = true, | ||
1247 | .allow_txfifo_reset_fifo_mode = false, | ||
1248 | .support_clk_src_div = true, | ||
1249 | }; | ||
1250 | |||
1251 | static struct of_device_id tegra_uart_of_match[] = { | ||
1252 | { | ||
1253 | .compatible = "nvidia,tegra30-hsuart", | ||
1254 | .data = &tegra30_uart_chip_data, | ||
1255 | }, { | ||
1256 | .compatible = "nvidia,tegra20-hsuart", | ||
1257 | .data = &tegra20_uart_chip_data, | ||
1258 | }, { | ||
1259 | }, | ||
1260 | }; | ||
1261 | MODULE_DEVICE_TABLE(of, tegra_uart_of_match); | ||
1262 | |||
1263 | static int tegra_uart_probe(struct platform_device *pdev) | ||
1264 | { | ||
1265 | struct tegra_uart_port *tup; | ||
1266 | struct uart_port *u; | ||
1267 | struct resource *resource; | ||
1268 | int ret; | ||
1269 | const struct tegra_uart_chip_data *cdata; | ||
1270 | const struct of_device_id *match; | ||
1271 | |||
1272 | match = of_match_device(tegra_uart_of_match, &pdev->dev); | ||
1273 | if (!match) { | ||
1274 | dev_err(&pdev->dev, "Error: No device match found\n"); | ||
1275 | return -ENODEV; | ||
1276 | } | ||
1277 | cdata = match->data; | ||
1278 | |||
1279 | tup = devm_kzalloc(&pdev->dev, sizeof(*tup), GFP_KERNEL); | ||
1280 | if (!tup) { | ||
1281 | dev_err(&pdev->dev, "Failed to allocate memory for tup\n"); | ||
1282 | return -ENOMEM; | ||
1283 | } | ||
1284 | |||
1285 | ret = tegra_uart_parse_dt(pdev, tup); | ||
1286 | if (ret < 0) | ||
1287 | return ret; | ||
1288 | |||
1289 | u = &tup->uport; | ||
1290 | u->dev = &pdev->dev; | ||
1291 | u->ops = &tegra_uart_ops; | ||
1292 | u->type = PORT_TEGRA; | ||
1293 | u->fifosize = 32; | ||
1294 | tup->cdata = cdata; | ||
1295 | |||
1296 | platform_set_drvdata(pdev, tup); | ||
1297 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1298 | if (!resource) { | ||
1299 | dev_err(&pdev->dev, "No IO memory resource\n"); | ||
1300 | return -ENODEV; | ||
1301 | } | ||
1302 | |||
1303 | u->mapbase = resource->start; | ||
1304 | u->membase = devm_request_and_ioremap(&pdev->dev, resource); | ||
1305 | if (!u->membase) { | ||
1306 | dev_err(&pdev->dev, "memregion/iomap address req failed\n"); | ||
1307 | return -EADDRNOTAVAIL; | ||
1308 | } | ||
1309 | |||
1310 | tup->uart_clk = devm_clk_get(&pdev->dev, NULL); | ||
1311 | if (IS_ERR(tup->uart_clk)) { | ||
1312 | dev_err(&pdev->dev, "Couldn't get the clock\n"); | ||
1313 | return PTR_ERR(tup->uart_clk); | ||
1314 | } | ||
1315 | |||
1316 | u->iotype = UPIO_MEM32; | ||
1317 | u->irq = platform_get_irq(pdev, 0); | ||
1318 | u->regshift = 2; | ||
1319 | ret = uart_add_one_port(&tegra_uart_driver, u); | ||
1320 | if (ret < 0) { | ||
1321 | dev_err(&pdev->dev, "Failed to add uart port, err %d\n", ret); | ||
1322 | return ret; | ||
1323 | } | ||
1324 | return ret; | ||
1325 | } | ||
1326 | |||
1327 | static int tegra_uart_remove(struct platform_device *pdev) | ||
1328 | { | ||
1329 | struct tegra_uart_port *tup = platform_get_drvdata(pdev); | ||
1330 | struct uart_port *u = &tup->uport; | ||
1331 | |||
1332 | uart_remove_one_port(&tegra_uart_driver, u); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | #ifdef CONFIG_PM_SLEEP | ||
1337 | static int tegra_uart_suspend(struct device *dev) | ||
1338 | { | ||
1339 | struct tegra_uart_port *tup = dev_get_drvdata(dev); | ||
1340 | struct uart_port *u = &tup->uport; | ||
1341 | |||
1342 | return uart_suspend_port(&tegra_uart_driver, u); | ||
1343 | } | ||
1344 | |||
1345 | static int tegra_uart_resume(struct device *dev) | ||
1346 | { | ||
1347 | struct tegra_uart_port *tup = dev_get_drvdata(dev); | ||
1348 | struct uart_port *u = &tup->uport; | ||
1349 | |||
1350 | return uart_resume_port(&tegra_uart_driver, u); | ||
1351 | } | ||
1352 | #endif | ||
1353 | |||
1354 | static const struct dev_pm_ops tegra_uart_pm_ops = { | ||
1355 | SET_SYSTEM_SLEEP_PM_OPS(tegra_uart_suspend, tegra_uart_resume) | ||
1356 | }; | ||
1357 | |||
1358 | static struct platform_driver tegra_uart_platform_driver = { | ||
1359 | .probe = tegra_uart_probe, | ||
1360 | .remove = tegra_uart_remove, | ||
1361 | .driver = { | ||
1362 | .name = "serial-tegra", | ||
1363 | .of_match_table = tegra_uart_of_match, | ||
1364 | .pm = &tegra_uart_pm_ops, | ||
1365 | }, | ||
1366 | }; | ||
1367 | |||
1368 | static int __init tegra_uart_init(void) | ||
1369 | { | ||
1370 | int ret; | ||
1371 | |||
1372 | ret = uart_register_driver(&tegra_uart_driver); | ||
1373 | if (ret < 0) { | ||
1374 | pr_err("Could not register %s driver\n", | ||
1375 | tegra_uart_driver.driver_name); | ||
1376 | return ret; | ||
1377 | } | ||
1378 | |||
1379 | ret = platform_driver_register(&tegra_uart_platform_driver); | ||
1380 | if (ret < 0) { | ||
1381 | pr_err("Uart platfrom driver register failed, e = %d\n", ret); | ||
1382 | uart_unregister_driver(&tegra_uart_driver); | ||
1383 | return ret; | ||
1384 | } | ||
1385 | return 0; | ||
1386 | } | ||
1387 | |||
1388 | static void __exit tegra_uart_exit(void) | ||
1389 | { | ||
1390 | pr_info("Unloading tegra uart driver\n"); | ||
1391 | platform_driver_unregister(&tegra_uart_platform_driver); | ||
1392 | uart_unregister_driver(&tegra_uart_driver); | ||
1393 | } | ||
1394 | |||
1395 | module_init(tegra_uart_init); | ||
1396 | module_exit(tegra_uart_exit); | ||
1397 | |||
1398 | MODULE_ALIAS("platform:serial-tegra"); | ||
1399 | MODULE_DESCRIPTION("High speed UART driver for tegra chipset"); | ||
1400 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
1401 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2c7230aaefd4..a400002dfa84 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -59,7 +59,8 @@ static struct lock_class_key port_lock_key; | |||
59 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | 59 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
60 | struct ktermios *old_termios); | 60 | struct ktermios *old_termios); |
61 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); | 61 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); |
62 | static void uart_change_pm(struct uart_state *state, int pm_state); | 62 | static void uart_change_pm(struct uart_state *state, |
63 | enum uart_pm_state pm_state); | ||
63 | 64 | ||
64 | static void uart_port_shutdown(struct tty_port *port); | 65 | static void uart_port_shutdown(struct tty_port *port); |
65 | 66 | ||
@@ -866,9 +867,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
866 | port->closing_wait = closing_wait; | 867 | port->closing_wait = closing_wait; |
867 | if (new_info->xmit_fifo_size) | 868 | if (new_info->xmit_fifo_size) |
868 | uport->fifosize = new_info->xmit_fifo_size; | 869 | uport->fifosize = new_info->xmit_fifo_size; |
869 | if (port->tty) | 870 | port->low_latency = (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; |
870 | port->tty->low_latency = | ||
871 | (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
872 | 871 | ||
873 | check_and_exit: | 872 | check_and_exit: |
874 | retval = 0; | 873 | retval = 0; |
@@ -1308,9 +1307,10 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1308 | } | 1307 | } |
1309 | 1308 | ||
1310 | /* | 1309 | /* |
1311 | * In 2.4.5, calls to this will be serialized via the BKL in | 1310 | * Calls to uart_close() are serialised via the tty_lock in |
1312 | * linux/drivers/char/tty_io.c:tty_release() | 1311 | * drivers/tty/tty_io.c:tty_release() |
1313 | * linux/drivers/char/tty_io.c:do_tty_handup() | 1312 | * drivers/tty/tty_io.c:do_tty_hangup() |
1313 | * This runs from a workqueue and can sleep for a _short_ time only. | ||
1314 | */ | 1314 | */ |
1315 | static void uart_close(struct tty_struct *tty, struct file *filp) | 1315 | static void uart_close(struct tty_struct *tty, struct file *filp) |
1316 | { | 1316 | { |
@@ -1365,7 +1365,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1365 | spin_lock_irqsave(&port->lock, flags); | 1365 | spin_lock_irqsave(&port->lock, flags); |
1366 | } else if (!uart_console(uport)) { | 1366 | } else if (!uart_console(uport)) { |
1367 | spin_unlock_irqrestore(&port->lock, flags); | 1367 | spin_unlock_irqrestore(&port->lock, flags); |
1368 | uart_change_pm(state, 3); | 1368 | uart_change_pm(state, UART_PM_STATE_OFF); |
1369 | spin_lock_irqsave(&port->lock, flags); | 1369 | spin_lock_irqsave(&port->lock, flags); |
1370 | } | 1370 | } |
1371 | 1371 | ||
@@ -1437,10 +1437,9 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | /* | 1439 | /* |
1440 | * This is called with the BKL held in | 1440 | * Calls to uart_hangup() are serialised by the tty_lock in |
1441 | * linux/drivers/char/tty_io.c:do_tty_hangup() | 1441 | * drivers/tty/tty_io.c:do_tty_hangup() |
1442 | * We're called from the eventd thread, so we can sleep for | 1442 | * This runs from a workqueue and can sleep for a _short_ time only. |
1443 | * a _short_ time only. | ||
1444 | */ | 1443 | */ |
1445 | static void uart_hangup(struct tty_struct *tty) | 1444 | static void uart_hangup(struct tty_struct *tty) |
1446 | { | 1445 | { |
@@ -1521,8 +1520,8 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) | |||
1521 | } | 1520 | } |
1522 | 1521 | ||
1523 | /* | 1522 | /* |
1524 | * calls to uart_open are serialised by the BKL in | 1523 | * Calls to uart_open are serialised by the tty_lock in |
1525 | * fs/char_dev.c:chrdev_open() | 1524 | * drivers/tty/tty_io.c:tty_open() |
1526 | * Note that if this fails, then uart_close() _will_ be called. | 1525 | * Note that if this fails, then uart_close() _will_ be called. |
1527 | * | 1526 | * |
1528 | * In time, we want to scrap the "opening nonpresent ports" | 1527 | * In time, we want to scrap the "opening nonpresent ports" |
@@ -1564,7 +1563,8 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1564 | */ | 1563 | */ |
1565 | tty->driver_data = state; | 1564 | tty->driver_data = state; |
1566 | state->uart_port->state = state; | 1565 | state->uart_port->state = state; |
1567 | tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; | 1566 | state->port.low_latency = |
1567 | (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
1568 | tty_port_tty_set(port, tty); | 1568 | tty_port_tty_set(port, tty); |
1569 | 1569 | ||
1570 | /* | 1570 | /* |
@@ -1579,7 +1579,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1579 | * Make sure the device is in D0 state. | 1579 | * Make sure the device is in D0 state. |
1580 | */ | 1580 | */ |
1581 | if (port->count == 1) | 1581 | if (port->count == 1) |
1582 | uart_change_pm(state, 0); | 1582 | uart_change_pm(state, UART_PM_STATE_ON); |
1583 | 1583 | ||
1584 | /* | 1584 | /* |
1585 | * Start up the serial port. | 1585 | * Start up the serial port. |
@@ -1620,7 +1620,7 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1620 | { | 1620 | { |
1621 | struct uart_state *state = drv->state + i; | 1621 | struct uart_state *state = drv->state + i; |
1622 | struct tty_port *port = &state->port; | 1622 | struct tty_port *port = &state->port; |
1623 | int pm_state; | 1623 | enum uart_pm_state pm_state; |
1624 | struct uart_port *uport = state->uart_port; | 1624 | struct uart_port *uport = state->uart_port; |
1625 | char stat_buf[32]; | 1625 | char stat_buf[32]; |
1626 | unsigned int status; | 1626 | unsigned int status; |
@@ -1645,12 +1645,12 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1645 | if (capable(CAP_SYS_ADMIN)) { | 1645 | if (capable(CAP_SYS_ADMIN)) { |
1646 | mutex_lock(&port->mutex); | 1646 | mutex_lock(&port->mutex); |
1647 | pm_state = state->pm_state; | 1647 | pm_state = state->pm_state; |
1648 | if (pm_state) | 1648 | if (pm_state != UART_PM_STATE_ON) |
1649 | uart_change_pm(state, 0); | 1649 | uart_change_pm(state, UART_PM_STATE_ON); |
1650 | spin_lock_irq(&uport->lock); | 1650 | spin_lock_irq(&uport->lock); |
1651 | status = uport->ops->get_mctrl(uport); | 1651 | status = uport->ops->get_mctrl(uport); |
1652 | spin_unlock_irq(&uport->lock); | 1652 | spin_unlock_irq(&uport->lock); |
1653 | if (pm_state) | 1653 | if (pm_state != UART_PM_STATE_ON) |
1654 | uart_change_pm(state, pm_state); | 1654 | uart_change_pm(state, pm_state); |
1655 | mutex_unlock(&port->mutex); | 1655 | mutex_unlock(&port->mutex); |
1656 | 1656 | ||
@@ -1897,7 +1897,8 @@ EXPORT_SYMBOL_GPL(uart_set_options); | |||
1897 | * | 1897 | * |
1898 | * Locking: port->mutex has to be held | 1898 | * Locking: port->mutex has to be held |
1899 | */ | 1899 | */ |
1900 | static void uart_change_pm(struct uart_state *state, int pm_state) | 1900 | static void uart_change_pm(struct uart_state *state, |
1901 | enum uart_pm_state pm_state) | ||
1901 | { | 1902 | { |
1902 | struct uart_port *port = state->uart_port; | 1903 | struct uart_port *port = state->uart_port; |
1903 | 1904 | ||
@@ -1982,7 +1983,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
1982 | console_stop(uport->cons); | 1983 | console_stop(uport->cons); |
1983 | 1984 | ||
1984 | if (console_suspend_enabled || !uart_console(uport)) | 1985 | if (console_suspend_enabled || !uart_console(uport)) |
1985 | uart_change_pm(state, 3); | 1986 | uart_change_pm(state, UART_PM_STATE_OFF); |
1986 | 1987 | ||
1987 | mutex_unlock(&port->mutex); | 1988 | mutex_unlock(&port->mutex); |
1988 | 1989 | ||
@@ -2027,7 +2028,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2027 | termios = port->tty->termios; | 2028 | termios = port->tty->termios; |
2028 | 2029 | ||
2029 | if (console_suspend_enabled) | 2030 | if (console_suspend_enabled) |
2030 | uart_change_pm(state, 0); | 2031 | uart_change_pm(state, UART_PM_STATE_ON); |
2031 | uport->ops->set_termios(uport, &termios, NULL); | 2032 | uport->ops->set_termios(uport, &termios, NULL); |
2032 | if (console_suspend_enabled) | 2033 | if (console_suspend_enabled) |
2033 | console_start(uport->cons); | 2034 | console_start(uport->cons); |
@@ -2037,7 +2038,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2037 | const struct uart_ops *ops = uport->ops; | 2038 | const struct uart_ops *ops = uport->ops; |
2038 | int ret; | 2039 | int ret; |
2039 | 2040 | ||
2040 | uart_change_pm(state, 0); | 2041 | uart_change_pm(state, UART_PM_STATE_ON); |
2041 | spin_lock_irq(&uport->lock); | 2042 | spin_lock_irq(&uport->lock); |
2042 | ops->set_mctrl(uport, 0); | 2043 | ops->set_mctrl(uport, 0); |
2043 | spin_unlock_irq(&uport->lock); | 2044 | spin_unlock_irq(&uport->lock); |
@@ -2137,7 +2138,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
2137 | uart_report_port(drv, port); | 2138 | uart_report_port(drv, port); |
2138 | 2139 | ||
2139 | /* Power up port for set_mctrl() */ | 2140 | /* Power up port for set_mctrl() */ |
2140 | uart_change_pm(state, 0); | 2141 | uart_change_pm(state, UART_PM_STATE_ON); |
2141 | 2142 | ||
2142 | /* | 2143 | /* |
2143 | * Ensure that the modem control lines are de-activated. | 2144 | * Ensure that the modem control lines are de-activated. |
@@ -2161,7 +2162,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
2161 | * console if we have one. | 2162 | * console if we have one. |
2162 | */ | 2163 | */ |
2163 | if (!uart_console(port)) | 2164 | if (!uart_console(port)) |
2164 | uart_change_pm(state, 3); | 2165 | uart_change_pm(state, UART_PM_STATE_OFF); |
2165 | } | 2166 | } |
2166 | } | 2167 | } |
2167 | 2168 | ||
@@ -2588,7 +2589,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2588 | } | 2589 | } |
2589 | 2590 | ||
2590 | state->uart_port = uport; | 2591 | state->uart_port = uport; |
2591 | state->pm_state = -1; | 2592 | state->pm_state = UART_PM_STATE_UNDEFINED; |
2592 | 2593 | ||
2593 | uport->cons = drv->cons; | 2594 | uport->cons = drv->cons; |
2594 | uport->state = state; | 2595 | uport->state = state; |
@@ -2642,6 +2643,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2642 | { | 2643 | { |
2643 | struct uart_state *state = drv->state + uport->line; | 2644 | struct uart_state *state = drv->state + uport->line; |
2644 | struct tty_port *port = &state->port; | 2645 | struct tty_port *port = &state->port; |
2646 | int ret = 0; | ||
2645 | 2647 | ||
2646 | BUG_ON(in_interrupt()); | 2648 | BUG_ON(in_interrupt()); |
2647 | 2649 | ||
@@ -2656,6 +2658,11 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2656 | * succeeding while we shut down the port. | 2658 | * succeeding while we shut down the port. |
2657 | */ | 2659 | */ |
2658 | mutex_lock(&port->mutex); | 2660 | mutex_lock(&port->mutex); |
2661 | if (!state->uart_port) { | ||
2662 | mutex_unlock(&port->mutex); | ||
2663 | ret = -EINVAL; | ||
2664 | goto out; | ||
2665 | } | ||
2659 | uport->flags |= UPF_DEAD; | 2666 | uport->flags |= UPF_DEAD; |
2660 | mutex_unlock(&port->mutex); | 2667 | mutex_unlock(&port->mutex); |
2661 | 2668 | ||
@@ -2679,9 +2686,10 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2679 | uport->type = PORT_UNKNOWN; | 2686 | uport->type = PORT_UNKNOWN; |
2680 | 2687 | ||
2681 | state->uart_port = NULL; | 2688 | state->uart_port = NULL; |
2689 | out: | ||
2682 | mutex_unlock(&port_mutex); | 2690 | mutex_unlock(&port_mutex); |
2683 | 2691 | ||
2684 | return 0; | 2692 | return ret; |
2685 | } | 2693 | } |
2686 | 2694 | ||
2687 | /* | 2695 | /* |
@@ -2715,22 +2723,17 @@ EXPORT_SYMBOL(uart_match_port); | |||
2715 | */ | 2723 | */ |
2716 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | 2724 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) |
2717 | { | 2725 | { |
2718 | struct uart_state *state = uport->state; | 2726 | struct tty_port *port = &uport->state->port; |
2719 | struct tty_port *port = &state->port; | ||
2720 | struct tty_ldisc *ld = NULL; | ||
2721 | struct pps_event_time ts; | ||
2722 | struct tty_struct *tty = port->tty; | 2727 | struct tty_struct *tty = port->tty; |
2728 | struct tty_ldisc *ld = tty ? tty_ldisc_ref(tty) : NULL; | ||
2723 | 2729 | ||
2724 | if (tty) | 2730 | if (ld) { |
2725 | ld = tty_ldisc_ref(tty); | 2731 | if (ld->ops->dcd_change) |
2726 | if (ld && ld->ops->dcd_change) | 2732 | ld->ops->dcd_change(tty, status); |
2727 | pps_get_ts(&ts); | 2733 | tty_ldisc_deref(ld); |
2734 | } | ||
2728 | 2735 | ||
2729 | uport->icount.dcd++; | 2736 | uport->icount.dcd++; |
2730 | #ifdef CONFIG_HARD_PPS | ||
2731 | if ((uport->flags & UPF_HARDPPS_CD) && status) | ||
2732 | hardpps(); | ||
2733 | #endif | ||
2734 | 2737 | ||
2735 | if (port->flags & ASYNC_CHECK_CD) { | 2738 | if (port->flags & ASYNC_CHECK_CD) { |
2736 | if (status) | 2739 | if (status) |
@@ -2738,11 +2741,6 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | |||
2738 | else if (tty) | 2741 | else if (tty) |
2739 | tty_hangup(tty); | 2742 | tty_hangup(tty); |
2740 | } | 2743 | } |
2741 | |||
2742 | if (ld && ld->ops->dcd_change) | ||
2743 | ld->ops->dcd_change(tty, status, &ts); | ||
2744 | if (ld) | ||
2745 | tty_ldisc_deref(ld); | ||
2746 | } | 2744 | } |
2747 | EXPORT_SYMBOL_GPL(uart_handle_dcd_change); | 2745 | EXPORT_SYMBOL_GPL(uart_handle_dcd_change); |
2748 | 2746 | ||
@@ -2790,10 +2788,10 @@ EXPORT_SYMBOL_GPL(uart_handle_cts_change); | |||
2790 | void uart_insert_char(struct uart_port *port, unsigned int status, | 2788 | void uart_insert_char(struct uart_port *port, unsigned int status, |
2791 | unsigned int overrun, unsigned int ch, unsigned int flag) | 2789 | unsigned int overrun, unsigned int ch, unsigned int flag) |
2792 | { | 2790 | { |
2793 | struct tty_struct *tty = port->state->port.tty; | 2791 | struct tty_port *tport = &port->state->port; |
2794 | 2792 | ||
2795 | if ((status & port->ignore_status_mask & ~overrun) == 0) | 2793 | if ((status & port->ignore_status_mask & ~overrun) == 0) |
2796 | if (tty_insert_flip_char(tty, ch, flag) == 0) | 2794 | if (tty_insert_flip_char(tport, ch, flag) == 0) |
2797 | ++port->icount.buf_overrun; | 2795 | ++port->icount.buf_overrun; |
2798 | 2796 | ||
2799 | /* | 2797 | /* |
@@ -2801,7 +2799,7 @@ void uart_insert_char(struct uart_port *port, unsigned int status, | |||
2801 | * it doesn't affect the current character. | 2799 | * it doesn't affect the current character. |
2802 | */ | 2800 | */ |
2803 | if (status & ~port->ignore_status_mask & overrun) | 2801 | if (status & ~port->ignore_status_mask & overrun) |
2804 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN) == 0) | 2802 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN) == 0) |
2805 | ++port->icount.buf_overrun; | 2803 | ++port->icount.buf_overrun; |
2806 | } | 2804 | } |
2807 | EXPORT_SYMBOL_GPL(uart_insert_char); | 2805 | EXPORT_SYMBOL_GPL(uart_insert_char); |
diff --git a/drivers/tty/serial/serial_ks8695.c b/drivers/tty/serial/serial_ks8695.c index 9bd004f9da89..e1caa99e3d3b 100644 --- a/drivers/tty/serial/serial_ks8695.c +++ b/drivers/tty/serial/serial_ks8695.c | |||
@@ -153,7 +153,6 @@ static void ks8695uart_disable_ms(struct uart_port *port) | |||
153 | static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) | 153 | static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) |
154 | { | 154 | { |
155 | struct uart_port *port = dev_id; | 155 | struct uart_port *port = dev_id; |
156 | struct tty_struct *tty = port->state->port.tty; | ||
157 | unsigned int status, ch, lsr, flg, max_count = 256; | 156 | unsigned int status, ch, lsr, flg, max_count = 256; |
158 | 157 | ||
159 | status = UART_GET_LSR(port); /* clears pending LSR interrupts */ | 158 | status = UART_GET_LSR(port); /* clears pending LSR interrupts */ |
@@ -200,7 +199,7 @@ static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) | |||
200 | ignore_char: | 199 | ignore_char: |
201 | status = UART_GET_LSR(port); | 200 | status = UART_GET_LSR(port); |
202 | } | 201 | } |
203 | tty_flip_buffer_push(tty); | 202 | tty_flip_buffer_push(&port->state->port); |
204 | 203 | ||
205 | return IRQ_HANDLED; | 204 | return IRQ_HANDLED; |
206 | } | 205 | } |
diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index b52b21aeb250..fe48a0c2b4ca 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c | |||
@@ -277,7 +277,6 @@ static void serial_txx9_initialize(struct uart_port *port) | |||
277 | static inline void | 277 | static inline void |
278 | receive_chars(struct uart_txx9_port *up, unsigned int *status) | 278 | receive_chars(struct uart_txx9_port *up, unsigned int *status) |
279 | { | 279 | { |
280 | struct tty_struct *tty = up->port.state->port.tty; | ||
281 | unsigned char ch; | 280 | unsigned char ch; |
282 | unsigned int disr = *status; | 281 | unsigned int disr = *status; |
283 | int max_count = 256; | 282 | int max_count = 256; |
@@ -346,7 +345,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status) | |||
346 | disr = sio_in(up, TXX9_SIDISR); | 345 | disr = sio_in(up, TXX9_SIDISR); |
347 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); | 346 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); |
348 | spin_unlock(&up->port.lock); | 347 | spin_unlock(&up->port.lock); |
349 | tty_flip_buffer_push(tty); | 348 | tty_flip_buffer_push(&up->port.state->port); |
350 | spin_lock(&up->port.lock); | 349 | spin_lock(&up->port.lock); |
351 | *status = disr; | 350 | *status = disr; |
352 | } | 351 | } |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 61477567423f..156418619949 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -596,7 +596,7 @@ static void sci_transmit_chars(struct uart_port *port) | |||
596 | static void sci_receive_chars(struct uart_port *port) | 596 | static void sci_receive_chars(struct uart_port *port) |
597 | { | 597 | { |
598 | struct sci_port *sci_port = to_sci_port(port); | 598 | struct sci_port *sci_port = to_sci_port(port); |
599 | struct tty_struct *tty = port->state->port.tty; | 599 | struct tty_port *tport = &port->state->port; |
600 | int i, count, copied = 0; | 600 | int i, count, copied = 0; |
601 | unsigned short status; | 601 | unsigned short status; |
602 | unsigned char flag; | 602 | unsigned char flag; |
@@ -607,7 +607,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
607 | 607 | ||
608 | while (1) { | 608 | while (1) { |
609 | /* Don't copy more bytes than there is room for in the buffer */ | 609 | /* Don't copy more bytes than there is room for in the buffer */ |
610 | count = tty_buffer_request_room(tty, sci_rxfill(port)); | 610 | count = tty_buffer_request_room(tport, sci_rxfill(port)); |
611 | 611 | ||
612 | /* If for any reason we can't copy more data, we're done! */ | 612 | /* If for any reason we can't copy more data, we're done! */ |
613 | if (count == 0) | 613 | if (count == 0) |
@@ -619,7 +619,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
619 | sci_port->break_flag) | 619 | sci_port->break_flag) |
620 | count = 0; | 620 | count = 0; |
621 | else | 621 | else |
622 | tty_insert_flip_char(tty, c, TTY_NORMAL); | 622 | tty_insert_flip_char(tport, c, TTY_NORMAL); |
623 | } else { | 623 | } else { |
624 | for (i = 0; i < count; i++) { | 624 | for (i = 0; i < count; i++) { |
625 | char c = serial_port_in(port, SCxRDR); | 625 | char c = serial_port_in(port, SCxRDR); |
@@ -661,7 +661,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
661 | } else | 661 | } else |
662 | flag = TTY_NORMAL; | 662 | flag = TTY_NORMAL; |
663 | 663 | ||
664 | tty_insert_flip_char(tty, c, flag); | 664 | tty_insert_flip_char(tport, c, flag); |
665 | } | 665 | } |
666 | } | 666 | } |
667 | 667 | ||
@@ -674,7 +674,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
674 | 674 | ||
675 | if (copied) { | 675 | if (copied) { |
676 | /* Tell the rest of the system the news. New characters! */ | 676 | /* Tell the rest of the system the news. New characters! */ |
677 | tty_flip_buffer_push(tty); | 677 | tty_flip_buffer_push(tport); |
678 | } else { | 678 | } else { |
679 | serial_port_in(port, SCxSR); /* dummy read */ | 679 | serial_port_in(port, SCxSR); /* dummy read */ |
680 | serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); | 680 | serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); |
@@ -720,7 +720,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
720 | { | 720 | { |
721 | int copied = 0; | 721 | int copied = 0; |
722 | unsigned short status = serial_port_in(port, SCxSR); | 722 | unsigned short status = serial_port_in(port, SCxSR); |
723 | struct tty_struct *tty = port->state->port.tty; | 723 | struct tty_port *tport = &port->state->port; |
724 | struct sci_port *s = to_sci_port(port); | 724 | struct sci_port *s = to_sci_port(port); |
725 | 725 | ||
726 | /* | 726 | /* |
@@ -731,7 +731,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
731 | port->icount.overrun++; | 731 | port->icount.overrun++; |
732 | 732 | ||
733 | /* overrun error */ | 733 | /* overrun error */ |
734 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) | 734 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) |
735 | copied++; | 735 | copied++; |
736 | 736 | ||
737 | dev_notice(port->dev, "overrun error"); | 737 | dev_notice(port->dev, "overrun error"); |
@@ -755,7 +755,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
755 | 755 | ||
756 | dev_dbg(port->dev, "BREAK detected\n"); | 756 | dev_dbg(port->dev, "BREAK detected\n"); |
757 | 757 | ||
758 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) | 758 | if (tty_insert_flip_char(tport, 0, TTY_BREAK)) |
759 | copied++; | 759 | copied++; |
760 | } | 760 | } |
761 | 761 | ||
@@ -763,7 +763,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
763 | /* frame error */ | 763 | /* frame error */ |
764 | port->icount.frame++; | 764 | port->icount.frame++; |
765 | 765 | ||
766 | if (tty_insert_flip_char(tty, 0, TTY_FRAME)) | 766 | if (tty_insert_flip_char(tport, 0, TTY_FRAME)) |
767 | copied++; | 767 | copied++; |
768 | 768 | ||
769 | dev_notice(port->dev, "frame error\n"); | 769 | dev_notice(port->dev, "frame error\n"); |
@@ -774,21 +774,21 @@ static int sci_handle_errors(struct uart_port *port) | |||
774 | /* parity error */ | 774 | /* parity error */ |
775 | port->icount.parity++; | 775 | port->icount.parity++; |
776 | 776 | ||
777 | if (tty_insert_flip_char(tty, 0, TTY_PARITY)) | 777 | if (tty_insert_flip_char(tport, 0, TTY_PARITY)) |
778 | copied++; | 778 | copied++; |
779 | 779 | ||
780 | dev_notice(port->dev, "parity error"); | 780 | dev_notice(port->dev, "parity error"); |
781 | } | 781 | } |
782 | 782 | ||
783 | if (copied) | 783 | if (copied) |
784 | tty_flip_buffer_push(tty); | 784 | tty_flip_buffer_push(tport); |
785 | 785 | ||
786 | return copied; | 786 | return copied; |
787 | } | 787 | } |
788 | 788 | ||
789 | static int sci_handle_fifo_overrun(struct uart_port *port) | 789 | static int sci_handle_fifo_overrun(struct uart_port *port) |
790 | { | 790 | { |
791 | struct tty_struct *tty = port->state->port.tty; | 791 | struct tty_port *tport = &port->state->port; |
792 | struct sci_port *s = to_sci_port(port); | 792 | struct sci_port *s = to_sci_port(port); |
793 | struct plat_sci_reg *reg; | 793 | struct plat_sci_reg *reg; |
794 | int copied = 0; | 794 | int copied = 0; |
@@ -802,8 +802,8 @@ static int sci_handle_fifo_overrun(struct uart_port *port) | |||
802 | 802 | ||
803 | port->icount.overrun++; | 803 | port->icount.overrun++; |
804 | 804 | ||
805 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 805 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
806 | tty_flip_buffer_push(tty); | 806 | tty_flip_buffer_push(tport); |
807 | 807 | ||
808 | dev_notice(port->dev, "overrun error\n"); | 808 | dev_notice(port->dev, "overrun error\n"); |
809 | copied++; | 809 | copied++; |
@@ -816,7 +816,7 @@ static int sci_handle_breaks(struct uart_port *port) | |||
816 | { | 816 | { |
817 | int copied = 0; | 817 | int copied = 0; |
818 | unsigned short status = serial_port_in(port, SCxSR); | 818 | unsigned short status = serial_port_in(port, SCxSR); |
819 | struct tty_struct *tty = port->state->port.tty; | 819 | struct tty_port *tport = &port->state->port; |
820 | struct sci_port *s = to_sci_port(port); | 820 | struct sci_port *s = to_sci_port(port); |
821 | 821 | ||
822 | if (uart_handle_break(port)) | 822 | if (uart_handle_break(port)) |
@@ -831,14 +831,14 @@ static int sci_handle_breaks(struct uart_port *port) | |||
831 | port->icount.brk++; | 831 | port->icount.brk++; |
832 | 832 | ||
833 | /* Notify of BREAK */ | 833 | /* Notify of BREAK */ |
834 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) | 834 | if (tty_insert_flip_char(tport, 0, TTY_BREAK)) |
835 | copied++; | 835 | copied++; |
836 | 836 | ||
837 | dev_dbg(port->dev, "BREAK detected\n"); | 837 | dev_dbg(port->dev, "BREAK detected\n"); |
838 | } | 838 | } |
839 | 839 | ||
840 | if (copied) | 840 | if (copied) |
841 | tty_flip_buffer_push(tty); | 841 | tty_flip_buffer_push(tport); |
842 | 842 | ||
843 | copied += sci_handle_fifo_overrun(port); | 843 | copied += sci_handle_fifo_overrun(port); |
844 | 844 | ||
@@ -1259,13 +1259,13 @@ static void sci_dma_tx_complete(void *arg) | |||
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | /* Locking: called with port lock held */ | 1261 | /* Locking: called with port lock held */ |
1262 | static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | 1262 | static int sci_dma_rx_push(struct sci_port *s, size_t count) |
1263 | size_t count) | ||
1264 | { | 1263 | { |
1265 | struct uart_port *port = &s->port; | 1264 | struct uart_port *port = &s->port; |
1265 | struct tty_port *tport = &port->state->port; | ||
1266 | int i, active, room; | 1266 | int i, active, room; |
1267 | 1267 | ||
1268 | room = tty_buffer_request_room(tty, count); | 1268 | room = tty_buffer_request_room(tport, count); |
1269 | 1269 | ||
1270 | if (s->active_rx == s->cookie_rx[0]) { | 1270 | if (s->active_rx == s->cookie_rx[0]) { |
1271 | active = 0; | 1271 | active = 0; |
@@ -1283,7 +1283,7 @@ static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | |||
1283 | return room; | 1283 | return room; |
1284 | 1284 | ||
1285 | for (i = 0; i < room; i++) | 1285 | for (i = 0; i < room; i++) |
1286 | tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i], | 1286 | tty_insert_flip_char(tport, ((u8 *)sg_virt(&s->sg_rx[active]))[i], |
1287 | TTY_NORMAL); | 1287 | TTY_NORMAL); |
1288 | 1288 | ||
1289 | port->icount.rx += room; | 1289 | port->icount.rx += room; |
@@ -1295,7 +1295,6 @@ static void sci_dma_rx_complete(void *arg) | |||
1295 | { | 1295 | { |
1296 | struct sci_port *s = arg; | 1296 | struct sci_port *s = arg; |
1297 | struct uart_port *port = &s->port; | 1297 | struct uart_port *port = &s->port; |
1298 | struct tty_struct *tty = port->state->port.tty; | ||
1299 | unsigned long flags; | 1298 | unsigned long flags; |
1300 | int count; | 1299 | int count; |
1301 | 1300 | ||
@@ -1303,14 +1302,14 @@ static void sci_dma_rx_complete(void *arg) | |||
1303 | 1302 | ||
1304 | spin_lock_irqsave(&port->lock, flags); | 1303 | spin_lock_irqsave(&port->lock, flags); |
1305 | 1304 | ||
1306 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); | 1305 | count = sci_dma_rx_push(s, s->buf_len_rx); |
1307 | 1306 | ||
1308 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); | 1307 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); |
1309 | 1308 | ||
1310 | spin_unlock_irqrestore(&port->lock, flags); | 1309 | spin_unlock_irqrestore(&port->lock, flags); |
1311 | 1310 | ||
1312 | if (count) | 1311 | if (count) |
1313 | tty_flip_buffer_push(tty); | 1312 | tty_flip_buffer_push(&port->state->port); |
1314 | 1313 | ||
1315 | schedule_work(&s->work_rx); | 1314 | schedule_work(&s->work_rx); |
1316 | } | 1315 | } |
@@ -1404,7 +1403,6 @@ static void work_fn_rx(struct work_struct *work) | |||
1404 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != | 1403 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != |
1405 | DMA_SUCCESS) { | 1404 | DMA_SUCCESS) { |
1406 | /* Handle incomplete DMA receive */ | 1405 | /* Handle incomplete DMA receive */ |
1407 | struct tty_struct *tty = port->state->port.tty; | ||
1408 | struct dma_chan *chan = s->chan_rx; | 1406 | struct dma_chan *chan = s->chan_rx; |
1409 | struct shdma_desc *sh_desc = container_of(desc, | 1407 | struct shdma_desc *sh_desc = container_of(desc, |
1410 | struct shdma_desc, async_tx); | 1408 | struct shdma_desc, async_tx); |
@@ -1416,11 +1414,11 @@ static void work_fn_rx(struct work_struct *work) | |||
1416 | sh_desc->partial, sh_desc->cookie); | 1414 | sh_desc->partial, sh_desc->cookie); |
1417 | 1415 | ||
1418 | spin_lock_irqsave(&port->lock, flags); | 1416 | spin_lock_irqsave(&port->lock, flags); |
1419 | count = sci_dma_rx_push(s, tty, sh_desc->partial); | 1417 | count = sci_dma_rx_push(s, sh_desc->partial); |
1420 | spin_unlock_irqrestore(&port->lock, flags); | 1418 | spin_unlock_irqrestore(&port->lock, flags); |
1421 | 1419 | ||
1422 | if (count) | 1420 | if (count) |
1423 | tty_flip_buffer_push(tty); | 1421 | tty_flip_buffer_push(&port->state->port); |
1424 | 1422 | ||
1425 | sci_submit_rx(s); | 1423 | sci_submit_rx(s); |
1426 | 1424 | ||
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 5da5cb962769..6bbfe9934a4d 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -75,6 +75,20 @@ static struct sirfsoc_uart_port sirfsoc_uart_ports[SIRFSOC_UART_NR] = { | |||
75 | .line = 2, | 75 | .line = 2, |
76 | }, | 76 | }, |
77 | }, | 77 | }, |
78 | [3] = { | ||
79 | .port = { | ||
80 | .iotype = UPIO_MEM, | ||
81 | .flags = UPF_BOOT_AUTOCONF, | ||
82 | .line = 3, | ||
83 | }, | ||
84 | }, | ||
85 | [4] = { | ||
86 | .port = { | ||
87 | .iotype = UPIO_MEM, | ||
88 | .flags = UPF_BOOT_AUTOCONF, | ||
89 | .line = 4, | ||
90 | }, | ||
91 | }, | ||
78 | }; | 92 | }; |
79 | 93 | ||
80 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) | 94 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) |
@@ -192,11 +206,6 @@ static unsigned int | |||
192 | sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | 206 | sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) |
193 | { | 207 | { |
194 | unsigned int ch, rx_count = 0; | 208 | unsigned int ch, rx_count = 0; |
195 | struct tty_struct *tty; | ||
196 | |||
197 | tty = tty_port_tty_get(&port->state->port); | ||
198 | if (!tty) | ||
199 | return -ENODEV; | ||
200 | 209 | ||
201 | while (!(rd_regl(port, SIRFUART_RX_FIFO_STATUS) & | 210 | while (!(rd_regl(port, SIRFUART_RX_FIFO_STATUS) & |
202 | SIRFUART_FIFOEMPTY_MASK(port))) { | 211 | SIRFUART_FIFOEMPTY_MASK(port))) { |
@@ -210,8 +219,7 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | |||
210 | } | 219 | } |
211 | 220 | ||
212 | port->icount.rx += rx_count; | 221 | port->icount.rx += rx_count; |
213 | tty_flip_buffer_push(tty); | 222 | tty_flip_buffer_push(&port->state->port); |
214 | tty_kref_put(tty); | ||
215 | 223 | ||
216 | return rx_count; | 224 | return rx_count; |
217 | } | 225 | } |
@@ -245,6 +253,7 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | |||
245 | struct uart_port *port = &sirfport->port; | 253 | struct uart_port *port = &sirfport->port; |
246 | struct uart_state *state = port->state; | 254 | struct uart_state *state = port->state; |
247 | struct circ_buf *xmit = &port->state->xmit; | 255 | struct circ_buf *xmit = &port->state->xmit; |
256 | spin_lock(&port->lock); | ||
248 | intr_status = rd_regl(port, SIRFUART_INT_STATUS); | 257 | intr_status = rd_regl(port, SIRFUART_INT_STATUS); |
249 | wr_regl(port, SIRFUART_INT_STATUS, intr_status); | 258 | wr_regl(port, SIRFUART_INT_STATUS, intr_status); |
250 | intr_status &= rd_regl(port, SIRFUART_INT_EN); | 259 | intr_status &= rd_regl(port, SIRFUART_INT_EN); |
@@ -254,6 +263,7 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | |||
254 | goto recv_char; | 263 | goto recv_char; |
255 | uart_insert_char(port, intr_status, | 264 | uart_insert_char(port, intr_status, |
256 | SIRFUART_RX_OFLOW, 0, TTY_BREAK); | 265 | SIRFUART_RX_OFLOW, 0, TTY_BREAK); |
266 | spin_unlock(&port->lock); | ||
257 | return IRQ_HANDLED; | 267 | return IRQ_HANDLED; |
258 | } | 268 | } |
259 | if (intr_status & SIRFUART_RX_OFLOW) | 269 | if (intr_status & SIRFUART_RX_OFLOW) |
@@ -286,6 +296,7 @@ recv_char: | |||
286 | sirfsoc_uart_pio_rx_chars(port, SIRFSOC_UART_IO_RX_MAX_CNT); | 296 | sirfsoc_uart_pio_rx_chars(port, SIRFSOC_UART_IO_RX_MAX_CNT); |
287 | if (intr_status & SIRFUART_TX_INT_EN) { | 297 | if (intr_status & SIRFUART_TX_INT_EN) { |
288 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | 298 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { |
299 | spin_unlock(&port->lock); | ||
289 | return IRQ_HANDLED; | 300 | return IRQ_HANDLED; |
290 | } else { | 301 | } else { |
291 | sirfsoc_uart_pio_tx_chars(sirfport, | 302 | sirfsoc_uart_pio_tx_chars(sirfport, |
@@ -296,6 +307,7 @@ recv_char: | |||
296 | sirfsoc_uart_stop_tx(port); | 307 | sirfsoc_uart_stop_tx(port); |
297 | } | 308 | } |
298 | } | 309 | } |
310 | spin_unlock(&port->lock); | ||
299 | return IRQ_HANDLED; | 311 | return IRQ_HANDLED; |
300 | } | 312 | } |
301 | 313 | ||
@@ -345,7 +357,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
345 | struct ktermios *old) | 357 | struct ktermios *old) |
346 | { | 358 | { |
347 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 359 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
348 | unsigned long ioclk_rate; | ||
349 | unsigned long config_reg = 0; | 360 | unsigned long config_reg = 0; |
350 | unsigned long baud_rate; | 361 | unsigned long baud_rate; |
351 | unsigned long setted_baud; | 362 | unsigned long setted_baud; |
@@ -357,7 +368,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
357 | int threshold_div; | 368 | int threshold_div; |
358 | int temp; | 369 | int temp; |
359 | 370 | ||
360 | ioclk_rate = 150000000; | ||
361 | switch (termios->c_cflag & CSIZE) { | 371 | switch (termios->c_cflag & CSIZE) { |
362 | default: | 372 | default: |
363 | case CS8: | 373 | case CS8: |
@@ -413,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
413 | sirfsoc_uart_disable_ms(port); | 423 | sirfsoc_uart_disable_ms(port); |
414 | } | 424 | } |
415 | 425 | ||
416 | /* common rate: fast calculation */ | 426 | if (port->uartclk == 150000000) { |
417 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) | 427 | /* common rate: fast calculation */ |
418 | if (baud_rate == baudrate_to_regv[ic].baud_rate) | 428 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) |
419 | clk_div_reg = baudrate_to_regv[ic].reg_val; | 429 | if (baud_rate == baudrate_to_regv[ic].baud_rate) |
430 | clk_div_reg = baudrate_to_regv[ic].reg_val; | ||
431 | } | ||
432 | |||
420 | setted_baud = baud_rate; | 433 | setted_baud = baud_rate; |
421 | /* arbitary rate setting */ | 434 | /* arbitary rate setting */ |
422 | if (unlikely(clk_div_reg == 0)) | 435 | if (unlikely(clk_div_reg == 0)) |
423 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate, | 436 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, port->uartclk, |
424 | &setted_baud); | 437 | &setted_baud); |
425 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); | 438 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); |
426 | 439 | ||
@@ -679,6 +692,14 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
679 | goto err; | 692 | goto err; |
680 | } | 693 | } |
681 | 694 | ||
695 | sirfport->clk = clk_get(&pdev->dev, NULL); | ||
696 | if (IS_ERR(sirfport->clk)) { | ||
697 | ret = PTR_ERR(sirfport->clk); | ||
698 | goto clk_err; | ||
699 | } | ||
700 | clk_prepare_enable(sirfport->clk); | ||
701 | port->uartclk = clk_get_rate(sirfport->clk); | ||
702 | |||
682 | port->ops = &sirfsoc_uart_ops; | 703 | port->ops = &sirfsoc_uart_ops; |
683 | spin_lock_init(&port->lock); | 704 | spin_lock_init(&port->lock); |
684 | 705 | ||
@@ -692,6 +713,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
692 | return 0; | 713 | return 0; |
693 | 714 | ||
694 | port_err: | 715 | port_err: |
716 | clk_disable_unprepare(sirfport->clk); | ||
717 | clk_put(sirfport->clk); | ||
718 | clk_err: | ||
695 | platform_set_drvdata(pdev, NULL); | 719 | platform_set_drvdata(pdev, NULL); |
696 | if (sirfport->hw_flow_ctrl) | 720 | if (sirfport->hw_flow_ctrl) |
697 | pinctrl_put(sirfport->p); | 721 | pinctrl_put(sirfport->p); |
@@ -706,6 +730,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) | |||
706 | platform_set_drvdata(pdev, NULL); | 730 | platform_set_drvdata(pdev, NULL); |
707 | if (sirfport->hw_flow_ctrl) | 731 | if (sirfport->hw_flow_ctrl) |
708 | pinctrl_put(sirfport->p); | 732 | pinctrl_put(sirfport->p); |
733 | clk_disable_unprepare(sirfport->clk); | ||
734 | clk_put(sirfport->clk); | ||
709 | uart_remove_one_port(&sirfsoc_uart_drv, port); | 735 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
710 | return 0; | 736 | return 0; |
711 | } | 737 | } |
@@ -729,6 +755,7 @@ static int sirfsoc_uart_resume(struct platform_device *pdev) | |||
729 | 755 | ||
730 | static struct of_device_id sirfsoc_uart_ids[] = { | 756 | static struct of_device_id sirfsoc_uart_ids[] = { |
731 | { .compatible = "sirf,prima2-uart", }, | 757 | { .compatible = "sirf,prima2-uart", }, |
758 | { .compatible = "sirf,marco-uart", }, | ||
732 | {} | 759 | {} |
733 | }; | 760 | }; |
734 | MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); | 761 | MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); |
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 6e207fdc2fed..85328ba0c4e3 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -139,7 +139,7 @@ | |||
139 | #define SIRFSOC_UART_MINOR 0 | 139 | #define SIRFSOC_UART_MINOR 0 |
140 | #define SIRFUART_PORT_NAME "sirfsoc-uart" | 140 | #define SIRFUART_PORT_NAME "sirfsoc-uart" |
141 | #define SIRFUART_MAP_SIZE 0x200 | 141 | #define SIRFUART_MAP_SIZE 0x200 |
142 | #define SIRFSOC_UART_NR 3 | 142 | #define SIRFSOC_UART_NR 5 |
143 | #define SIRFSOC_PORT_TYPE 0xa5 | 143 | #define SIRFSOC_PORT_TYPE 0xa5 |
144 | 144 | ||
145 | /* Baud Rate Calculation */ | 145 | /* Baud Rate Calculation */ |
@@ -163,6 +163,7 @@ struct sirfsoc_uart_port { | |||
163 | 163 | ||
164 | struct uart_port port; | 164 | struct uart_port port; |
165 | struct pinctrl *p; | 165 | struct pinctrl *p; |
166 | struct clk *clk; | ||
166 | }; | 167 | }; |
167 | 168 | ||
168 | /* Hardware Flow Control */ | 169 | /* Hardware Flow Control */ |
diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c index 1c6de9f58699..f51ffdc696fd 100644 --- a/drivers/tty/serial/sn_console.c +++ b/drivers/tty/serial/sn_console.c | |||
@@ -457,8 +457,8 @@ static int sn_debug_printf(const char *fmt, ...) | |||
457 | static void | 457 | static void |
458 | sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | 458 | sn_receive_chars(struct sn_cons_port *port, unsigned long flags) |
459 | { | 459 | { |
460 | struct tty_port *tport = NULL; | ||
460 | int ch; | 461 | int ch; |
461 | struct tty_struct *tty; | ||
462 | 462 | ||
463 | if (!port) { | 463 | if (!port) { |
464 | printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n"); | 464 | printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n"); |
@@ -472,11 +472,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
472 | 472 | ||
473 | if (port->sc_port.state) { | 473 | if (port->sc_port.state) { |
474 | /* The serial_core stuffs are initialized, use them */ | 474 | /* The serial_core stuffs are initialized, use them */ |
475 | tty = port->sc_port.state->port.tty; | 475 | tport = &port->sc_port.state->port; |
476 | } | ||
477 | else { | ||
478 | /* Not registered yet - can't pass to tty layer. */ | ||
479 | tty = NULL; | ||
480 | } | 476 | } |
481 | 477 | ||
482 | while (port->sc_ops->sal_input_pending()) { | 478 | while (port->sc_ops->sal_input_pending()) { |
@@ -516,15 +512,15 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
516 | #endif /* CONFIG_MAGIC_SYSRQ */ | 512 | #endif /* CONFIG_MAGIC_SYSRQ */ |
517 | 513 | ||
518 | /* record the character to pass up to the tty layer */ | 514 | /* record the character to pass up to the tty layer */ |
519 | if (tty) { | 515 | if (tport) { |
520 | if(tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) | 516 | if (tty_insert_flip_char(tport, ch, TTY_NORMAL) == 0) |
521 | break; | 517 | break; |
522 | } | 518 | } |
523 | port->sc_port.icount.rx++; | 519 | port->sc_port.icount.rx++; |
524 | } | 520 | } |
525 | 521 | ||
526 | if (tty) | 522 | if (tport) |
527 | tty_flip_buffer_push(tty); | 523 | tty_flip_buffer_push(tport); |
528 | } | 524 | } |
529 | 525 | ||
530 | /** | 526 | /** |
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index b9bf9c53f7fd..ba60708053e0 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c | |||
@@ -72,7 +72,7 @@ static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit) | |||
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | 75 | static int receive_chars_getchar(struct uart_port *port) |
76 | { | 76 | { |
77 | int saw_console_brk = 0; | 77 | int saw_console_brk = 0; |
78 | int limit = 10000; | 78 | int limit = 10000; |
@@ -99,7 +99,7 @@ static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | |||
99 | uart_handle_dcd_change(port, 1); | 99 | uart_handle_dcd_change(port, 1); |
100 | } | 100 | } |
101 | 101 | ||
102 | if (tty == NULL) { | 102 | if (port->state == NULL) { |
103 | uart_handle_sysrq_char(port, c); | 103 | uart_handle_sysrq_char(port, c); |
104 | continue; | 104 | continue; |
105 | } | 105 | } |
@@ -109,13 +109,13 @@ static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | |||
109 | if (uart_handle_sysrq_char(port, c)) | 109 | if (uart_handle_sysrq_char(port, c)) |
110 | continue; | 110 | continue; |
111 | 111 | ||
112 | tty_insert_flip_char(tty, c, TTY_NORMAL); | 112 | tty_insert_flip_char(&port->state->port, c, TTY_NORMAL); |
113 | } | 113 | } |
114 | 114 | ||
115 | return saw_console_brk; | 115 | return saw_console_brk; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | 118 | static int receive_chars_read(struct uart_port *port) |
119 | { | 119 | { |
120 | int saw_console_brk = 0; | 120 | int saw_console_brk = 0; |
121 | int limit = 10000; | 121 | int limit = 10000; |
@@ -152,12 +152,13 @@ static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | |||
152 | for (i = 0; i < bytes_read; i++) | 152 | for (i = 0; i < bytes_read; i++) |
153 | uart_handle_sysrq_char(port, con_read_page[i]); | 153 | uart_handle_sysrq_char(port, con_read_page[i]); |
154 | 154 | ||
155 | if (tty == NULL) | 155 | if (port->state == NULL) |
156 | continue; | 156 | continue; |
157 | 157 | ||
158 | port->icount.rx += bytes_read; | 158 | port->icount.rx += bytes_read; |
159 | 159 | ||
160 | tty_insert_flip_string(tty, con_read_page, bytes_read); | 160 | tty_insert_flip_string(&port->state->port, con_read_page, |
161 | bytes_read); | ||
161 | } | 162 | } |
162 | 163 | ||
163 | return saw_console_brk; | 164 | return saw_console_brk; |
@@ -165,7 +166,7 @@ static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | |||
165 | 166 | ||
166 | struct sunhv_ops { | 167 | struct sunhv_ops { |
167 | void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit); | 168 | void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit); |
168 | int (*receive_chars)(struct uart_port *port, struct tty_struct *tty); | 169 | int (*receive_chars)(struct uart_port *port); |
169 | }; | 170 | }; |
170 | 171 | ||
171 | static struct sunhv_ops bychar_ops = { | 172 | static struct sunhv_ops bychar_ops = { |
@@ -180,17 +181,17 @@ static struct sunhv_ops bywrite_ops = { | |||
180 | 181 | ||
181 | static struct sunhv_ops *sunhv_ops = &bychar_ops; | 182 | static struct sunhv_ops *sunhv_ops = &bychar_ops; |
182 | 183 | ||
183 | static struct tty_struct *receive_chars(struct uart_port *port) | 184 | static struct tty_port *receive_chars(struct uart_port *port) |
184 | { | 185 | { |
185 | struct tty_struct *tty = NULL; | 186 | struct tty_port *tport = NULL; |
186 | 187 | ||
187 | if (port->state != NULL) /* Unopened serial console */ | 188 | if (port->state != NULL) /* Unopened serial console */ |
188 | tty = port->state->port.tty; | 189 | tport = &port->state->port; |
189 | 190 | ||
190 | if (sunhv_ops->receive_chars(port, tty)) | 191 | if (sunhv_ops->receive_chars(port)) |
191 | sun_do_break(); | 192 | sun_do_break(); |
192 | 193 | ||
193 | return tty; | 194 | return tport; |
194 | } | 195 | } |
195 | 196 | ||
196 | static void transmit_chars(struct uart_port *port) | 197 | static void transmit_chars(struct uart_port *port) |
@@ -213,16 +214,16 @@ static void transmit_chars(struct uart_port *port) | |||
213 | static irqreturn_t sunhv_interrupt(int irq, void *dev_id) | 214 | static irqreturn_t sunhv_interrupt(int irq, void *dev_id) |
214 | { | 215 | { |
215 | struct uart_port *port = dev_id; | 216 | struct uart_port *port = dev_id; |
216 | struct tty_struct *tty; | 217 | struct tty_port *tport; |
217 | unsigned long flags; | 218 | unsigned long flags; |
218 | 219 | ||
219 | spin_lock_irqsave(&port->lock, flags); | 220 | spin_lock_irqsave(&port->lock, flags); |
220 | tty = receive_chars(port); | 221 | tport = receive_chars(port); |
221 | transmit_chars(port); | 222 | transmit_chars(port); |
222 | spin_unlock_irqrestore(&port->lock, flags); | 223 | spin_unlock_irqrestore(&port->lock, flags); |
223 | 224 | ||
224 | if (tty) | 225 | if (tport) |
225 | tty_flip_buffer_push(tty); | 226 | tty_flip_buffer_push(tport); |
226 | 227 | ||
227 | return IRQ_HANDLED; | 228 | return IRQ_HANDLED; |
228 | } | 229 | } |
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index bd8b3b634103..8de2213664e0 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c | |||
@@ -107,11 +107,11 @@ static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up) | |||
107 | udelay(1); | 107 | udelay(1); |
108 | } | 108 | } |
109 | 109 | ||
110 | static struct tty_struct * | 110 | static struct tty_port * |
111 | receive_chars(struct uart_sunsab_port *up, | 111 | receive_chars(struct uart_sunsab_port *up, |
112 | union sab82532_irq_status *stat) | 112 | union sab82532_irq_status *stat) |
113 | { | 113 | { |
114 | struct tty_struct *tty = NULL; | 114 | struct tty_port *port = NULL; |
115 | unsigned char buf[32]; | 115 | unsigned char buf[32]; |
116 | int saw_console_brk = 0; | 116 | int saw_console_brk = 0; |
117 | int free_fifo = 0; | 117 | int free_fifo = 0; |
@@ -119,7 +119,7 @@ receive_chars(struct uart_sunsab_port *up, | |||
119 | int i; | 119 | int i; |
120 | 120 | ||
121 | if (up->port.state != NULL) /* Unopened serial console */ | 121 | if (up->port.state != NULL) /* Unopened serial console */ |
122 | tty = up->port.state->port.tty; | 122 | port = &up->port.state->port; |
123 | 123 | ||
124 | /* Read number of BYTES (Character + Status) available. */ | 124 | /* Read number of BYTES (Character + Status) available. */ |
125 | if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { | 125 | if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { |
@@ -136,7 +136,7 @@ receive_chars(struct uart_sunsab_port *up, | |||
136 | if (stat->sreg.isr0 & SAB82532_ISR0_TIME) { | 136 | if (stat->sreg.isr0 & SAB82532_ISR0_TIME) { |
137 | sunsab_cec_wait(up); | 137 | sunsab_cec_wait(up); |
138 | writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr); | 138 | writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr); |
139 | return tty; | 139 | return port; |
140 | } | 140 | } |
141 | 141 | ||
142 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) | 142 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) |
@@ -160,11 +160,6 @@ receive_chars(struct uart_sunsab_port *up, | |||
160 | for (i = 0; i < count; i++) { | 160 | for (i = 0; i < count; i++) { |
161 | unsigned char ch = buf[i], flag; | 161 | unsigned char ch = buf[i], flag; |
162 | 162 | ||
163 | if (tty == NULL) { | ||
164 | uart_handle_sysrq_char(&up->port, ch); | ||
165 | continue; | ||
166 | } | ||
167 | |||
168 | flag = TTY_NORMAL; | 163 | flag = TTY_NORMAL; |
169 | up->port.icount.rx++; | 164 | up->port.icount.rx++; |
170 | 165 | ||
@@ -213,15 +208,15 @@ receive_chars(struct uart_sunsab_port *up, | |||
213 | 208 | ||
214 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && | 209 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && |
215 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) | 210 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) |
216 | tty_insert_flip_char(tty, ch, flag); | 211 | tty_insert_flip_char(port, ch, flag); |
217 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) | 212 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) |
218 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 213 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
219 | } | 214 | } |
220 | 215 | ||
221 | if (saw_console_brk) | 216 | if (saw_console_brk) |
222 | sun_do_break(); | 217 | sun_do_break(); |
223 | 218 | ||
224 | return tty; | 219 | return port; |
225 | } | 220 | } |
226 | 221 | ||
227 | static void sunsab_stop_tx(struct uart_port *); | 222 | static void sunsab_stop_tx(struct uart_port *); |
@@ -304,7 +299,7 @@ static void check_status(struct uart_sunsab_port *up, | |||
304 | static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | 299 | static irqreturn_t sunsab_interrupt(int irq, void *dev_id) |
305 | { | 300 | { |
306 | struct uart_sunsab_port *up = dev_id; | 301 | struct uart_sunsab_port *up = dev_id; |
307 | struct tty_struct *tty; | 302 | struct tty_port *port = NULL; |
308 | union sab82532_irq_status status; | 303 | union sab82532_irq_status status; |
309 | unsigned long flags; | 304 | unsigned long flags; |
310 | unsigned char gis; | 305 | unsigned char gis; |
@@ -318,12 +313,11 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | |||
318 | if (gis & 2) | 313 | if (gis & 2) |
319 | status.sreg.isr1 = readb(&up->regs->r.isr1); | 314 | status.sreg.isr1 = readb(&up->regs->r.isr1); |
320 | 315 | ||
321 | tty = NULL; | ||
322 | if (status.stat) { | 316 | if (status.stat) { |
323 | if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | | 317 | if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | |
324 | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || | 318 | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || |
325 | (status.sreg.isr1 & SAB82532_ISR1_BRK)) | 319 | (status.sreg.isr1 & SAB82532_ISR1_BRK)) |
326 | tty = receive_chars(up, &status); | 320 | port = receive_chars(up, &status); |
327 | if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || | 321 | if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || |
328 | (status.sreg.isr1 & SAB82532_ISR1_CSC)) | 322 | (status.sreg.isr1 & SAB82532_ISR1_CSC)) |
329 | check_status(up, &status); | 323 | check_status(up, &status); |
@@ -333,8 +327,8 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | |||
333 | 327 | ||
334 | spin_unlock_irqrestore(&up->port.lock, flags); | 328 | spin_unlock_irqrestore(&up->port.lock, flags); |
335 | 329 | ||
336 | if (tty) | 330 | if (port) |
337 | tty_flip_buffer_push(tty); | 331 | tty_flip_buffer_push(port); |
338 | 332 | ||
339 | return IRQ_HANDLED; | 333 | return IRQ_HANDLED; |
340 | } | 334 | } |
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 220da3f9724f..e343d6670854 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c | |||
@@ -315,10 +315,10 @@ static void sunsu_enable_ms(struct uart_port *port) | |||
315 | spin_unlock_irqrestore(&up->port.lock, flags); | 315 | spin_unlock_irqrestore(&up->port.lock, flags); |
316 | } | 316 | } |
317 | 317 | ||
318 | static struct tty_struct * | 318 | static void |
319 | receive_chars(struct uart_sunsu_port *up, unsigned char *status) | 319 | receive_chars(struct uart_sunsu_port *up, unsigned char *status) |
320 | { | 320 | { |
321 | struct tty_struct *tty = up->port.state->port.tty; | 321 | struct tty_port *port = &up->port.state->port; |
322 | unsigned char ch, flag; | 322 | unsigned char ch, flag; |
323 | int max_count = 256; | 323 | int max_count = 256; |
324 | int saw_console_brk = 0; | 324 | int saw_console_brk = 0; |
@@ -376,22 +376,20 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status) | |||
376 | if (uart_handle_sysrq_char(&up->port, ch)) | 376 | if (uart_handle_sysrq_char(&up->port, ch)) |
377 | goto ignore_char; | 377 | goto ignore_char; |
378 | if ((*status & up->port.ignore_status_mask) == 0) | 378 | if ((*status & up->port.ignore_status_mask) == 0) |
379 | tty_insert_flip_char(tty, ch, flag); | 379 | tty_insert_flip_char(port, ch, flag); |
380 | if (*status & UART_LSR_OE) | 380 | if (*status & UART_LSR_OE) |
381 | /* | 381 | /* |
382 | * Overrun is special, since it's reported | 382 | * Overrun is special, since it's reported |
383 | * immediately, and doesn't affect the current | 383 | * immediately, and doesn't affect the current |
384 | * character. | 384 | * character. |
385 | */ | 385 | */ |
386 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 386 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
387 | ignore_char: | 387 | ignore_char: |
388 | *status = serial_inp(up, UART_LSR); | 388 | *status = serial_inp(up, UART_LSR); |
389 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 389 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
390 | 390 | ||
391 | if (saw_console_brk) | 391 | if (saw_console_brk) |
392 | sun_do_break(); | 392 | sun_do_break(); |
393 | |||
394 | return tty; | ||
395 | } | 393 | } |
396 | 394 | ||
397 | static void transmit_chars(struct uart_sunsu_port *up) | 395 | static void transmit_chars(struct uart_sunsu_port *up) |
@@ -460,20 +458,16 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) | |||
460 | spin_lock_irqsave(&up->port.lock, flags); | 458 | spin_lock_irqsave(&up->port.lock, flags); |
461 | 459 | ||
462 | do { | 460 | do { |
463 | struct tty_struct *tty; | ||
464 | |||
465 | status = serial_inp(up, UART_LSR); | 461 | status = serial_inp(up, UART_LSR); |
466 | tty = NULL; | ||
467 | if (status & UART_LSR_DR) | 462 | if (status & UART_LSR_DR) |
468 | tty = receive_chars(up, &status); | 463 | receive_chars(up, &status); |
469 | check_modem_status(up); | 464 | check_modem_status(up); |
470 | if (status & UART_LSR_THRE) | 465 | if (status & UART_LSR_THRE) |
471 | transmit_chars(up); | 466 | transmit_chars(up); |
472 | 467 | ||
473 | spin_unlock_irqrestore(&up->port.lock, flags); | 468 | spin_unlock_irqrestore(&up->port.lock, flags); |
474 | 469 | ||
475 | if (tty) | 470 | tty_flip_buffer_push(&up->port.state->port); |
476 | tty_flip_buffer_push(tty); | ||
477 | 471 | ||
478 | spin_lock_irqsave(&up->port.lock, flags); | 472 | spin_lock_irqsave(&up->port.lock, flags); |
479 | 473 | ||
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index aef4fab957c3..27669ff3d446 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c | |||
@@ -323,17 +323,15 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up, | |||
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | static struct tty_struct * | 326 | static struct tty_port * |
327 | sunzilog_receive_chars(struct uart_sunzilog_port *up, | 327 | sunzilog_receive_chars(struct uart_sunzilog_port *up, |
328 | struct zilog_channel __iomem *channel) | 328 | struct zilog_channel __iomem *channel) |
329 | { | 329 | { |
330 | struct tty_struct *tty; | 330 | struct tty_port *port = NULL; |
331 | unsigned char ch, r1, flag; | 331 | unsigned char ch, r1, flag; |
332 | 332 | ||
333 | tty = NULL; | 333 | if (up->port.state != NULL) /* Unopened serial console */ |
334 | if (up->port.state != NULL && /* Unopened serial console */ | 334 | port = &up->port.state->port; |
335 | up->port.state->port.tty != NULL) /* Keyboard || mouse */ | ||
336 | tty = up->port.state->port.tty; | ||
337 | 335 | ||
338 | for (;;) { | 336 | for (;;) { |
339 | 337 | ||
@@ -366,11 +364,6 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
366 | continue; | 364 | continue; |
367 | } | 365 | } |
368 | 366 | ||
369 | if (tty == NULL) { | ||
370 | uart_handle_sysrq_char(&up->port, ch); | ||
371 | continue; | ||
372 | } | ||
373 | |||
374 | /* A real serial line, record the character and status. */ | 367 | /* A real serial line, record the character and status. */ |
375 | flag = TTY_NORMAL; | 368 | flag = TTY_NORMAL; |
376 | up->port.icount.rx++; | 369 | up->port.icount.rx++; |
@@ -400,13 +393,13 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
400 | 393 | ||
401 | if (up->port.ignore_status_mask == 0xff || | 394 | if (up->port.ignore_status_mask == 0xff || |
402 | (r1 & up->port.ignore_status_mask) == 0) { | 395 | (r1 & up->port.ignore_status_mask) == 0) { |
403 | tty_insert_flip_char(tty, ch, flag); | 396 | tty_insert_flip_char(port, ch, flag); |
404 | } | 397 | } |
405 | if (r1 & Rx_OVR) | 398 | if (r1 & Rx_OVR) |
406 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 399 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
407 | } | 400 | } |
408 | 401 | ||
409 | return tty; | 402 | return port; |
410 | } | 403 | } |
411 | 404 | ||
412 | static void sunzilog_status_handle(struct uart_sunzilog_port *up, | 405 | static void sunzilog_status_handle(struct uart_sunzilog_port *up, |
@@ -539,21 +532,21 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
539 | while (up) { | 532 | while (up) { |
540 | struct zilog_channel __iomem *channel | 533 | struct zilog_channel __iomem *channel |
541 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | 534 | = ZILOG_CHANNEL_FROM_PORT(&up->port); |
542 | struct tty_struct *tty; | 535 | struct tty_port *port; |
543 | unsigned char r3; | 536 | unsigned char r3; |
544 | 537 | ||
545 | spin_lock(&up->port.lock); | 538 | spin_lock(&up->port.lock); |
546 | r3 = read_zsreg(channel, R3); | 539 | r3 = read_zsreg(channel, R3); |
547 | 540 | ||
548 | /* Channel A */ | 541 | /* Channel A */ |
549 | tty = NULL; | 542 | port = NULL; |
550 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 543 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
551 | writeb(RES_H_IUS, &channel->control); | 544 | writeb(RES_H_IUS, &channel->control); |
552 | ZSDELAY(); | 545 | ZSDELAY(); |
553 | ZS_WSYNC(channel); | 546 | ZS_WSYNC(channel); |
554 | 547 | ||
555 | if (r3 & CHARxIP) | 548 | if (r3 & CHARxIP) |
556 | tty = sunzilog_receive_chars(up, channel); | 549 | port = sunzilog_receive_chars(up, channel); |
557 | if (r3 & CHAEXT) | 550 | if (r3 & CHAEXT) |
558 | sunzilog_status_handle(up, channel); | 551 | sunzilog_status_handle(up, channel); |
559 | if (r3 & CHATxIP) | 552 | if (r3 & CHATxIP) |
@@ -561,22 +554,22 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
561 | } | 554 | } |
562 | spin_unlock(&up->port.lock); | 555 | spin_unlock(&up->port.lock); |
563 | 556 | ||
564 | if (tty) | 557 | if (port) |
565 | tty_flip_buffer_push(tty); | 558 | tty_flip_buffer_push(port); |
566 | 559 | ||
567 | /* Channel B */ | 560 | /* Channel B */ |
568 | up = up->next; | 561 | up = up->next; |
569 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | 562 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); |
570 | 563 | ||
571 | spin_lock(&up->port.lock); | 564 | spin_lock(&up->port.lock); |
572 | tty = NULL; | 565 | port = NULL; |
573 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 566 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
574 | writeb(RES_H_IUS, &channel->control); | 567 | writeb(RES_H_IUS, &channel->control); |
575 | ZSDELAY(); | 568 | ZSDELAY(); |
576 | ZS_WSYNC(channel); | 569 | ZS_WSYNC(channel); |
577 | 570 | ||
578 | if (r3 & CHBRxIP) | 571 | if (r3 & CHBRxIP) |
579 | tty = sunzilog_receive_chars(up, channel); | 572 | port = sunzilog_receive_chars(up, channel); |
580 | if (r3 & CHBEXT) | 573 | if (r3 & CHBEXT) |
581 | sunzilog_status_handle(up, channel); | 574 | sunzilog_status_handle(up, channel); |
582 | if (r3 & CHBTxIP) | 575 | if (r3 & CHBTxIP) |
@@ -584,8 +577,8 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
584 | } | 577 | } |
585 | spin_unlock(&up->port.lock); | 578 | spin_unlock(&up->port.lock); |
586 | 579 | ||
587 | if (tty) | 580 | if (port) |
588 | tty_flip_buffer_push(tty); | 581 | tty_flip_buffer_push(port); |
589 | 582 | ||
590 | up = up->next; | 583 | up = up->next; |
591 | } | 584 | } |
diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 5be0d68feceb..6818410a2bea 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c | |||
@@ -91,16 +91,16 @@ static void timbuart_flush_buffer(struct uart_port *port) | |||
91 | 91 | ||
92 | static void timbuart_rx_chars(struct uart_port *port) | 92 | static void timbuart_rx_chars(struct uart_port *port) |
93 | { | 93 | { |
94 | struct tty_struct *tty = port->state->port.tty; | 94 | struct tty_port *tport = &port->state->port; |
95 | 95 | ||
96 | while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { | 96 | while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { |
97 | u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); | 97 | u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); |
98 | port->icount.rx++; | 98 | port->icount.rx++; |
99 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 99 | tty_insert_flip_char(tport, ch, TTY_NORMAL); |
100 | } | 100 | } |
101 | 101 | ||
102 | spin_unlock(&port->lock); | 102 | spin_unlock(&port->lock); |
103 | tty_flip_buffer_push(port->state->port.tty); | 103 | tty_flip_buffer_push(tport); |
104 | spin_lock(&port->lock); | 104 | spin_lock(&port->lock); |
105 | 105 | ||
106 | dev_dbg(port->dev, "%s - total read %d bytes\n", | 106 | dev_dbg(port->dev, "%s - total read %d bytes\n", |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 89eee43c4e2d..5f90ef24d475 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <asm/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
25 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
@@ -34,7 +34,7 @@ | |||
34 | * Register definitions | 34 | * Register definitions |
35 | * | 35 | * |
36 | * For register details see datasheet: | 36 | * For register details see datasheet: |
37 | * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf | 37 | * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #define ULITE_RX 0x00 | 40 | #define ULITE_RX 0x00 |
@@ -57,6 +57,54 @@ | |||
57 | #define ULITE_CONTROL_RST_RX 0x02 | 57 | #define ULITE_CONTROL_RST_RX 0x02 |
58 | #define ULITE_CONTROL_IE 0x10 | 58 | #define ULITE_CONTROL_IE 0x10 |
59 | 59 | ||
60 | struct uartlite_reg_ops { | ||
61 | u32 (*in)(void __iomem *addr); | ||
62 | void (*out)(u32 val, void __iomem *addr); | ||
63 | }; | ||
64 | |||
65 | static u32 uartlite_inbe32(void __iomem *addr) | ||
66 | { | ||
67 | return ioread32be(addr); | ||
68 | } | ||
69 | |||
70 | static void uartlite_outbe32(u32 val, void __iomem *addr) | ||
71 | { | ||
72 | iowrite32be(val, addr); | ||
73 | } | ||
74 | |||
75 | static struct uartlite_reg_ops uartlite_be = { | ||
76 | .in = uartlite_inbe32, | ||
77 | .out = uartlite_outbe32, | ||
78 | }; | ||
79 | |||
80 | static u32 uartlite_inle32(void __iomem *addr) | ||
81 | { | ||
82 | return ioread32(addr); | ||
83 | } | ||
84 | |||
85 | static void uartlite_outle32(u32 val, void __iomem *addr) | ||
86 | { | ||
87 | iowrite32(val, addr); | ||
88 | } | ||
89 | |||
90 | static struct uartlite_reg_ops uartlite_le = { | ||
91 | .in = uartlite_inle32, | ||
92 | .out = uartlite_outle32, | ||
93 | }; | ||
94 | |||
95 | static inline u32 uart_in32(u32 offset, struct uart_port *port) | ||
96 | { | ||
97 | struct uartlite_reg_ops *reg_ops = port->private_data; | ||
98 | |||
99 | return reg_ops->in(port->membase + offset); | ||
100 | } | ||
101 | |||
102 | static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) | ||
103 | { | ||
104 | struct uartlite_reg_ops *reg_ops = port->private_data; | ||
105 | |||
106 | reg_ops->out(val, port->membase + offset); | ||
107 | } | ||
60 | 108 | ||
61 | static struct uart_port ulite_ports[ULITE_NR_UARTS]; | 109 | static struct uart_port ulite_ports[ULITE_NR_UARTS]; |
62 | 110 | ||
@@ -66,7 +114,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS]; | |||
66 | 114 | ||
67 | static int ulite_receive(struct uart_port *port, int stat) | 115 | static int ulite_receive(struct uart_port *port, int stat) |
68 | { | 116 | { |
69 | struct tty_struct *tty = port->state->port.tty; | 117 | struct tty_port *tport = &port->state->port; |
70 | unsigned char ch = 0; | 118 | unsigned char ch = 0; |
71 | char flag = TTY_NORMAL; | 119 | char flag = TTY_NORMAL; |
72 | 120 | ||
@@ -77,7 +125,7 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
77 | /* stats */ | 125 | /* stats */ |
78 | if (stat & ULITE_STATUS_RXVALID) { | 126 | if (stat & ULITE_STATUS_RXVALID) { |
79 | port->icount.rx++; | 127 | port->icount.rx++; |
80 | ch = ioread32be(port->membase + ULITE_RX); | 128 | ch = uart_in32(ULITE_RX, port); |
81 | 129 | ||
82 | if (stat & ULITE_STATUS_PARITY) | 130 | if (stat & ULITE_STATUS_PARITY) |
83 | port->icount.parity++; | 131 | port->icount.parity++; |
@@ -103,13 +151,13 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
103 | stat &= ~port->ignore_status_mask; | 151 | stat &= ~port->ignore_status_mask; |
104 | 152 | ||
105 | if (stat & ULITE_STATUS_RXVALID) | 153 | if (stat & ULITE_STATUS_RXVALID) |
106 | tty_insert_flip_char(tty, ch, flag); | 154 | tty_insert_flip_char(tport, ch, flag); |
107 | 155 | ||
108 | if (stat & ULITE_STATUS_FRAME) | 156 | if (stat & ULITE_STATUS_FRAME) |
109 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 157 | tty_insert_flip_char(tport, 0, TTY_FRAME); |
110 | 158 | ||
111 | if (stat & ULITE_STATUS_OVERRUN) | 159 | if (stat & ULITE_STATUS_OVERRUN) |
112 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 160 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
113 | 161 | ||
114 | return 1; | 162 | return 1; |
115 | } | 163 | } |
@@ -122,7 +170,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
122 | return 0; | 170 | return 0; |
123 | 171 | ||
124 | if (port->x_char) { | 172 | if (port->x_char) { |
125 | iowrite32be(port->x_char, port->membase + ULITE_TX); | 173 | uart_out32(port->x_char, ULITE_TX, port); |
126 | port->x_char = 0; | 174 | port->x_char = 0; |
127 | port->icount.tx++; | 175 | port->icount.tx++; |
128 | return 1; | 176 | return 1; |
@@ -131,7 +179,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
131 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 179 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
132 | return 0; | 180 | return 0; |
133 | 181 | ||
134 | iowrite32be(xmit->buf[xmit->tail], port->membase + ULITE_TX); | 182 | uart_out32(xmit->buf[xmit->tail], ULITE_TX, port); |
135 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); | 183 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); |
136 | port->icount.tx++; | 184 | port->icount.tx++; |
137 | 185 | ||
@@ -148,7 +196,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) | |||
148 | int busy, n = 0; | 196 | int busy, n = 0; |
149 | 197 | ||
150 | do { | 198 | do { |
151 | int stat = ioread32be(port->membase + ULITE_STATUS); | 199 | int stat = uart_in32(ULITE_STATUS, port); |
152 | busy = ulite_receive(port, stat); | 200 | busy = ulite_receive(port, stat); |
153 | busy |= ulite_transmit(port, stat); | 201 | busy |= ulite_transmit(port, stat); |
154 | n++; | 202 | n++; |
@@ -156,7 +204,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) | |||
156 | 204 | ||
157 | /* work done? */ | 205 | /* work done? */ |
158 | if (n > 1) { | 206 | if (n > 1) { |
159 | tty_flip_buffer_push(port->state->port.tty); | 207 | tty_flip_buffer_push(&port->state->port); |
160 | return IRQ_HANDLED; | 208 | return IRQ_HANDLED; |
161 | } else { | 209 | } else { |
162 | return IRQ_NONE; | 210 | return IRQ_NONE; |
@@ -169,7 +217,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port) | |||
169 | unsigned int ret; | 217 | unsigned int ret; |
170 | 218 | ||
171 | spin_lock_irqsave(&port->lock, flags); | 219 | spin_lock_irqsave(&port->lock, flags); |
172 | ret = ioread32be(port->membase + ULITE_STATUS); | 220 | ret = uart_in32(ULITE_STATUS, port); |
173 | spin_unlock_irqrestore(&port->lock, flags); | 221 | spin_unlock_irqrestore(&port->lock, flags); |
174 | 222 | ||
175 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; | 223 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; |
@@ -192,7 +240,7 @@ static void ulite_stop_tx(struct uart_port *port) | |||
192 | 240 | ||
193 | static void ulite_start_tx(struct uart_port *port) | 241 | static void ulite_start_tx(struct uart_port *port) |
194 | { | 242 | { |
195 | ulite_transmit(port, ioread32be(port->membase + ULITE_STATUS)); | 243 | ulite_transmit(port, uart_in32(ULITE_STATUS, port)); |
196 | } | 244 | } |
197 | 245 | ||
198 | static void ulite_stop_rx(struct uart_port *port) | 246 | static void ulite_stop_rx(struct uart_port *port) |
@@ -220,17 +268,17 @@ static int ulite_startup(struct uart_port *port) | |||
220 | if (ret) | 268 | if (ret) |
221 | return ret; | 269 | return ret; |
222 | 270 | ||
223 | iowrite32be(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, | 271 | uart_out32(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, |
224 | port->membase + ULITE_CONTROL); | 272 | ULITE_CONTROL, port); |
225 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 273 | uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port); |
226 | 274 | ||
227 | return 0; | 275 | return 0; |
228 | } | 276 | } |
229 | 277 | ||
230 | static void ulite_shutdown(struct uart_port *port) | 278 | static void ulite_shutdown(struct uart_port *port) |
231 | { | 279 | { |
232 | iowrite32be(0, port->membase + ULITE_CONTROL); | 280 | uart_out32(0, ULITE_CONTROL, port); |
233 | ioread32be(port->membase + ULITE_CONTROL); /* dummy */ | 281 | uart_in32(ULITE_CONTROL, port); /* dummy */ |
234 | free_irq(port->irq, port); | 282 | free_irq(port->irq, port); |
235 | } | 283 | } |
236 | 284 | ||
@@ -281,6 +329,8 @@ static void ulite_release_port(struct uart_port *port) | |||
281 | 329 | ||
282 | static int ulite_request_port(struct uart_port *port) | 330 | static int ulite_request_port(struct uart_port *port) |
283 | { | 331 | { |
332 | int ret; | ||
333 | |||
284 | pr_debug("ulite console: port=%p; port->mapbase=%llx\n", | 334 | pr_debug("ulite console: port=%p; port->mapbase=%llx\n", |
285 | port, (unsigned long long) port->mapbase); | 335 | port, (unsigned long long) port->mapbase); |
286 | 336 | ||
@@ -296,6 +346,14 @@ static int ulite_request_port(struct uart_port *port) | |||
296 | return -EBUSY; | 346 | return -EBUSY; |
297 | } | 347 | } |
298 | 348 | ||
349 | port->private_data = &uartlite_be; | ||
350 | ret = uart_in32(ULITE_CONTROL, port); | ||
351 | uart_out32(ULITE_CONTROL_RST_TX, ULITE_CONTROL, port); | ||
352 | ret = uart_in32(ULITE_STATUS, port); | ||
353 | /* Endianess detection */ | ||
354 | if ((ret & ULITE_STATUS_TXEMPTY) != ULITE_STATUS_TXEMPTY) | ||
355 | port->private_data = &uartlite_le; | ||
356 | |||
299 | return 0; | 357 | return 0; |
300 | } | 358 | } |
301 | 359 | ||
@@ -314,20 +372,19 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
314 | #ifdef CONFIG_CONSOLE_POLL | 372 | #ifdef CONFIG_CONSOLE_POLL |
315 | static int ulite_get_poll_char(struct uart_port *port) | 373 | static int ulite_get_poll_char(struct uart_port *port) |
316 | { | 374 | { |
317 | if (!(ioread32be(port->membase + ULITE_STATUS) | 375 | if (!(uart_in32(ULITE_STATUS, port) & ULITE_STATUS_RXVALID)) |
318 | & ULITE_STATUS_RXVALID)) | ||
319 | return NO_POLL_CHAR; | 376 | return NO_POLL_CHAR; |
320 | 377 | ||
321 | return ioread32be(port->membase + ULITE_RX); | 378 | return uart_in32(ULITE_RX, port); |
322 | } | 379 | } |
323 | 380 | ||
324 | static void ulite_put_poll_char(struct uart_port *port, unsigned char ch) | 381 | static void ulite_put_poll_char(struct uart_port *port, unsigned char ch) |
325 | { | 382 | { |
326 | while (ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_TXFULL) | 383 | while (uart_in32(ULITE_STATUS, port) & ULITE_STATUS_TXFULL) |
327 | cpu_relax(); | 384 | cpu_relax(); |
328 | 385 | ||
329 | /* write char to device */ | 386 | /* write char to device */ |
330 | iowrite32be(ch, port->membase + ULITE_TX); | 387 | uart_out32(ch, ULITE_TX, port); |
331 | } | 388 | } |
332 | #endif | 389 | #endif |
333 | 390 | ||
@@ -366,7 +423,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
366 | 423 | ||
367 | /* Spin waiting for TX fifo to have space available */ | 424 | /* Spin waiting for TX fifo to have space available */ |
368 | for (i = 0; i < 100000; i++) { | 425 | for (i = 0; i < 100000; i++) { |
369 | val = ioread32be(port->membase + ULITE_STATUS); | 426 | val = uart_in32(ULITE_STATUS, port); |
370 | if ((val & ULITE_STATUS_TXFULL) == 0) | 427 | if ((val & ULITE_STATUS_TXFULL) == 0) |
371 | break; | 428 | break; |
372 | cpu_relax(); | 429 | cpu_relax(); |
@@ -376,7 +433,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
376 | static void ulite_console_putchar(struct uart_port *port, int ch) | 433 | static void ulite_console_putchar(struct uart_port *port, int ch) |
377 | { | 434 | { |
378 | ulite_console_wait_tx(port); | 435 | ulite_console_wait_tx(port); |
379 | iowrite32be(ch, port->membase + ULITE_TX); | 436 | uart_out32(ch, ULITE_TX, port); |
380 | } | 437 | } |
381 | 438 | ||
382 | static void ulite_console_write(struct console *co, const char *s, | 439 | static void ulite_console_write(struct console *co, const char *s, |
@@ -393,8 +450,8 @@ static void ulite_console_write(struct console *co, const char *s, | |||
393 | spin_lock_irqsave(&port->lock, flags); | 450 | spin_lock_irqsave(&port->lock, flags); |
394 | 451 | ||
395 | /* save and disable interrupt */ | 452 | /* save and disable interrupt */ |
396 | ier = ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; | 453 | ier = uart_in32(ULITE_STATUS, port) & ULITE_STATUS_IE; |
397 | iowrite32be(0, port->membase + ULITE_CONTROL); | 454 | uart_out32(0, ULITE_CONTROL, port); |
398 | 455 | ||
399 | uart_console_write(port, s, count, ulite_console_putchar); | 456 | uart_console_write(port, s, count, ulite_console_putchar); |
400 | 457 | ||
@@ -402,7 +459,7 @@ static void ulite_console_write(struct console *co, const char *s, | |||
402 | 459 | ||
403 | /* restore interrupt state */ | 460 | /* restore interrupt state */ |
404 | if (ier) | 461 | if (ier) |
405 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 462 | uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port); |
406 | 463 | ||
407 | if (locked) | 464 | if (locked) |
408 | spin_unlock_irqrestore(&port->lock, flags); | 465 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -615,7 +672,7 @@ static struct platform_driver ulite_platform_driver = { | |||
615 | * Module setup/teardown | 672 | * Module setup/teardown |
616 | */ | 673 | */ |
617 | 674 | ||
618 | int __init ulite_init(void) | 675 | static int __init ulite_init(void) |
619 | { | 676 | { |
620 | int ret; | 677 | int ret; |
621 | 678 | ||
@@ -634,11 +691,11 @@ int __init ulite_init(void) | |||
634 | err_plat: | 691 | err_plat: |
635 | uart_unregister_driver(&ulite_uart_driver); | 692 | uart_unregister_driver(&ulite_uart_driver); |
636 | err_uart: | 693 | err_uart: |
637 | printk(KERN_ERR "registering uartlite driver failed: err=%i", ret); | 694 | pr_err("registering uartlite driver failed: err=%i", ret); |
638 | return ret; | 695 | return ret; |
639 | } | 696 | } |
640 | 697 | ||
641 | void __exit ulite_exit(void) | 698 | static void __exit ulite_exit(void) |
642 | { | 699 | { |
643 | platform_driver_unregister(&ulite_platform_driver); | 700 | platform_driver_unregister(&ulite_platform_driver); |
644 | uart_unregister_driver(&ulite_uart_driver); | 701 | uart_unregister_driver(&ulite_uart_driver); |
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index f99b0c965f85..7355303dad99 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c | |||
@@ -469,7 +469,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
469 | int i; | 469 | int i; |
470 | unsigned char ch, *cp; | 470 | unsigned char ch, *cp; |
471 | struct uart_port *port = &qe_port->port; | 471 | struct uart_port *port = &qe_port->port; |
472 | struct tty_struct *tty = port->state->port.tty; | 472 | struct tty_port *tport = &port->state->port; |
473 | struct qe_bd *bdp; | 473 | struct qe_bd *bdp; |
474 | u16 status; | 474 | u16 status; |
475 | unsigned int flg; | 475 | unsigned int flg; |
@@ -491,7 +491,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
491 | /* If we don't have enough room in RX buffer for the entire BD, | 491 | /* If we don't have enough room in RX buffer for the entire BD, |
492 | * then we try later, which will be the next RX interrupt. | 492 | * then we try later, which will be the next RX interrupt. |
493 | */ | 493 | */ |
494 | if (tty_buffer_request_room(tty, i) < i) { | 494 | if (tty_buffer_request_room(tport, i) < i) { |
495 | dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n"); | 495 | dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n"); |
496 | return; | 496 | return; |
497 | } | 497 | } |
@@ -512,7 +512,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
512 | continue; | 512 | continue; |
513 | 513 | ||
514 | error_return: | 514 | error_return: |
515 | tty_insert_flip_char(tty, ch, flg); | 515 | tty_insert_flip_char(tport, ch, flg); |
516 | 516 | ||
517 | } | 517 | } |
518 | 518 | ||
@@ -530,7 +530,7 @@ error_return: | |||
530 | qe_port->rx_cur = bdp; | 530 | qe_port->rx_cur = bdp; |
531 | 531 | ||
532 | /* Activate BH processing */ | 532 | /* Activate BH processing */ |
533 | tty_flip_buffer_push(tty); | 533 | tty_flip_buffer_push(tport); |
534 | 534 | ||
535 | return; | 535 | return; |
536 | 536 | ||
@@ -560,7 +560,7 @@ handle_error: | |||
560 | 560 | ||
561 | /* Overrun does not affect the current character ! */ | 561 | /* Overrun does not affect the current character ! */ |
562 | if (status & BD_SC_OV) | 562 | if (status & BD_SC_OV) |
563 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 563 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
564 | #ifdef SUPPORT_SYSRQ | 564 | #ifdef SUPPORT_SYSRQ |
565 | port->sysrq = 0; | 565 | port->sysrq = 0; |
566 | #endif | 566 | #endif |
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 62ee0166bc65..f655997f44af 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c | |||
@@ -313,12 +313,10 @@ static void siu_break_ctl(struct uart_port *port, int ctl) | |||
313 | 313 | ||
314 | static inline void receive_chars(struct uart_port *port, uint8_t *status) | 314 | static inline void receive_chars(struct uart_port *port, uint8_t *status) |
315 | { | 315 | { |
316 | struct tty_struct *tty; | ||
317 | uint8_t lsr, ch; | 316 | uint8_t lsr, ch; |
318 | char flag; | 317 | char flag; |
319 | int max_count = RX_MAX_COUNT; | 318 | int max_count = RX_MAX_COUNT; |
320 | 319 | ||
321 | tty = port->state->port.tty; | ||
322 | lsr = *status; | 320 | lsr = *status; |
323 | 321 | ||
324 | do { | 322 | do { |
@@ -365,7 +363,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status) | |||
365 | lsr = siu_read(port, UART_LSR); | 363 | lsr = siu_read(port, UART_LSR); |
366 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); | 364 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); |
367 | 365 | ||
368 | tty_flip_buffer_push(tty); | 366 | tty_flip_buffer_push(&port->state->port); |
369 | 367 | ||
370 | *status = lsr; | 368 | *status = lsr; |
371 | } | 369 | } |
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index d5ed9f613005..a3f9dd5c9dff 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
@@ -136,22 +136,14 @@ static void vt8500_enable_ms(struct uart_port *port) | |||
136 | 136 | ||
137 | static void handle_rx(struct uart_port *port) | 137 | static void handle_rx(struct uart_port *port) |
138 | { | 138 | { |
139 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 139 | struct tty_port *tport = &port->state->port; |
140 | if (!tty) { | ||
141 | /* Discard data: no tty available */ | ||
142 | int count = (vt8500_read(port, VT8500_URFIDX) & 0x1f00) >> 8; | ||
143 | u16 ch; | ||
144 | while (count--) | ||
145 | ch = readw(port->membase + VT8500_RXFIFO); | ||
146 | return; | ||
147 | } | ||
148 | 140 | ||
149 | /* | 141 | /* |
150 | * Handle overrun | 142 | * Handle overrun |
151 | */ | 143 | */ |
152 | if ((vt8500_read(port, VT8500_URISR) & RXOVER)) { | 144 | if ((vt8500_read(port, VT8500_URISR) & RXOVER)) { |
153 | port->icount.overrun++; | 145 | port->icount.overrun++; |
154 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 146 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
155 | } | 147 | } |
156 | 148 | ||
157 | /* and now the main RX loop */ | 149 | /* and now the main RX loop */ |
@@ -174,11 +166,10 @@ static void handle_rx(struct uart_port *port) | |||
174 | port->icount.rx++; | 166 | port->icount.rx++; |
175 | 167 | ||
176 | if (!uart_handle_sysrq_char(port, c)) | 168 | if (!uart_handle_sysrq_char(port, c)) |
177 | tty_insert_flip_char(tty, c, flag); | 169 | tty_insert_flip_char(tport, c, flag); |
178 | } | 170 | } |
179 | 171 | ||
180 | tty_flip_buffer_push(tty); | 172 | tty_flip_buffer_push(tport); |
181 | tty_kref_put(tty); | ||
182 | } | 173 | } |
183 | 174 | ||
184 | static void handle_tx(struct uart_port *port) | 175 | static void handle_tx(struct uart_port *port) |
@@ -569,7 +560,7 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
569 | 560 | ||
570 | if (np) | 561 | if (np) |
571 | port = of_alias_get_id(np, "serial"); | 562 | port = of_alias_get_id(np, "serial"); |
572 | if (port > VT8500_MAX_PORTS) | 563 | if (port >= VT8500_MAX_PORTS) |
573 | port = -1; | 564 | port = -1; |
574 | else | 565 | else |
575 | port = -1; | 566 | port = -1; |
@@ -580,7 +571,7 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
580 | sizeof(vt8500_ports_in_use)); | 571 | sizeof(vt8500_ports_in_use)); |
581 | } | 572 | } |
582 | 573 | ||
583 | if (port > VT8500_MAX_PORTS) | 574 | if (port >= VT8500_MAX_PORTS) |
584 | return -ENODEV; | 575 | return -ENODEV; |
585 | 576 | ||
586 | /* reserve the port id */ | 577 | /* reserve the port id */ |
@@ -589,10 +580,27 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
589 | return -EBUSY; | 580 | return -EBUSY; |
590 | } | 581 | } |
591 | 582 | ||
592 | vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL); | 583 | vt8500_port = devm_kzalloc(&pdev->dev, sizeof(struct vt8500_port), |
584 | GFP_KERNEL); | ||
593 | if (!vt8500_port) | 585 | if (!vt8500_port) |
594 | return -ENOMEM; | 586 | return -ENOMEM; |
595 | 587 | ||
588 | vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres); | ||
589 | if (!vt8500_port->uart.membase) | ||
590 | return -EADDRNOTAVAIL; | ||
591 | |||
592 | vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); | ||
593 | if (IS_ERR(vt8500_port->clk)) { | ||
594 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
595 | return -EINVAL; | ||
596 | } | ||
597 | |||
598 | ret = clk_prepare_enable(vt8500_port->clk); | ||
599 | if (ret) { | ||
600 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
601 | return ret; | ||
602 | } | ||
603 | |||
596 | vt8500_port->uart.type = PORT_VT8500; | 604 | vt8500_port->uart.type = PORT_VT8500; |
597 | vt8500_port->uart.iotype = UPIO_MEM; | 605 | vt8500_port->uart.iotype = UPIO_MEM; |
598 | vt8500_port->uart.mapbase = mmres->start; | 606 | vt8500_port->uart.mapbase = mmres->start; |
@@ -615,12 +623,6 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
615 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), | 623 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), |
616 | "VT8500 UART%d", pdev->id); | 624 | "VT8500 UART%d", pdev->id); |
617 | 625 | ||
618 | vt8500_port->uart.membase = ioremap(mmres->start, resource_size(mmres)); | ||
619 | if (!vt8500_port->uart.membase) { | ||
620 | ret = -ENOMEM; | ||
621 | goto err; | ||
622 | } | ||
623 | |||
624 | vt8500_uart_ports[port] = vt8500_port; | 626 | vt8500_uart_ports[port] = vt8500_port; |
625 | 627 | ||
626 | uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); | 628 | uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); |
@@ -628,10 +630,6 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
628 | platform_set_drvdata(pdev, vt8500_port); | 630 | platform_set_drvdata(pdev, vt8500_port); |
629 | 631 | ||
630 | return 0; | 632 | return 0; |
631 | |||
632 | err: | ||
633 | kfree(vt8500_port); | ||
634 | return ret; | ||
635 | } | 633 | } |
636 | 634 | ||
637 | static int vt8500_serial_remove(struct platform_device *pdev) | 635 | static int vt8500_serial_remove(struct platform_device *pdev) |
@@ -639,8 +637,8 @@ static int vt8500_serial_remove(struct platform_device *pdev) | |||
639 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); | 637 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); |
640 | 638 | ||
641 | platform_set_drvdata(pdev, NULL); | 639 | platform_set_drvdata(pdev, NULL); |
640 | clk_disable_unprepare(vt8500_port->clk); | ||
642 | uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart); | 641 | uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart); |
643 | kfree(vt8500_port); | ||
644 | 642 | ||
645 | return 0; | 643 | return 0; |
646 | } | 644 | } |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 9ab910370c56..ba451c7209fc 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
18 | #include <linux/tty_flip.h> | 18 | #include <linux/tty_flip.h> |
19 | #include <linux/console.h> | 19 | #include <linux/console.h> |
20 | #include <linux/clk.h> | ||
20 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
@@ -147,15 +148,11 @@ | |||
147 | static irqreturn_t xuartps_isr(int irq, void *dev_id) | 148 | static irqreturn_t xuartps_isr(int irq, void *dev_id) |
148 | { | 149 | { |
149 | struct uart_port *port = (struct uart_port *)dev_id; | 150 | struct uart_port *port = (struct uart_port *)dev_id; |
150 | struct tty_struct *tty; | ||
151 | unsigned long flags; | 151 | unsigned long flags; |
152 | unsigned int isrstatus, numbytes; | 152 | unsigned int isrstatus, numbytes; |
153 | unsigned int data; | 153 | unsigned int data; |
154 | char status = TTY_NORMAL; | 154 | char status = TTY_NORMAL; |
155 | 155 | ||
156 | /* Get the tty which could be NULL so don't assume it's valid */ | ||
157 | tty = tty_port_tty_get(&port->state->port); | ||
158 | |||
159 | spin_lock_irqsave(&port->lock, flags); | 156 | spin_lock_irqsave(&port->lock, flags); |
160 | 157 | ||
161 | /* Read the interrupt status register to determine which | 158 | /* Read the interrupt status register to determine which |
@@ -187,14 +184,11 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) | |||
187 | } else if (isrstatus & XUARTPS_IXR_OVERRUN) | 184 | } else if (isrstatus & XUARTPS_IXR_OVERRUN) |
188 | port->icount.overrun++; | 185 | port->icount.overrun++; |
189 | 186 | ||
190 | if (tty) | 187 | uart_insert_char(port, isrstatus, XUARTPS_IXR_OVERRUN, |
191 | uart_insert_char(port, isrstatus, | 188 | data, status); |
192 | XUARTPS_IXR_OVERRUN, data, | ||
193 | status); | ||
194 | } | 189 | } |
195 | spin_unlock(&port->lock); | 190 | spin_unlock(&port->lock); |
196 | if (tty) | 191 | tty_flip_buffer_push(&port->state->port); |
197 | tty_flip_buffer_push(tty); | ||
198 | spin_lock(&port->lock); | 192 | spin_lock(&port->lock); |
199 | } | 193 | } |
200 | 194 | ||
@@ -237,7 +231,6 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) | |||
237 | 231 | ||
238 | /* be sure to release the lock and tty before leaving */ | 232 | /* be sure to release the lock and tty before leaving */ |
239 | spin_unlock_irqrestore(&port->lock, flags); | 233 | spin_unlock_irqrestore(&port->lock, flags); |
240 | tty_kref_put(tty); | ||
241 | 234 | ||
242 | return IRQ_HANDLED; | 235 | return IRQ_HANDLED; |
243 | } | 236 | } |
@@ -944,16 +937,18 @@ static int xuartps_probe(struct platform_device *pdev) | |||
944 | int rc; | 937 | int rc; |
945 | struct uart_port *port; | 938 | struct uart_port *port; |
946 | struct resource *res, *res2; | 939 | struct resource *res, *res2; |
947 | int clk = 0; | 940 | struct clk *clk; |
948 | |||
949 | const unsigned int *prop; | ||
950 | 941 | ||
951 | prop = of_get_property(pdev->dev.of_node, "clock", NULL); | 942 | clk = of_clk_get(pdev->dev.of_node, 0); |
952 | if (prop) | 943 | if (IS_ERR(clk)) { |
953 | clk = be32_to_cpup(prop); | ||
954 | if (!clk) { | ||
955 | dev_err(&pdev->dev, "no clock specified\n"); | 944 | dev_err(&pdev->dev, "no clock specified\n"); |
956 | return -ENODEV; | 945 | return PTR_ERR(clk); |
946 | } | ||
947 | |||
948 | rc = clk_prepare_enable(clk); | ||
949 | if (rc) { | ||
950 | dev_err(&pdev->dev, "could not enable clock\n"); | ||
951 | return -EBUSY; | ||
957 | } | 952 | } |
958 | 953 | ||
959 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 954 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -978,7 +973,8 @@ static int xuartps_probe(struct platform_device *pdev) | |||
978 | port->mapbase = res->start; | 973 | port->mapbase = res->start; |
979 | port->irq = res2->start; | 974 | port->irq = res2->start; |
980 | port->dev = &pdev->dev; | 975 | port->dev = &pdev->dev; |
981 | port->uartclk = clk; | 976 | port->uartclk = clk_get_rate(clk); |
977 | port->private_data = clk; | ||
982 | dev_set_drvdata(&pdev->dev, port); | 978 | dev_set_drvdata(&pdev->dev, port); |
983 | rc = uart_add_one_port(&xuartps_uart_driver, port); | 979 | rc = uart_add_one_port(&xuartps_uart_driver, port); |
984 | if (rc) { | 980 | if (rc) { |
@@ -1000,14 +996,14 @@ static int xuartps_probe(struct platform_device *pdev) | |||
1000 | static int xuartps_remove(struct platform_device *pdev) | 996 | static int xuartps_remove(struct platform_device *pdev) |
1001 | { | 997 | { |
1002 | struct uart_port *port = dev_get_drvdata(&pdev->dev); | 998 | struct uart_port *port = dev_get_drvdata(&pdev->dev); |
1003 | int rc = 0; | 999 | struct clk *clk = port->private_data; |
1000 | int rc; | ||
1004 | 1001 | ||
1005 | /* Remove the xuartps port from the serial core */ | 1002 | /* Remove the xuartps port from the serial core */ |
1006 | if (port) { | 1003 | rc = uart_remove_one_port(&xuartps_uart_driver, port); |
1007 | rc = uart_remove_one_port(&xuartps_uart_driver, port); | 1004 | dev_set_drvdata(&pdev->dev, NULL); |
1008 | dev_set_drvdata(&pdev->dev, NULL); | 1005 | port->mapbase = 0; |
1009 | port->mapbase = 0; | 1006 | clk_disable_unprepare(clk); |
1010 | } | ||
1011 | return rc; | 1007 | return rc; |
1012 | } | 1008 | } |
1013 | 1009 | ||
@@ -1048,7 +1044,7 @@ MODULE_DEVICE_TABLE(of, xuartps_of_match); | |||
1048 | 1044 | ||
1049 | static struct platform_driver xuartps_platform_driver = { | 1045 | static struct platform_driver xuartps_platform_driver = { |
1050 | .probe = xuartps_probe, /* Probe method */ | 1046 | .probe = xuartps_probe, /* Probe method */ |
1051 | .remove = __exit_p(xuartps_remove), /* Detach method */ | 1047 | .remove = xuartps_remove, /* Detach method */ |
1052 | .suspend = xuartps_suspend, /* Suspend */ | 1048 | .suspend = xuartps_suspend, /* Suspend */ |
1053 | .resume = xuartps_resume, /* Resume after a suspend */ | 1049 | .resume = xuartps_resume, /* Resume after a suspend */ |
1054 | .driver = { | 1050 | .driver = { |
diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index 92c00b24d0df..6a169877109b 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c | |||
@@ -603,7 +603,7 @@ static void zs_receive_chars(struct zs_port *zport) | |||
603 | uart_insert_char(uport, status, Rx_OVR, ch, flag); | 603 | uart_insert_char(uport, status, Rx_OVR, ch, flag); |
604 | } | 604 | } |
605 | 605 | ||
606 | tty_flip_buffer_push(uport->state->port.tty); | 606 | tty_flip_buffer_push(&uport->state->port); |
607 | } | 607 | } |
608 | 608 | ||
609 | static void zs_raw_transmit_chars(struct zs_port *zport) | 609 | static void zs_raw_transmit_chars(struct zs_port *zport) |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 9e071f6985f6..8983276aa35e 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -291,8 +291,7 @@ struct mgsl_struct { | |||
291 | bool lcr_mem_requested; | 291 | bool lcr_mem_requested; |
292 | 292 | ||
293 | u32 misc_ctrl_value; | 293 | u32 misc_ctrl_value; |
294 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 294 | char *flag_buf; |
295 | char char_buf[MAX_ASYNC_BUFFER_SIZE]; | ||
296 | bool drop_rts_on_tx_done; | 295 | bool drop_rts_on_tx_done; |
297 | 296 | ||
298 | bool loopmode_insert_requested; | 297 | bool loopmode_insert_requested; |
@@ -1440,7 +1439,6 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1440 | u16 status; | 1439 | u16 status; |
1441 | int work = 0; | 1440 | int work = 0; |
1442 | unsigned char DataByte; | 1441 | unsigned char DataByte; |
1443 | struct tty_struct *tty = info->port.tty; | ||
1444 | struct mgsl_icount *icount = &info->icount; | 1442 | struct mgsl_icount *icount = &info->icount; |
1445 | 1443 | ||
1446 | if ( debug_level >= DEBUG_LEVEL_ISR ) | 1444 | if ( debug_level >= DEBUG_LEVEL_ISR ) |
@@ -1502,19 +1500,19 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1502 | if (status & RXSTATUS_BREAK_RECEIVED) { | 1500 | if (status & RXSTATUS_BREAK_RECEIVED) { |
1503 | flag = TTY_BREAK; | 1501 | flag = TTY_BREAK; |
1504 | if (info->port.flags & ASYNC_SAK) | 1502 | if (info->port.flags & ASYNC_SAK) |
1505 | do_SAK(tty); | 1503 | do_SAK(info->port.tty); |
1506 | } else if (status & RXSTATUS_PARITY_ERROR) | 1504 | } else if (status & RXSTATUS_PARITY_ERROR) |
1507 | flag = TTY_PARITY; | 1505 | flag = TTY_PARITY; |
1508 | else if (status & RXSTATUS_FRAMING_ERROR) | 1506 | else if (status & RXSTATUS_FRAMING_ERROR) |
1509 | flag = TTY_FRAME; | 1507 | flag = TTY_FRAME; |
1510 | } /* end of if (error) */ | 1508 | } /* end of if (error) */ |
1511 | tty_insert_flip_char(tty, DataByte, flag); | 1509 | tty_insert_flip_char(&info->port, DataByte, flag); |
1512 | if (status & RXSTATUS_OVERRUN) { | 1510 | if (status & RXSTATUS_OVERRUN) { |
1513 | /* Overrun is special, since it's | 1511 | /* Overrun is special, since it's |
1514 | * reported immediately, and doesn't | 1512 | * reported immediately, and doesn't |
1515 | * affect the current character | 1513 | * affect the current character |
1516 | */ | 1514 | */ |
1517 | work += tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1515 | work += tty_insert_flip_char(&info->port, 0, TTY_OVERRUN); |
1518 | } | 1516 | } |
1519 | } | 1517 | } |
1520 | 1518 | ||
@@ -1525,7 +1523,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1525 | } | 1523 | } |
1526 | 1524 | ||
1527 | if(work) | 1525 | if(work) |
1528 | tty_flip_buffer_push(tty); | 1526 | tty_flip_buffer_push(&info->port); |
1529 | } | 1527 | } |
1530 | 1528 | ||
1531 | /* mgsl_isr_misc() | 1529 | /* mgsl_isr_misc() |
@@ -1852,7 +1850,7 @@ static void shutdown(struct mgsl_struct * info) | |||
1852 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); | 1850 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); |
1853 | 1851 | ||
1854 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { | 1852 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
1855 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 1853 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1856 | usc_set_serial_signals(info); | 1854 | usc_set_serial_signals(info); |
1857 | } | 1855 | } |
1858 | 1856 | ||
@@ -1917,12 +1915,12 @@ static void mgsl_change_params(struct mgsl_struct *info) | |||
1917 | 1915 | ||
1918 | cflag = info->port.tty->termios.c_cflag; | 1916 | cflag = info->port.tty->termios.c_cflag; |
1919 | 1917 | ||
1920 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 1918 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
1921 | /* otherwise assert DTR and RTS */ | 1919 | /* otherwise assert RTS and DTR */ |
1922 | if (cflag & CBAUD) | 1920 | if (cflag & CBAUD) |
1923 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 1921 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
1924 | else | 1922 | else |
1925 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 1923 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1926 | 1924 | ||
1927 | /* byte size and parity */ | 1925 | /* byte size and parity */ |
1928 | 1926 | ||
@@ -3046,7 +3044,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
3046 | /* Handle transition to B0 status */ | 3044 | /* Handle transition to B0 status */ |
3047 | if (old_termios->c_cflag & CBAUD && | 3045 | if (old_termios->c_cflag & CBAUD && |
3048 | !(tty->termios.c_cflag & CBAUD)) { | 3046 | !(tty->termios.c_cflag & CBAUD)) { |
3049 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3047 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3050 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3048 | spin_lock_irqsave(&info->irq_spinlock,flags); |
3051 | usc_set_serial_signals(info); | 3049 | usc_set_serial_signals(info); |
3052 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 3050 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
@@ -3245,9 +3243,9 @@ static void dtr_rts(struct tty_port *port, int on) | |||
3245 | 3243 | ||
3246 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3244 | spin_lock_irqsave(&info->irq_spinlock,flags); |
3247 | if (on) | 3245 | if (on) |
3248 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 3246 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
3249 | else | 3247 | else |
3250 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3248 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3251 | usc_set_serial_signals(info); | 3249 | usc_set_serial_signals(info); |
3252 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 3250 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
3253 | } | 3251 | } |
@@ -3416,7 +3414,7 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp) | |||
3416 | goto cleanup; | 3414 | goto cleanup; |
3417 | } | 3415 | } |
3418 | 3416 | ||
3419 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 3417 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
3420 | 3418 | ||
3421 | spin_lock_irqsave(&info->netlock, flags); | 3419 | spin_lock_irqsave(&info->netlock, flags); |
3422 | if (info->netcount) { | 3420 | if (info->netcount) { |
@@ -3898,7 +3896,13 @@ static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info) | |||
3898 | info->intermediate_rxbuffer = kmalloc(info->max_frame_size, GFP_KERNEL | GFP_DMA); | 3896 | info->intermediate_rxbuffer = kmalloc(info->max_frame_size, GFP_KERNEL | GFP_DMA); |
3899 | if ( info->intermediate_rxbuffer == NULL ) | 3897 | if ( info->intermediate_rxbuffer == NULL ) |
3900 | return -ENOMEM; | 3898 | return -ENOMEM; |
3901 | 3899 | /* unused flag buffer to satisfy receive_buf calling interface */ | |
3900 | info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL); | ||
3901 | if (!info->flag_buf) { | ||
3902 | kfree(info->intermediate_rxbuffer); | ||
3903 | info->intermediate_rxbuffer = NULL; | ||
3904 | return -ENOMEM; | ||
3905 | } | ||
3902 | return 0; | 3906 | return 0; |
3903 | 3907 | ||
3904 | } /* end of mgsl_alloc_intermediate_rxbuffer_memory() */ | 3908 | } /* end of mgsl_alloc_intermediate_rxbuffer_memory() */ |
@@ -3917,6 +3921,8 @@ static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info) | |||
3917 | { | 3921 | { |
3918 | kfree(info->intermediate_rxbuffer); | 3922 | kfree(info->intermediate_rxbuffer); |
3919 | info->intermediate_rxbuffer = NULL; | 3923 | info->intermediate_rxbuffer = NULL; |
3924 | kfree(info->flag_buf); | ||
3925 | info->flag_buf = NULL; | ||
3920 | 3926 | ||
3921 | } /* end of mgsl_free_intermediate_rxbuffer_memory() */ | 3927 | } /* end of mgsl_free_intermediate_rxbuffer_memory() */ |
3922 | 3928 | ||
@@ -6233,8 +6239,8 @@ static void usc_get_serial_signals( struct mgsl_struct *info ) | |||
6233 | { | 6239 | { |
6234 | u16 status; | 6240 | u16 status; |
6235 | 6241 | ||
6236 | /* clear all serial signals except DTR and RTS */ | 6242 | /* clear all serial signals except RTS and DTR */ |
6237 | info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; | 6243 | info->serial_signals &= SerialSignal_RTS | SerialSignal_DTR; |
6238 | 6244 | ||
6239 | /* Read the Misc Interrupt status Register (MISR) to get */ | 6245 | /* Read the Misc Interrupt status Register (MISR) to get */ |
6240 | /* the V24 status signals. */ | 6246 | /* the V24 status signals. */ |
@@ -6259,7 +6265,7 @@ static void usc_get_serial_signals( struct mgsl_struct *info ) | |||
6259 | 6265 | ||
6260 | /* usc_set_serial_signals() | 6266 | /* usc_set_serial_signals() |
6261 | * | 6267 | * |
6262 | * Set the state of DTR and RTS based on contents of | 6268 | * Set the state of RTS and DTR based on contents of |
6263 | * serial_signals member of device extension. | 6269 | * serial_signals member of device extension. |
6264 | * | 6270 | * |
6265 | * Arguments: info pointer to device instance data | 6271 | * Arguments: info pointer to device instance data |
@@ -7773,8 +7779,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
7773 | return rc; | 7779 | return rc; |
7774 | } | 7780 | } |
7775 | 7781 | ||
7776 | /* assert DTR and RTS, apply hardware settings */ | 7782 | /* assert RTS and DTR, apply hardware settings */ |
7777 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 7783 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
7778 | mgsl_program_hw(info); | 7784 | mgsl_program_hw(info); |
7779 | 7785 | ||
7780 | /* enable network layer transmit */ | 7786 | /* enable network layer transmit */ |
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index aba1e59f4a88..aa9eece35c3b 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -317,8 +317,7 @@ struct slgt_info { | |||
317 | unsigned char *tx_buf; | 317 | unsigned char *tx_buf; |
318 | int tx_count; | 318 | int tx_count; |
319 | 319 | ||
320 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 320 | char *flag_buf; |
321 | char char_buf[MAX_ASYNC_BUFFER_SIZE]; | ||
322 | bool drop_rts_on_tx_done; | 321 | bool drop_rts_on_tx_done; |
323 | struct _input_signal_events input_signal_events; | 322 | struct _input_signal_events input_signal_events; |
324 | 323 | ||
@@ -683,7 +682,7 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
683 | } | 682 | } |
684 | 683 | ||
685 | mutex_lock(&info->port.mutex); | 684 | mutex_lock(&info->port.mutex); |
686 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 685 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
687 | 686 | ||
688 | spin_lock_irqsave(&info->netlock, flags); | 687 | spin_lock_irqsave(&info->netlock, flags); |
689 | if (info->netcount) { | 688 | if (info->netcount) { |
@@ -786,7 +785,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
786 | /* Handle transition to B0 status */ | 785 | /* Handle transition to B0 status */ |
787 | if (old_termios->c_cflag & CBAUD && | 786 | if (old_termios->c_cflag & CBAUD && |
788 | !(tty->termios.c_cflag & CBAUD)) { | 787 | !(tty->termios.c_cflag & CBAUD)) { |
789 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 788 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
790 | spin_lock_irqsave(&info->lock,flags); | 789 | spin_lock_irqsave(&info->lock,flags); |
791 | set_signals(info); | 790 | set_signals(info); |
792 | spin_unlock_irqrestore(&info->lock,flags); | 791 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -1561,8 +1560,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
1561 | return rc; | 1560 | return rc; |
1562 | } | 1561 | } |
1563 | 1562 | ||
1564 | /* assert DTR and RTS, apply hardware settings */ | 1563 | /* assert RTS and DTR, apply hardware settings */ |
1565 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 1564 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
1566 | program_hw(info); | 1565 | program_hw(info); |
1567 | 1566 | ||
1568 | /* enable network layer transmit */ | 1567 | /* enable network layer transmit */ |
@@ -1855,7 +1854,6 @@ static void hdlcdev_exit(struct slgt_info *info) | |||
1855 | */ | 1854 | */ |
1856 | static void rx_async(struct slgt_info *info) | 1855 | static void rx_async(struct slgt_info *info) |
1857 | { | 1856 | { |
1858 | struct tty_struct *tty = info->port.tty; | ||
1859 | struct mgsl_icount *icount = &info->icount; | 1857 | struct mgsl_icount *icount = &info->icount; |
1860 | unsigned int start, end; | 1858 | unsigned int start, end; |
1861 | unsigned char *p; | 1859 | unsigned char *p; |
@@ -1894,10 +1892,8 @@ static void rx_async(struct slgt_info *info) | |||
1894 | else if (status & BIT0) | 1892 | else if (status & BIT0) |
1895 | stat = TTY_FRAME; | 1893 | stat = TTY_FRAME; |
1896 | } | 1894 | } |
1897 | if (tty) { | 1895 | tty_insert_flip_char(&info->port, ch, stat); |
1898 | tty_insert_flip_char(tty, ch, stat); | 1896 | chars++; |
1899 | chars++; | ||
1900 | } | ||
1901 | } | 1897 | } |
1902 | 1898 | ||
1903 | if (i < count) { | 1899 | if (i < count) { |
@@ -1918,8 +1914,8 @@ static void rx_async(struct slgt_info *info) | |||
1918 | break; | 1914 | break; |
1919 | } | 1915 | } |
1920 | 1916 | ||
1921 | if (tty && chars) | 1917 | if (chars) |
1922 | tty_flip_buffer_push(tty); | 1918 | tty_flip_buffer_push(&info->port); |
1923 | } | 1919 | } |
1924 | 1920 | ||
1925 | /* | 1921 | /* |
@@ -1961,8 +1957,6 @@ static void bh_handler(struct work_struct *work) | |||
1961 | struct slgt_info *info = container_of(work, struct slgt_info, task); | 1957 | struct slgt_info *info = container_of(work, struct slgt_info, task); |
1962 | int action; | 1958 | int action; |
1963 | 1959 | ||
1964 | if (!info) | ||
1965 | return; | ||
1966 | info->bh_running = true; | 1960 | info->bh_running = true; |
1967 | 1961 | ||
1968 | while((action = bh_action(info))) { | 1962 | while((action = bh_action(info))) { |
@@ -2183,7 +2177,7 @@ static void isr_serial(struct slgt_info *info) | |||
2183 | if (info->port.tty) { | 2177 | if (info->port.tty) { |
2184 | if (!(status & info->ignore_status_mask)) { | 2178 | if (!(status & info->ignore_status_mask)) { |
2185 | if (info->read_status_mask & MASK_BREAK) { | 2179 | if (info->read_status_mask & MASK_BREAK) { |
2186 | tty_insert_flip_char(info->port.tty, 0, TTY_BREAK); | 2180 | tty_insert_flip_char(&info->port, 0, TTY_BREAK); |
2187 | if (info->port.flags & ASYNC_SAK) | 2181 | if (info->port.flags & ASYNC_SAK) |
2188 | do_SAK(info->port.tty); | 2182 | do_SAK(info->port.tty); |
2189 | } | 2183 | } |
@@ -2494,7 +2488,7 @@ static void shutdown(struct slgt_info *info) | |||
2494 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); | 2488 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); |
2495 | 2489 | ||
2496 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { | 2490 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
2497 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2491 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2498 | set_signals(info); | 2492 | set_signals(info); |
2499 | } | 2493 | } |
2500 | 2494 | ||
@@ -2554,12 +2548,12 @@ static void change_params(struct slgt_info *info) | |||
2554 | 2548 | ||
2555 | cflag = info->port.tty->termios.c_cflag; | 2549 | cflag = info->port.tty->termios.c_cflag; |
2556 | 2550 | ||
2557 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2551 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
2558 | /* otherwise assert DTR and RTS */ | 2552 | /* otherwise assert RTS and DTR */ |
2559 | if (cflag & CBAUD) | 2553 | if (cflag & CBAUD) |
2560 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 2554 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
2561 | else | 2555 | else |
2562 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2556 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2563 | 2557 | ||
2564 | /* byte size and parity */ | 2558 | /* byte size and parity */ |
2565 | 2559 | ||
@@ -3262,9 +3256,9 @@ static void dtr_rts(struct tty_port *port, int on) | |||
3262 | 3256 | ||
3263 | spin_lock_irqsave(&info->lock,flags); | 3257 | spin_lock_irqsave(&info->lock,flags); |
3264 | if (on) | 3258 | if (on) |
3265 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 3259 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
3266 | else | 3260 | else |
3267 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3261 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3268 | set_signals(info); | 3262 | set_signals(info); |
3269 | spin_unlock_irqrestore(&info->lock,flags); | 3263 | spin_unlock_irqrestore(&info->lock,flags); |
3270 | } | 3264 | } |
@@ -3355,11 +3349,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3355 | return retval; | 3349 | return retval; |
3356 | } | 3350 | } |
3357 | 3351 | ||
3352 | /* | ||
3353 | * allocate buffers used for calling line discipline receive_buf | ||
3354 | * directly in synchronous mode | ||
3355 | * note: add 5 bytes to max frame size to allow appending | ||
3356 | * 32-bit CRC and status byte when configured to do so | ||
3357 | */ | ||
3358 | static int alloc_tmp_rbuf(struct slgt_info *info) | 3358 | static int alloc_tmp_rbuf(struct slgt_info *info) |
3359 | { | 3359 | { |
3360 | info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); | 3360 | info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); |
3361 | if (info->tmp_rbuf == NULL) | 3361 | if (info->tmp_rbuf == NULL) |
3362 | return -ENOMEM; | 3362 | return -ENOMEM; |
3363 | /* unused flag buffer to satisfy receive_buf calling interface */ | ||
3364 | info->flag_buf = kzalloc(info->max_frame_size + 5, GFP_KERNEL); | ||
3365 | if (!info->flag_buf) { | ||
3366 | kfree(info->tmp_rbuf); | ||
3367 | info->tmp_rbuf = NULL; | ||
3368 | return -ENOMEM; | ||
3369 | } | ||
3363 | return 0; | 3370 | return 0; |
3364 | } | 3371 | } |
3365 | 3372 | ||
@@ -3367,6 +3374,8 @@ static void free_tmp_rbuf(struct slgt_info *info) | |||
3367 | { | 3374 | { |
3368 | kfree(info->tmp_rbuf); | 3375 | kfree(info->tmp_rbuf); |
3369 | info->tmp_rbuf = NULL; | 3376 | info->tmp_rbuf = NULL; |
3377 | kfree(info->flag_buf); | ||
3378 | info->flag_buf = NULL; | ||
3370 | } | 3379 | } |
3371 | 3380 | ||
3372 | /* | 3381 | /* |
@@ -4110,7 +4119,7 @@ static void reset_port(struct slgt_info *info) | |||
4110 | tx_stop(info); | 4119 | tx_stop(info); |
4111 | rx_stop(info); | 4120 | rx_stop(info); |
4112 | 4121 | ||
4113 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 4122 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
4114 | set_signals(info); | 4123 | set_signals(info); |
4115 | 4124 | ||
4116 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); | 4125 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); |
@@ -4537,8 +4546,8 @@ static void get_signals(struct slgt_info *info) | |||
4537 | { | 4546 | { |
4538 | unsigned short status = rd_reg16(info, SSR); | 4547 | unsigned short status = rd_reg16(info, SSR); |
4539 | 4548 | ||
4540 | /* clear all serial signals except DTR and RTS */ | 4549 | /* clear all serial signals except RTS and DTR */ |
4541 | info->signals &= SerialSignal_DTR + SerialSignal_RTS; | 4550 | info->signals &= SerialSignal_RTS | SerialSignal_DTR; |
4542 | 4551 | ||
4543 | if (status & BIT3) | 4552 | if (status & BIT3) |
4544 | info->signals |= SerialSignal_DSR; | 4553 | info->signals |= SerialSignal_DSR; |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index fd43fb6f7cee..6d5780cf1d57 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
@@ -262,8 +262,7 @@ typedef struct _synclinkmp_info { | |||
262 | bool sca_statctrl_requested; | 262 | bool sca_statctrl_requested; |
263 | 263 | ||
264 | u32 misc_ctrl_value; | 264 | u32 misc_ctrl_value; |
265 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 265 | char *flag_buf; |
266 | char char_buf[MAX_ASYNC_BUFFER_SIZE]; | ||
267 | bool drop_rts_on_tx_done; | 266 | bool drop_rts_on_tx_done; |
268 | 267 | ||
269 | struct _input_signal_events input_signal_events; | 268 | struct _input_signal_events input_signal_events; |
@@ -762,7 +761,7 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
762 | goto cleanup; | 761 | goto cleanup; |
763 | } | 762 | } |
764 | 763 | ||
765 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 764 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
766 | 765 | ||
767 | spin_lock_irqsave(&info->netlock, flags); | 766 | spin_lock_irqsave(&info->netlock, flags); |
768 | if (info->netcount) { | 767 | if (info->netcount) { |
@@ -883,7 +882,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
883 | /* Handle transition to B0 status */ | 882 | /* Handle transition to B0 status */ |
884 | if (old_termios->c_cflag & CBAUD && | 883 | if (old_termios->c_cflag & CBAUD && |
885 | !(tty->termios.c_cflag & CBAUD)) { | 884 | !(tty->termios.c_cflag & CBAUD)) { |
886 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 885 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
887 | spin_lock_irqsave(&info->lock,flags); | 886 | spin_lock_irqsave(&info->lock,flags); |
888 | set_signals(info); | 887 | set_signals(info); |
889 | spin_unlock_irqrestore(&info->lock,flags); | 888 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -1677,8 +1676,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
1677 | return rc; | 1676 | return rc; |
1678 | } | 1677 | } |
1679 | 1678 | ||
1680 | /* assert DTR and RTS, apply hardware settings */ | 1679 | /* assert RTS and DTR, apply hardware settings */ |
1681 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 1680 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
1682 | program_hw(info); | 1681 | program_hw(info); |
1683 | 1682 | ||
1684 | /* enable network layer transmit */ | 1683 | /* enable network layer transmit */ |
@@ -2008,9 +2007,6 @@ static void bh_handler(struct work_struct *work) | |||
2008 | SLMP_INFO *info = container_of(work, SLMP_INFO, task); | 2007 | SLMP_INFO *info = container_of(work, SLMP_INFO, task); |
2009 | int action; | 2008 | int action; |
2010 | 2009 | ||
2011 | if (!info) | ||
2012 | return; | ||
2013 | |||
2014 | if ( debug_level >= DEBUG_LEVEL_BH ) | 2010 | if ( debug_level >= DEBUG_LEVEL_BH ) |
2015 | printk( "%s(%d):%s bh_handler() entry\n", | 2011 | printk( "%s(%d):%s bh_handler() entry\n", |
2016 | __FILE__,__LINE__,info->device_name); | 2012 | __FILE__,__LINE__,info->device_name); |
@@ -2132,13 +2128,11 @@ static void isr_rxint(SLMP_INFO * info) | |||
2132 | /* process break detection if tty control | 2128 | /* process break detection if tty control |
2133 | * is not set to ignore it | 2129 | * is not set to ignore it |
2134 | */ | 2130 | */ |
2135 | if ( tty ) { | 2131 | if (!(status & info->ignore_status_mask1)) { |
2136 | if (!(status & info->ignore_status_mask1)) { | 2132 | if (info->read_status_mask1 & BRKD) { |
2137 | if (info->read_status_mask1 & BRKD) { | 2133 | tty_insert_flip_char(&info->port, 0, TTY_BREAK); |
2138 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 2134 | if (tty && (info->port.flags & ASYNC_SAK)) |
2139 | if (info->port.flags & ASYNC_SAK) | 2135 | do_SAK(tty); |
2140 | do_SAK(tty); | ||
2141 | } | ||
2142 | } | 2136 | } |
2143 | } | 2137 | } |
2144 | } | 2138 | } |
@@ -2170,7 +2164,6 @@ static void isr_rxrdy(SLMP_INFO * info) | |||
2170 | { | 2164 | { |
2171 | u16 status; | 2165 | u16 status; |
2172 | unsigned char DataByte; | 2166 | unsigned char DataByte; |
2173 | struct tty_struct *tty = info->port.tty; | ||
2174 | struct mgsl_icount *icount = &info->icount; | 2167 | struct mgsl_icount *icount = &info->icount; |
2175 | 2168 | ||
2176 | if ( debug_level >= DEBUG_LEVEL_ISR ) | 2169 | if ( debug_level >= DEBUG_LEVEL_ISR ) |
@@ -2203,26 +2196,22 @@ static void isr_rxrdy(SLMP_INFO * info) | |||
2203 | 2196 | ||
2204 | status &= info->read_status_mask2; | 2197 | status &= info->read_status_mask2; |
2205 | 2198 | ||
2206 | if ( tty ) { | 2199 | if (status & PE) |
2207 | if (status & PE) | 2200 | flag = TTY_PARITY; |
2208 | flag = TTY_PARITY; | 2201 | else if (status & FRME) |
2209 | else if (status & FRME) | 2202 | flag = TTY_FRAME; |
2210 | flag = TTY_FRAME; | 2203 | if (status & OVRN) { |
2211 | if (status & OVRN) { | 2204 | /* Overrun is special, since it's |
2212 | /* Overrun is special, since it's | 2205 | * reported immediately, and doesn't |
2213 | * reported immediately, and doesn't | 2206 | * affect the current character |
2214 | * affect the current character | 2207 | */ |
2215 | */ | 2208 | over = true; |
2216 | over = true; | ||
2217 | } | ||
2218 | } | 2209 | } |
2219 | } /* end of if (error) */ | 2210 | } /* end of if (error) */ |
2220 | 2211 | ||
2221 | if ( tty ) { | 2212 | tty_insert_flip_char(&info->port, DataByte, flag); |
2222 | tty_insert_flip_char(tty, DataByte, flag); | 2213 | if (over) |
2223 | if (over) | 2214 | tty_insert_flip_char(&info->port, 0, TTY_OVERRUN); |
2224 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
2225 | } | ||
2226 | } | 2215 | } |
2227 | 2216 | ||
2228 | if ( debug_level >= DEBUG_LEVEL_ISR ) { | 2217 | if ( debug_level >= DEBUG_LEVEL_ISR ) { |
@@ -2232,8 +2221,7 @@ static void isr_rxrdy(SLMP_INFO * info) | |||
2232 | icount->frame,icount->overrun); | 2221 | icount->frame,icount->overrun); |
2233 | } | 2222 | } |
2234 | 2223 | ||
2235 | if ( tty ) | 2224 | tty_flip_buffer_push(&info->port); |
2236 | tty_flip_buffer_push(tty); | ||
2237 | } | 2225 | } |
2238 | 2226 | ||
2239 | static void isr_txeom(SLMP_INFO * info, unsigned char status) | 2227 | static void isr_txeom(SLMP_INFO * info, unsigned char status) |
@@ -2718,7 +2706,7 @@ static void shutdown(SLMP_INFO * info) | |||
2718 | reset_port(info); | 2706 | reset_port(info); |
2719 | 2707 | ||
2720 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { | 2708 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
2721 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2709 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2722 | set_signals(info); | 2710 | set_signals(info); |
2723 | } | 2711 | } |
2724 | 2712 | ||
@@ -2780,12 +2768,12 @@ static void change_params(SLMP_INFO *info) | |||
2780 | 2768 | ||
2781 | cflag = info->port.tty->termios.c_cflag; | 2769 | cflag = info->port.tty->termios.c_cflag; |
2782 | 2770 | ||
2783 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2771 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
2784 | /* otherwise assert DTR and RTS */ | 2772 | /* otherwise assert RTS and DTR */ |
2785 | if (cflag & CBAUD) | 2773 | if (cflag & CBAUD) |
2786 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 2774 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
2787 | else | 2775 | else |
2788 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2776 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2789 | 2777 | ||
2790 | /* byte size and parity */ | 2778 | /* byte size and parity */ |
2791 | 2779 | ||
@@ -3224,12 +3212,12 @@ static int tiocmget(struct tty_struct *tty) | |||
3224 | get_signals(info); | 3212 | get_signals(info); |
3225 | spin_unlock_irqrestore(&info->lock,flags); | 3213 | spin_unlock_irqrestore(&info->lock,flags); |
3226 | 3214 | ||
3227 | result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS:0) + | 3215 | result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS : 0) | |
3228 | ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR:0) + | 3216 | ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR : 0) | |
3229 | ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR:0) + | 3217 | ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR : 0) | |
3230 | ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG:0) + | 3218 | ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG : 0) | |
3231 | ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR:0) + | 3219 | ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR : 0) | |
3232 | ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS:0); | 3220 | ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS : 0); |
3233 | 3221 | ||
3234 | if (debug_level >= DEBUG_LEVEL_INFO) | 3222 | if (debug_level >= DEBUG_LEVEL_INFO) |
3235 | printk("%s(%d):%s tiocmget() value=%08X\n", | 3223 | printk("%s(%d):%s tiocmget() value=%08X\n", |
@@ -3284,9 +3272,9 @@ static void dtr_rts(struct tty_port *port, int on) | |||
3284 | 3272 | ||
3285 | spin_lock_irqsave(&info->lock,flags); | 3273 | spin_lock_irqsave(&info->lock,flags); |
3286 | if (on) | 3274 | if (on) |
3287 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 3275 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
3288 | else | 3276 | else |
3289 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3277 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3290 | set_signals(info); | 3278 | set_signals(info); |
3291 | spin_unlock_irqrestore(&info->lock,flags); | 3279 | spin_unlock_irqrestore(&info->lock,flags); |
3292 | } | 3280 | } |
@@ -3553,6 +3541,13 @@ static int alloc_tmp_rx_buf(SLMP_INFO *info) | |||
3553 | info->tmp_rx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); | 3541 | info->tmp_rx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); |
3554 | if (info->tmp_rx_buf == NULL) | 3542 | if (info->tmp_rx_buf == NULL) |
3555 | return -ENOMEM; | 3543 | return -ENOMEM; |
3544 | /* unused flag buffer to satisfy receive_buf calling interface */ | ||
3545 | info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL); | ||
3546 | if (!info->flag_buf) { | ||
3547 | kfree(info->tmp_rx_buf); | ||
3548 | info->tmp_rx_buf = NULL; | ||
3549 | return -ENOMEM; | ||
3550 | } | ||
3556 | return 0; | 3551 | return 0; |
3557 | } | 3552 | } |
3558 | 3553 | ||
@@ -3560,6 +3555,8 @@ static void free_tmp_rx_buf(SLMP_INFO *info) | |||
3560 | { | 3555 | { |
3561 | kfree(info->tmp_rx_buf); | 3556 | kfree(info->tmp_rx_buf); |
3562 | info->tmp_rx_buf = NULL; | 3557 | info->tmp_rx_buf = NULL; |
3558 | kfree(info->flag_buf); | ||
3559 | info->flag_buf = NULL; | ||
3563 | } | 3560 | } |
3564 | 3561 | ||
3565 | static int claim_resources(SLMP_INFO *info) | 3562 | static int claim_resources(SLMP_INFO *info) |
@@ -4357,7 +4354,7 @@ static void reset_port(SLMP_INFO *info) | |||
4357 | tx_stop(info); | 4354 | tx_stop(info); |
4358 | rx_stop(info); | 4355 | rx_stop(info); |
4359 | 4356 | ||
4360 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 4357 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
4361 | set_signals(info); | 4358 | set_signals(info); |
4362 | 4359 | ||
4363 | /* disable all port interrupts */ | 4360 | /* disable all port interrupts */ |
@@ -4753,8 +4750,8 @@ static void get_signals(SLMP_INFO *info) | |||
4753 | u16 gpstatus = read_status_reg(info); | 4750 | u16 gpstatus = read_status_reg(info); |
4754 | u16 testbit; | 4751 | u16 testbit; |
4755 | 4752 | ||
4756 | /* clear all serial signals except DTR and RTS */ | 4753 | /* clear all serial signals except RTS and DTR */ |
4757 | info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; | 4754 | info->serial_signals &= SerialSignal_RTS | SerialSignal_DTR; |
4758 | 4755 | ||
4759 | /* set serial signal bits to reflect MISR */ | 4756 | /* set serial signal bits to reflect MISR */ |
4760 | 4757 | ||
@@ -4773,7 +4770,7 @@ static void get_signals(SLMP_INFO *info) | |||
4773 | info->serial_signals |= SerialSignal_DSR; | 4770 | info->serial_signals |= SerialSignal_DSR; |
4774 | } | 4771 | } |
4775 | 4772 | ||
4776 | /* Set the state of DTR and RTS based on contents of | 4773 | /* Set the state of RTS and DTR based on contents of |
4777 | * serial_signals member of device context. | 4774 | * serial_signals member of device context. |
4778 | */ | 4775 | */ |
4779 | static void set_signals(SLMP_INFO *info) | 4776 | static void set_signals(SLMP_INFO *info) |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 45d916198f78..bb119934e76c 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/ratelimit.h> | ||
19 | 20 | ||
20 | /** | 21 | /** |
21 | * tty_buffer_free_all - free buffers used by a tty | 22 | * tty_buffer_free_all - free buffers used by a tty |
@@ -119,11 +120,14 @@ static void __tty_buffer_flush(struct tty_port *port) | |||
119 | struct tty_bufhead *buf = &port->buf; | 120 | struct tty_bufhead *buf = &port->buf; |
120 | struct tty_buffer *thead; | 121 | struct tty_buffer *thead; |
121 | 122 | ||
122 | while ((thead = buf->head) != NULL) { | 123 | if (unlikely(buf->head == NULL)) |
123 | buf->head = thead->next; | 124 | return; |
124 | tty_buffer_free(port, thead); | 125 | while ((thead = buf->head->next) != NULL) { |
126 | tty_buffer_free(port, buf->head); | ||
127 | buf->head = thead; | ||
125 | } | 128 | } |
126 | buf->tail = NULL; | 129 | WARN_ON(buf->head != buf->tail); |
130 | buf->head->read = buf->head->commit; | ||
127 | } | 131 | } |
128 | 132 | ||
129 | /** | 133 | /** |
@@ -194,19 +198,22 @@ static struct tty_buffer *tty_buffer_find(struct tty_port *port, size_t size) | |||
194 | have queued and recycle that ? */ | 198 | have queued and recycle that ? */ |
195 | } | 199 | } |
196 | /** | 200 | /** |
197 | * __tty_buffer_request_room - grow tty buffer if needed | 201 | * tty_buffer_request_room - grow tty buffer if needed |
198 | * @tty: tty structure | 202 | * @tty: tty structure |
199 | * @size: size desired | 203 | * @size: size desired |
200 | * | 204 | * |
201 | * Make at least size bytes of linear space available for the tty | 205 | * Make at least size bytes of linear space available for the tty |
202 | * buffer. If we fail return the size we managed to find. | 206 | * buffer. If we fail return the size we managed to find. |
203 | * Locking: Caller must hold port->buf.lock | 207 | * |
208 | * Locking: Takes port->buf.lock | ||
204 | */ | 209 | */ |
205 | static int __tty_buffer_request_room(struct tty_port *port, size_t size) | 210 | int tty_buffer_request_room(struct tty_port *port, size_t size) |
206 | { | 211 | { |
207 | struct tty_bufhead *buf = &port->buf; | 212 | struct tty_bufhead *buf = &port->buf; |
208 | struct tty_buffer *b, *n; | 213 | struct tty_buffer *b, *n; |
209 | int left; | 214 | int left; |
215 | unsigned long flags; | ||
216 | spin_lock_irqsave(&buf->lock, flags); | ||
210 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | 217 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to |
211 | remove this conditional if its worth it. This would be invisible | 218 | remove this conditional if its worth it. This would be invisible |
212 | to the callers */ | 219 | to the callers */ |
@@ -228,37 +235,14 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size) | |||
228 | } else | 235 | } else |
229 | size = left; | 236 | size = left; |
230 | } | 237 | } |
231 | 238 | spin_unlock_irqrestore(&buf->lock, flags); | |
232 | return size; | 239 | return size; |
233 | } | 240 | } |
234 | |||
235 | |||
236 | /** | ||
237 | * tty_buffer_request_room - grow tty buffer if needed | ||
238 | * @tty: tty structure | ||
239 | * @size: size desired | ||
240 | * | ||
241 | * Make at least size bytes of linear space available for the tty | ||
242 | * buffer. If we fail return the size we managed to find. | ||
243 | * | ||
244 | * Locking: Takes port->buf.lock | ||
245 | */ | ||
246 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
247 | { | ||
248 | struct tty_port *port = tty->port; | ||
249 | unsigned long flags; | ||
250 | int length; | ||
251 | |||
252 | spin_lock_irqsave(&port->buf.lock, flags); | ||
253 | length = __tty_buffer_request_room(port, size); | ||
254 | spin_unlock_irqrestore(&port->buf.lock, flags); | ||
255 | return length; | ||
256 | } | ||
257 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 241 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
258 | 242 | ||
259 | /** | 243 | /** |
260 | * tty_insert_flip_string_fixed_flag - Add characters to the tty buffer | 244 | * tty_insert_flip_string_fixed_flag - Add characters to the tty buffer |
261 | * @tty: tty structure | 245 | * @port: tty port |
262 | * @chars: characters | 246 | * @chars: characters |
263 | * @flag: flag value for each character | 247 | * @flag: flag value for each character |
264 | * @size: size | 248 | * @size: size |
@@ -269,29 +253,21 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); | |||
269 | * Locking: Called functions may take port->buf.lock | 253 | * Locking: Called functions may take port->buf.lock |
270 | */ | 254 | */ |
271 | 255 | ||
272 | int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, | 256 | int tty_insert_flip_string_fixed_flag(struct tty_port *port, |
273 | const unsigned char *chars, char flag, size_t size) | 257 | const unsigned char *chars, char flag, size_t size) |
274 | { | 258 | { |
275 | struct tty_bufhead *buf = &tty->port->buf; | ||
276 | int copied = 0; | 259 | int copied = 0; |
277 | do { | 260 | do { |
278 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); | 261 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
279 | int space; | 262 | int space = tty_buffer_request_room(port, goal); |
280 | unsigned long flags; | 263 | struct tty_buffer *tb = port->buf.tail; |
281 | struct tty_buffer *tb; | ||
282 | |||
283 | spin_lock_irqsave(&buf->lock, flags); | ||
284 | space = __tty_buffer_request_room(tty->port, goal); | ||
285 | tb = buf->tail; | ||
286 | /* If there is no space then tb may be NULL */ | 264 | /* If there is no space then tb may be NULL */ |
287 | if (unlikely(space == 0)) { | 265 | if (unlikely(space == 0)) { |
288 | spin_unlock_irqrestore(&buf->lock, flags); | ||
289 | break; | 266 | break; |
290 | } | 267 | } |
291 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 268 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
292 | memset(tb->flag_buf_ptr + tb->used, flag, space); | 269 | memset(tb->flag_buf_ptr + tb->used, flag, space); |
293 | tb->used += space; | 270 | tb->used += space; |
294 | spin_unlock_irqrestore(&buf->lock, flags); | ||
295 | copied += space; | 271 | copied += space; |
296 | chars += space; | 272 | chars += space; |
297 | /* There is a small chance that we need to split the data over | 273 | /* There is a small chance that we need to split the data over |
@@ -303,7 +279,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); | |||
303 | 279 | ||
304 | /** | 280 | /** |
305 | * tty_insert_flip_string_flags - Add characters to the tty buffer | 281 | * tty_insert_flip_string_flags - Add characters to the tty buffer |
306 | * @tty: tty structure | 282 | * @port: tty port |
307 | * @chars: characters | 283 | * @chars: characters |
308 | * @flags: flag bytes | 284 | * @flags: flag bytes |
309 | * @size: size | 285 | * @size: size |
@@ -315,29 +291,21 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); | |||
315 | * Locking: Called functions may take port->buf.lock | 291 | * Locking: Called functions may take port->buf.lock |
316 | */ | 292 | */ |
317 | 293 | ||
318 | int tty_insert_flip_string_flags(struct tty_struct *tty, | 294 | int tty_insert_flip_string_flags(struct tty_port *port, |
319 | const unsigned char *chars, const char *flags, size_t size) | 295 | const unsigned char *chars, const char *flags, size_t size) |
320 | { | 296 | { |
321 | struct tty_bufhead *buf = &tty->port->buf; | ||
322 | int copied = 0; | 297 | int copied = 0; |
323 | do { | 298 | do { |
324 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); | 299 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
325 | int space; | 300 | int space = tty_buffer_request_room(port, goal); |
326 | unsigned long __flags; | 301 | struct tty_buffer *tb = port->buf.tail; |
327 | struct tty_buffer *tb; | ||
328 | |||
329 | spin_lock_irqsave(&buf->lock, __flags); | ||
330 | space = __tty_buffer_request_room(tty->port, goal); | ||
331 | tb = buf->tail; | ||
332 | /* If there is no space then tb may be NULL */ | 302 | /* If there is no space then tb may be NULL */ |
333 | if (unlikely(space == 0)) { | 303 | if (unlikely(space == 0)) { |
334 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
335 | break; | 304 | break; |
336 | } | 305 | } |
337 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 306 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
338 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | 307 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); |
339 | tb->used += space; | 308 | tb->used += space; |
340 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
341 | copied += space; | 309 | copied += space; |
342 | chars += space; | 310 | chars += space; |
343 | flags += space; | 311 | flags += space; |
@@ -350,7 +318,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); | |||
350 | 318 | ||
351 | /** | 319 | /** |
352 | * tty_schedule_flip - push characters to ldisc | 320 | * tty_schedule_flip - push characters to ldisc |
353 | * @tty: tty to push from | 321 | * @port: tty port to push from |
354 | * | 322 | * |
355 | * Takes any pending buffers and transfers their ownership to the | 323 | * Takes any pending buffers and transfers their ownership to the |
356 | * ldisc side of the queue. It then schedules those characters for | 324 | * ldisc side of the queue. It then schedules those characters for |
@@ -361,11 +329,11 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); | |||
361 | * Locking: Takes port->buf.lock | 329 | * Locking: Takes port->buf.lock |
362 | */ | 330 | */ |
363 | 331 | ||
364 | void tty_schedule_flip(struct tty_struct *tty) | 332 | void tty_schedule_flip(struct tty_port *port) |
365 | { | 333 | { |
366 | struct tty_bufhead *buf = &tty->port->buf; | 334 | struct tty_bufhead *buf = &port->buf; |
367 | unsigned long flags; | 335 | unsigned long flags; |
368 | WARN_ON(tty->low_latency); | 336 | WARN_ON(port->low_latency); |
369 | 337 | ||
370 | spin_lock_irqsave(&buf->lock, flags); | 338 | spin_lock_irqsave(&buf->lock, flags); |
371 | if (buf->tail != NULL) | 339 | if (buf->tail != NULL) |
@@ -377,7 +345,7 @@ EXPORT_SYMBOL(tty_schedule_flip); | |||
377 | 345 | ||
378 | /** | 346 | /** |
379 | * tty_prepare_flip_string - make room for characters | 347 | * tty_prepare_flip_string - make room for characters |
380 | * @tty: tty | 348 | * @port: tty port |
381 | * @chars: return pointer for character write area | 349 | * @chars: return pointer for character write area |
382 | * @size: desired size | 350 | * @size: desired size |
383 | * | 351 | * |
@@ -390,31 +358,23 @@ EXPORT_SYMBOL(tty_schedule_flip); | |||
390 | * Locking: May call functions taking port->buf.lock | 358 | * Locking: May call functions taking port->buf.lock |
391 | */ | 359 | */ |
392 | 360 | ||
393 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, | 361 | int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, |
394 | size_t size) | 362 | size_t size) |
395 | { | 363 | { |
396 | struct tty_bufhead *buf = &tty->port->buf; | 364 | int space = tty_buffer_request_room(port, size); |
397 | int space; | ||
398 | unsigned long flags; | ||
399 | struct tty_buffer *tb; | ||
400 | |||
401 | spin_lock_irqsave(&buf->lock, flags); | ||
402 | space = __tty_buffer_request_room(tty->port, size); | ||
403 | |||
404 | tb = buf->tail; | ||
405 | if (likely(space)) { | 365 | if (likely(space)) { |
366 | struct tty_buffer *tb = port->buf.tail; | ||
406 | *chars = tb->char_buf_ptr + tb->used; | 367 | *chars = tb->char_buf_ptr + tb->used; |
407 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | 368 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); |
408 | tb->used += space; | 369 | tb->used += space; |
409 | } | 370 | } |
410 | spin_unlock_irqrestore(&buf->lock, flags); | ||
411 | return space; | 371 | return space; |
412 | } | 372 | } |
413 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | 373 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); |
414 | 374 | ||
415 | /** | 375 | /** |
416 | * tty_prepare_flip_string_flags - make room for characters | 376 | * tty_prepare_flip_string_flags - make room for characters |
417 | * @tty: tty | 377 | * @port: tty port |
418 | * @chars: return pointer for character write area | 378 | * @chars: return pointer for character write area |
419 | * @flags: return pointer for status flag write area | 379 | * @flags: return pointer for status flag write area |
420 | * @size: desired size | 380 | * @size: desired size |
@@ -428,24 +388,16 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | |||
428 | * Locking: May call functions taking port->buf.lock | 388 | * Locking: May call functions taking port->buf.lock |
429 | */ | 389 | */ |
430 | 390 | ||
431 | int tty_prepare_flip_string_flags(struct tty_struct *tty, | 391 | int tty_prepare_flip_string_flags(struct tty_port *port, |
432 | unsigned char **chars, char **flags, size_t size) | 392 | unsigned char **chars, char **flags, size_t size) |
433 | { | 393 | { |
434 | struct tty_bufhead *buf = &tty->port->buf; | 394 | int space = tty_buffer_request_room(port, size); |
435 | int space; | ||
436 | unsigned long __flags; | ||
437 | struct tty_buffer *tb; | ||
438 | |||
439 | spin_lock_irqsave(&buf->lock, __flags); | ||
440 | space = __tty_buffer_request_room(tty->port, size); | ||
441 | |||
442 | tb = buf->tail; | ||
443 | if (likely(space)) { | 395 | if (likely(space)) { |
396 | struct tty_buffer *tb = port->buf.tail; | ||
444 | *chars = tb->char_buf_ptr + tb->used; | 397 | *chars = tb->char_buf_ptr + tb->used; |
445 | *flags = tb->flag_buf_ptr + tb->used; | 398 | *flags = tb->flag_buf_ptr + tb->used; |
446 | tb->used += space; | 399 | tb->used += space; |
447 | } | 400 | } |
448 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
449 | return space; | 401 | return space; |
450 | } | 402 | } |
451 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | 403 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); |
@@ -539,16 +491,17 @@ static void flush_to_ldisc(struct work_struct *work) | |||
539 | */ | 491 | */ |
540 | void tty_flush_to_ldisc(struct tty_struct *tty) | 492 | void tty_flush_to_ldisc(struct tty_struct *tty) |
541 | { | 493 | { |
542 | if (!tty->low_latency) | 494 | if (!tty->port->low_latency) |
543 | flush_work(&tty->port->buf.work); | 495 | flush_work(&tty->port->buf.work); |
544 | } | 496 | } |
545 | 497 | ||
546 | /** | 498 | /** |
547 | * tty_flip_buffer_push - terminal | 499 | * tty_flip_buffer_push - terminal |
548 | * @tty: tty to push | 500 | * @port: tty port to push |
549 | * | 501 | * |
550 | * Queue a push of the terminal flip buffers to the line discipline. This | 502 | * Queue a push of the terminal flip buffers to the line discipline. This |
551 | * function must not be called from IRQ context if tty->low_latency is set. | 503 | * function must not be called from IRQ context if port->low_latency is |
504 | * set. | ||
552 | * | 505 | * |
553 | * In the event of the queue being busy for flipping the work will be | 506 | * In the event of the queue being busy for flipping the work will be |
554 | * held off and retried later. | 507 | * held off and retried later. |
@@ -556,9 +509,9 @@ void tty_flush_to_ldisc(struct tty_struct *tty) | |||
556 | * Locking: tty buffer lock. Driver locks in low latency mode. | 509 | * Locking: tty buffer lock. Driver locks in low latency mode. |
557 | */ | 510 | */ |
558 | 511 | ||
559 | void tty_flip_buffer_push(struct tty_struct *tty) | 512 | void tty_flip_buffer_push(struct tty_port *port) |
560 | { | 513 | { |
561 | struct tty_bufhead *buf = &tty->port->buf; | 514 | struct tty_bufhead *buf = &port->buf; |
562 | unsigned long flags; | 515 | unsigned long flags; |
563 | 516 | ||
564 | spin_lock_irqsave(&buf->lock, flags); | 517 | spin_lock_irqsave(&buf->lock, flags); |
@@ -566,7 +519,7 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
566 | buf->tail->commit = buf->tail->used; | 519 | buf->tail->commit = buf->tail->used; |
567 | spin_unlock_irqrestore(&buf->lock, flags); | 520 | spin_unlock_irqrestore(&buf->lock, flags); |
568 | 521 | ||
569 | if (tty->low_latency) | 522 | if (port->low_latency) |
570 | flush_to_ldisc(&buf->work); | 523 | flush_to_ldisc(&buf->work); |
571 | else | 524 | else |
572 | schedule_work(&buf->work); | 525 | schedule_work(&buf->work); |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6b20fd66d4ad..60e48a11b66c 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -536,7 +536,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); | |||
536 | * __tty_hangup - actual handler for hangup events | 536 | * __tty_hangup - actual handler for hangup events |
537 | * @work: tty device | 537 | * @work: tty device |
538 | * | 538 | * |
539 | * This can be called by the "eventd" kernel thread. That is process | 539 | * This can be called by a "kworker" kernel thread. That is process |
540 | * synchronous but doesn't hold any locks, so we need to make sure we | 540 | * synchronous but doesn't hold any locks, so we need to make sure we |
541 | * have the appropriate locks for what we're doing. | 541 | * have the appropriate locks for what we're doing. |
542 | * | 542 | * |
@@ -977,8 +977,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
977 | else | 977 | else |
978 | i = -EIO; | 978 | i = -EIO; |
979 | tty_ldisc_deref(ld); | 979 | tty_ldisc_deref(ld); |
980 | if (i > 0) | 980 | |
981 | inode->i_atime = current_fs_time(inode->i_sb); | ||
982 | return i; | 981 | return i; |
983 | } | 982 | } |
984 | 983 | ||
@@ -1079,11 +1078,8 @@ static inline ssize_t do_tty_write( | |||
1079 | break; | 1078 | break; |
1080 | cond_resched(); | 1079 | cond_resched(); |
1081 | } | 1080 | } |
1082 | if (written) { | 1081 | if (written) |
1083 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1084 | inode->i_mtime = current_fs_time(inode->i_sb); | ||
1085 | ret = written; | 1082 | ret = written; |
1086 | } | ||
1087 | out: | 1083 | out: |
1088 | tty_write_unlock(tty); | 1084 | tty_write_unlock(tty); |
1089 | return ret; | 1085 | return ret; |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 8481b29d5b3a..d58b92cc187c 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -617,7 +617,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | |||
617 | if (opt & TERMIOS_WAIT) { | 617 | if (opt & TERMIOS_WAIT) { |
618 | tty_wait_until_sent(tty, 0); | 618 | tty_wait_until_sent(tty, 0); |
619 | if (signal_pending(current)) | 619 | if (signal_pending(current)) |
620 | return -EINTR; | 620 | return -ERESTARTSYS; |
621 | } | 621 | } |
622 | 622 | ||
623 | tty_set_termios(tty, &tmp_termios); | 623 | tty_set_termios(tty, &tmp_termios); |
@@ -684,7 +684,7 @@ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) | |||
684 | if (opt & TERMIOS_WAIT) { | 684 | if (opt & TERMIOS_WAIT) { |
685 | tty_wait_until_sent(tty, 0); | 685 | tty_wait_until_sent(tty, 0); |
686 | if (signal_pending(current)) | 686 | if (signal_pending(current)) |
687 | return -EINTR; | 687 | return -ERESTARTSYS; |
688 | } | 688 | } |
689 | 689 | ||
690 | mutex_lock(&tty->termios_mutex); | 690 | mutex_lock(&tty->termios_mutex); |
@@ -1096,12 +1096,16 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | |||
1096 | ld = tty_ldisc_ref_wait(tty); | 1096 | ld = tty_ldisc_ref_wait(tty); |
1097 | switch (arg) { | 1097 | switch (arg) { |
1098 | case TCIFLUSH: | 1098 | case TCIFLUSH: |
1099 | if (ld && ld->ops->flush_buffer) | 1099 | if (ld && ld->ops->flush_buffer) { |
1100 | ld->ops->flush_buffer(tty); | 1100 | ld->ops->flush_buffer(tty); |
1101 | tty_unthrottle(tty); | ||
1102 | } | ||
1101 | break; | 1103 | break; |
1102 | case TCIOFLUSH: | 1104 | case TCIOFLUSH: |
1103 | if (ld && ld->ops->flush_buffer) | 1105 | if (ld && ld->ops->flush_buffer) { |
1104 | ld->ops->flush_buffer(tty); | 1106 | ld->ops->flush_buffer(tty); |
1107 | tty_unthrottle(tty); | ||
1108 | } | ||
1105 | /* fall through */ | 1109 | /* fall through */ |
1106 | case TCOFLUSH: | 1110 | case TCOFLUSH: |
1107 | tty_driver_flush_buffer(tty); | 1111 | tty_driver_flush_buffer(tty); |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index c5782294e532..d794087c327e 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -64,7 +64,9 @@ static void put_ldisc(struct tty_ldisc *ld) | |||
64 | return; | 64 | return; |
65 | } | 65 | } |
66 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 66 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
67 | wake_up(&ld->wq_idle); | 67 | |
68 | if (waitqueue_active(&ld->wq_idle)) | ||
69 | wake_up(&ld->wq_idle); | ||
68 | } | 70 | } |
69 | 71 | ||
70 | /** | 72 | /** |
@@ -934,17 +936,17 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
934 | * race with the set_ldisc code path. | 936 | * race with the set_ldisc code path. |
935 | */ | 937 | */ |
936 | 938 | ||
937 | tty_lock_pair(tty, o_tty); | ||
938 | tty_ldisc_halt(tty); | 939 | tty_ldisc_halt(tty); |
939 | tty_ldisc_flush_works(tty); | 940 | if (o_tty) |
940 | if (o_tty) { | ||
941 | tty_ldisc_halt(o_tty); | 941 | tty_ldisc_halt(o_tty); |
942 | |||
943 | tty_ldisc_flush_works(tty); | ||
944 | if (o_tty) | ||
942 | tty_ldisc_flush_works(o_tty); | 945 | tty_ldisc_flush_works(o_tty); |
943 | } | ||
944 | 946 | ||
947 | tty_lock_pair(tty, o_tty); | ||
945 | /* This will need doing differently if we need to lock */ | 948 | /* This will need doing differently if we need to lock */ |
946 | tty_ldisc_kill(tty); | 949 | tty_ldisc_kill(tty); |
947 | |||
948 | if (o_tty) | 950 | if (o_tty) |
949 | tty_ldisc_kill(o_tty); | 951 | tty_ldisc_kill(o_tty); |
950 | 952 | ||
diff --git a/drivers/tty/vt/Makefile b/drivers/tty/vt/Makefile index 14a51c9960df..17ae94cb29f8 100644 --- a/drivers/tty/vt/Makefile +++ b/drivers/tty/vt/Makefile | |||
@@ -27,8 +27,6 @@ $(obj)/defkeymap.o: $(obj)/defkeymap.c | |||
27 | ifdef GENERATE_KEYMAP | 27 | ifdef GENERATE_KEYMAP |
28 | 28 | ||
29 | $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map | 29 | $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map |
30 | loadkeys --mktable $< > $@.tmp | 30 | loadkeys --mktable $< > $@ |
31 | sed -e 's/^static *//' $@.tmp > $@ | ||
32 | rm $@.tmp | ||
33 | 31 | ||
34 | endif | 32 | endif |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 681765baef69..a9af1b9ae160 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -307,26 +307,17 @@ int kbd_rate(struct kbd_repeat *rep) | |||
307 | */ | 307 | */ |
308 | static void put_queue(struct vc_data *vc, int ch) | 308 | static void put_queue(struct vc_data *vc, int ch) |
309 | { | 309 | { |
310 | struct tty_struct *tty = vc->port.tty; | 310 | tty_insert_flip_char(&vc->port, ch, 0); |
311 | 311 | tty_schedule_flip(&vc->port); | |
312 | if (tty) { | ||
313 | tty_insert_flip_char(tty, ch, 0); | ||
314 | tty_schedule_flip(tty); | ||
315 | } | ||
316 | } | 312 | } |
317 | 313 | ||
318 | static void puts_queue(struct vc_data *vc, char *cp) | 314 | static void puts_queue(struct vc_data *vc, char *cp) |
319 | { | 315 | { |
320 | struct tty_struct *tty = vc->port.tty; | ||
321 | |||
322 | if (!tty) | ||
323 | return; | ||
324 | |||
325 | while (*cp) { | 316 | while (*cp) { |
326 | tty_insert_flip_char(tty, *cp, 0); | 317 | tty_insert_flip_char(&vc->port, *cp, 0); |
327 | cp++; | 318 | cp++; |
328 | } | 319 | } |
329 | tty_schedule_flip(tty); | 320 | tty_schedule_flip(&vc->port); |
330 | } | 321 | } |
331 | 322 | ||
332 | static void applkey(struct vc_data *vc, int key, char mode) | 323 | static void applkey(struct vc_data *vc, int key, char mode) |
@@ -582,12 +573,8 @@ static void fn_inc_console(struct vc_data *vc) | |||
582 | 573 | ||
583 | static void fn_send_intr(struct vc_data *vc) | 574 | static void fn_send_intr(struct vc_data *vc) |
584 | { | 575 | { |
585 | struct tty_struct *tty = vc->port.tty; | 576 | tty_insert_flip_char(&vc->port, 0, TTY_BREAK); |
586 | 577 | tty_schedule_flip(&vc->port); | |
587 | if (!tty) | ||
588 | return; | ||
589 | tty_insert_flip_char(tty, 0, TTY_BREAK); | ||
590 | tty_schedule_flip(tty); | ||
591 | } | 578 | } |
592 | 579 | ||
593 | static void fn_scroll_forw(struct vc_data *vc) | 580 | static void fn_scroll_forw(struct vc_data *vc) |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 8fd89687d068..1a2728034599 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -1333,13 +1333,13 @@ static void csi_m(struct vc_data *vc) | |||
1333 | update_attr(vc); | 1333 | update_attr(vc); |
1334 | } | 1334 | } |
1335 | 1335 | ||
1336 | static void respond_string(const char *p, struct tty_struct *tty) | 1336 | static void respond_string(const char *p, struct tty_port *port) |
1337 | { | 1337 | { |
1338 | while (*p) { | 1338 | while (*p) { |
1339 | tty_insert_flip_char(tty, *p, 0); | 1339 | tty_insert_flip_char(port, *p, 0); |
1340 | p++; | 1340 | p++; |
1341 | } | 1341 | } |
1342 | tty_schedule_flip(tty); | 1342 | tty_schedule_flip(port); |
1343 | } | 1343 | } |
1344 | 1344 | ||
1345 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) | 1345 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) |
@@ -1347,17 +1347,17 @@ static void cursor_report(struct vc_data *vc, struct tty_struct *tty) | |||
1347 | char buf[40]; | 1347 | char buf[40]; |
1348 | 1348 | ||
1349 | sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1); | 1349 | sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1); |
1350 | respond_string(buf, tty); | 1350 | respond_string(buf, tty->port); |
1351 | } | 1351 | } |
1352 | 1352 | ||
1353 | static inline void status_report(struct tty_struct *tty) | 1353 | static inline void status_report(struct tty_struct *tty) |
1354 | { | 1354 | { |
1355 | respond_string("\033[0n", tty); /* Terminal ok */ | 1355 | respond_string("\033[0n", tty->port); /* Terminal ok */ |
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | static inline void respond_ID(struct tty_struct * tty) | 1358 | static inline void respond_ID(struct tty_struct *tty) |
1359 | { | 1359 | { |
1360 | respond_string(VT102ID, tty); | 1360 | respond_string(VT102ID, tty->port); |
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry) | 1363 | void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry) |
@@ -1366,7 +1366,7 @@ void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry) | |||
1366 | 1366 | ||
1367 | sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx), | 1367 | sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx), |
1368 | (char)('!' + mry)); | 1368 | (char)('!' + mry)); |
1369 | respond_string(buf, tty); | 1369 | respond_string(buf, tty->port); |
1370 | } | 1370 | } |
1371 | 1371 | ||
1372 | /* invoked via ioctl(TIOCLINUX) and through set_selection */ | 1372 | /* invoked via ioctl(TIOCLINUX) and through set_selection */ |
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 2519e320098f..316aac8e4ca1 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig | |||
@@ -6,7 +6,7 @@ comment "USB Device Class drivers" | |||
6 | 6 | ||
7 | config USB_ACM | 7 | config USB_ACM |
8 | tristate "USB Modem (CDC ACM) support" | 8 | tristate "USB Modem (CDC ACM) support" |
9 | depends on USB | 9 | depends on USB && TTY |
10 | ---help--- | 10 | ---help--- |
11 | This driver supports USB modems and ISDN adapters which support the | 11 | This driver supports USB modems and ISDN adapters which support the |
12 | Communication Device Class Abstract Control Model interface. | 12 | Communication Device Class Abstract Control Model interface. |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 2d92cce260d7..8ac25adf31b4 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -410,19 +410,12 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags) | |||
410 | 410 | ||
411 | static void acm_process_read_urb(struct acm *acm, struct urb *urb) | 411 | static void acm_process_read_urb(struct acm *acm, struct urb *urb) |
412 | { | 412 | { |
413 | struct tty_struct *tty; | ||
414 | |||
415 | if (!urb->actual_length) | 413 | if (!urb->actual_length) |
416 | return; | 414 | return; |
417 | 415 | ||
418 | tty = tty_port_tty_get(&acm->port); | 416 | tty_insert_flip_string(&acm->port, urb->transfer_buffer, |
419 | if (!tty) | 417 | urb->actual_length); |
420 | return; | 418 | tty_flip_buffer_push(&acm->port); |
421 | |||
422 | tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length); | ||
423 | tty_flip_buffer_push(tty); | ||
424 | |||
425 | tty_kref_put(tty); | ||
426 | } | 419 | } |
427 | 420 | ||
428 | static void acm_read_bulk_callback(struct urb *urb) | 421 | static void acm_read_bulk_callback(struct urb *urb) |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index c5c6fa60910d..5a0c541daf89 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -762,6 +762,7 @@ config USB_GADGET_TARGET | |||
762 | 762 | ||
763 | config USB_G_SERIAL | 763 | config USB_G_SERIAL |
764 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" | 764 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" |
765 | depends on TTY | ||
765 | select USB_U_SERIAL | 766 | select USB_U_SERIAL |
766 | select USB_F_ACM | 767 | select USB_F_ACM |
767 | select USB_LIBCOMPOSITE | 768 | select USB_LIBCOMPOSITE |
@@ -813,6 +814,8 @@ config USB_G_PRINTER | |||
813 | For more information, see Documentation/usb/gadget_printer.txt | 814 | For more information, see Documentation/usb/gadget_printer.txt |
814 | which includes sample code for accessing the device file. | 815 | which includes sample code for accessing the device file. |
815 | 816 | ||
817 | if TTY | ||
818 | |||
816 | config USB_CDC_COMPOSITE | 819 | config USB_CDC_COMPOSITE |
817 | tristate "CDC Composite Device (Ethernet and ACM)" | 820 | tristate "CDC Composite Device (Ethernet and ACM)" |
818 | depends on NET | 821 | depends on NET |
@@ -900,6 +903,8 @@ config USB_G_MULTI_CDC | |||
900 | 903 | ||
901 | If unsure, say "y". | 904 | If unsure, say "y". |
902 | 905 | ||
906 | endif # TTY | ||
907 | |||
903 | config USB_G_HID | 908 | config USB_G_HID |
904 | tristate "HID Gadget" | 909 | tristate "HID Gadget" |
905 | select USB_LIBCOMPOSITE | 910 | select USB_LIBCOMPOSITE |
@@ -916,6 +921,7 @@ config USB_G_HID | |||
916 | # Standalone / single function gadgets | 921 | # Standalone / single function gadgets |
917 | config USB_G_DBGP | 922 | config USB_G_DBGP |
918 | tristate "EHCI Debug Device Gadget" | 923 | tristate "EHCI Debug Device Gadget" |
924 | depends on TTY | ||
919 | select USB_LIBCOMPOSITE | 925 | select USB_LIBCOMPOSITE |
920 | help | 926 | help |
921 | This gadget emulates an EHCI Debug device. This is useful when you want | 927 | This gadget emulates an EHCI Debug device. This is useful when you want |
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 588a9be18ef8..c5034d9c946b 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -496,12 +496,8 @@ static void gs_rx_push(unsigned long _port) | |||
496 | 496 | ||
497 | req = list_first_entry(queue, struct usb_request, list); | 497 | req = list_first_entry(queue, struct usb_request, list); |
498 | 498 | ||
499 | /* discard data if tty was closed */ | ||
500 | if (!tty) | ||
501 | goto recycle; | ||
502 | |||
503 | /* leave data queued if tty was rx throttled */ | 499 | /* leave data queued if tty was rx throttled */ |
504 | if (test_bit(TTY_THROTTLED, &tty->flags)) | 500 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) |
505 | break; | 501 | break; |
506 | 502 | ||
507 | switch (req->status) { | 503 | switch (req->status) { |
@@ -534,7 +530,8 @@ static void gs_rx_push(unsigned long _port) | |||
534 | size -= n; | 530 | size -= n; |
535 | } | 531 | } |
536 | 532 | ||
537 | count = tty_insert_flip_string(tty, packet, size); | 533 | count = tty_insert_flip_string(&port->port, packet, |
534 | size); | ||
538 | if (count) | 535 | if (count) |
539 | do_push = true; | 536 | do_push = true; |
540 | if (count != size) { | 537 | if (count != size) { |
@@ -547,7 +544,7 @@ static void gs_rx_push(unsigned long _port) | |||
547 | } | 544 | } |
548 | port->n_read = 0; | 545 | port->n_read = 0; |
549 | } | 546 | } |
550 | recycle: | 547 | |
551 | list_move(&req->list, &port->read_pool); | 548 | list_move(&req->list, &port->read_pool); |
552 | port->read_started--; | 549 | port->read_started--; |
553 | } | 550 | } |
@@ -555,8 +552,8 @@ recycle: | |||
555 | /* Push from tty to ldisc; without low_latency set this is handled by | 552 | /* Push from tty to ldisc; without low_latency set this is handled by |
556 | * a workqueue, so we won't get callbacks and can hold port_lock | 553 | * a workqueue, so we won't get callbacks and can hold port_lock |
557 | */ | 554 | */ |
558 | if (tty && do_push) | 555 | if (do_push) |
559 | tty_flip_buffer_push(tty); | 556 | tty_flip_buffer_push(&port->port); |
560 | 557 | ||
561 | 558 | ||
562 | /* We want our data queue to become empty ASAP, keeping data | 559 | /* We want our data queue to become empty ASAP, keeping data |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index dad8363e5b2a..17b7f9ae36ad 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | menuconfig USB_SERIAL | 5 | menuconfig USB_SERIAL |
6 | tristate "USB Serial Converter support" | 6 | tristate "USB Serial Converter support" |
7 | depends on USB | 7 | depends on USB && TTY |
8 | ---help--- | 8 | ---help--- |
9 | Say Y here if you have a USB device that provides normal serial | 9 | Say Y here if you have a USB device that provides normal serial |
10 | ports, or acts like a serial device, and you want to connect it to | 10 | ports, or acts like a serial device, and you want to connect it to |
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 6d110a3bc7e7..6e320cec397d 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -119,9 +119,8 @@ static int aircable_probe(struct usb_serial *serial, | |||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | static int aircable_process_packet(struct tty_struct *tty, | 122 | static int aircable_process_packet(struct usb_serial_port *port, |
123 | struct usb_serial_port *port, int has_headers, | 123 | int has_headers, char *packet, int len) |
124 | char *packet, int len) | ||
125 | { | 124 | { |
126 | if (has_headers) { | 125 | if (has_headers) { |
127 | len -= HCI_HEADER_LENGTH; | 126 | len -= HCI_HEADER_LENGTH; |
@@ -132,7 +131,7 @@ static int aircable_process_packet(struct tty_struct *tty, | |||
132 | return 0; | 131 | return 0; |
133 | } | 132 | } |
134 | 133 | ||
135 | tty_insert_flip_string(tty, packet, len); | 134 | tty_insert_flip_string(&port->port, packet, len); |
136 | 135 | ||
137 | return len; | 136 | return len; |
138 | } | 137 | } |
@@ -141,28 +140,22 @@ static void aircable_process_read_urb(struct urb *urb) | |||
141 | { | 140 | { |
142 | struct usb_serial_port *port = urb->context; | 141 | struct usb_serial_port *port = urb->context; |
143 | char *data = (char *)urb->transfer_buffer; | 142 | char *data = (char *)urb->transfer_buffer; |
144 | struct tty_struct *tty; | ||
145 | int has_headers; | 143 | int has_headers; |
146 | int count; | 144 | int count; |
147 | int len; | 145 | int len; |
148 | int i; | 146 | int i; |
149 | 147 | ||
150 | tty = tty_port_tty_get(&port->port); | ||
151 | if (!tty) | ||
152 | return; | ||
153 | |||
154 | has_headers = (urb->actual_length > 2 && data[0] == RX_HEADER_0); | 148 | has_headers = (urb->actual_length > 2 && data[0] == RX_HEADER_0); |
155 | 149 | ||
156 | count = 0; | 150 | count = 0; |
157 | for (i = 0; i < urb->actual_length; i += HCI_COMPLETE_FRAME) { | 151 | for (i = 0; i < urb->actual_length; i += HCI_COMPLETE_FRAME) { |
158 | len = min_t(int, urb->actual_length - i, HCI_COMPLETE_FRAME); | 152 | len = min_t(int, urb->actual_length - i, HCI_COMPLETE_FRAME); |
159 | count += aircable_process_packet(tty, port, has_headers, | 153 | count += aircable_process_packet(port, has_headers, |
160 | &data[i], len); | 154 | &data[i], len); |
161 | } | 155 | } |
162 | 156 | ||
163 | if (count) | 157 | if (count) |
164 | tty_flip_buffer_push(tty); | 158 | tty_flip_buffer_push(&port->port); |
165 | tty_kref_put(tty); | ||
166 | } | 159 | } |
167 | 160 | ||
168 | static struct usb_serial_driver aircable_device = { | 161 | static struct usb_serial_driver aircable_device = { |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index a88882c0e237..cbd904b8fba5 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -674,7 +674,6 @@ static void ark3116_process_read_urb(struct urb *urb) | |||
674 | { | 674 | { |
675 | struct usb_serial_port *port = urb->context; | 675 | struct usb_serial_port *port = urb->context; |
676 | struct ark3116_private *priv = usb_get_serial_port_data(port); | 676 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
677 | struct tty_struct *tty; | ||
678 | unsigned char *data = urb->transfer_buffer; | 677 | unsigned char *data = urb->transfer_buffer; |
679 | char tty_flag = TTY_NORMAL; | 678 | char tty_flag = TTY_NORMAL; |
680 | unsigned long flags; | 679 | unsigned long flags; |
@@ -689,10 +688,6 @@ static void ark3116_process_read_urb(struct urb *urb) | |||
689 | if (!urb->actual_length) | 688 | if (!urb->actual_length) |
690 | return; | 689 | return; |
691 | 690 | ||
692 | tty = tty_port_tty_get(&port->port); | ||
693 | if (!tty) | ||
694 | return; | ||
695 | |||
696 | if (lsr & UART_LSR_BRK_ERROR_BITS) { | 691 | if (lsr & UART_LSR_BRK_ERROR_BITS) { |
697 | if (lsr & UART_LSR_BI) | 692 | if (lsr & UART_LSR_BI) |
698 | tty_flag = TTY_BREAK; | 693 | tty_flag = TTY_BREAK; |
@@ -703,12 +698,11 @@ static void ark3116_process_read_urb(struct urb *urb) | |||
703 | 698 | ||
704 | /* overrun is special, not associated with a char */ | 699 | /* overrun is special, not associated with a char */ |
705 | if (lsr & UART_LSR_OE) | 700 | if (lsr & UART_LSR_OE) |
706 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 701 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
707 | } | 702 | } |
708 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 703 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
709 | urb->actual_length); | 704 | urb->actual_length); |
710 | tty_flip_buffer_push(tty); | 705 | tty_flip_buffer_push(&port->port); |
711 | tty_kref_put(tty); | ||
712 | } | 706 | } |
713 | 707 | ||
714 | static struct usb_serial_driver ark3116_device = { | 708 | static struct usb_serial_driver ark3116_device = { |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index b72a4c166705..84217e78ded4 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -242,7 +242,6 @@ static void belkin_sa_process_read_urb(struct urb *urb) | |||
242 | { | 242 | { |
243 | struct usb_serial_port *port = urb->context; | 243 | struct usb_serial_port *port = urb->context; |
244 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); | 244 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); |
245 | struct tty_struct *tty; | ||
246 | unsigned char *data = urb->transfer_buffer; | 245 | unsigned char *data = urb->transfer_buffer; |
247 | unsigned long flags; | 246 | unsigned long flags; |
248 | unsigned char status; | 247 | unsigned char status; |
@@ -259,10 +258,6 @@ static void belkin_sa_process_read_urb(struct urb *urb) | |||
259 | if (!urb->actual_length) | 258 | if (!urb->actual_length) |
260 | return; | 259 | return; |
261 | 260 | ||
262 | tty = tty_port_tty_get(&port->port); | ||
263 | if (!tty) | ||
264 | return; | ||
265 | |||
266 | if (status & BELKIN_SA_LSR_ERR) { | 261 | if (status & BELKIN_SA_LSR_ERR) { |
267 | /* Break takes precedence over parity, which takes precedence | 262 | /* Break takes precedence over parity, which takes precedence |
268 | * over framing errors. */ | 263 | * over framing errors. */ |
@@ -276,13 +271,12 @@ static void belkin_sa_process_read_urb(struct urb *urb) | |||
276 | 271 | ||
277 | /* Overrun is special, not associated with a char. */ | 272 | /* Overrun is special, not associated with a char. */ |
278 | if (status & BELKIN_SA_LSR_OE) | 273 | if (status & BELKIN_SA_LSR_OE) |
279 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 274 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
280 | } | 275 | } |
281 | 276 | ||
282 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 277 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
283 | urb->actual_length); | 278 | urb->actual_length); |
284 | tty_flip_buffer_push(tty); | 279 | tty_flip_buffer_push(&port->port); |
285 | tty_kref_put(tty); | ||
286 | } | 280 | } |
287 | 281 | ||
288 | static void belkin_sa_set_termios(struct tty_struct *tty, | 282 | static void belkin_sa_set_termios(struct tty_struct *tty, |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 69a4fa1cee25..629bd2894506 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -324,7 +324,6 @@ static void cyberjack_read_bulk_callback(struct urb *urb) | |||
324 | struct usb_serial_port *port = urb->context; | 324 | struct usb_serial_port *port = urb->context; |
325 | struct cyberjack_private *priv = usb_get_serial_port_data(port); | 325 | struct cyberjack_private *priv = usb_get_serial_port_data(port); |
326 | struct device *dev = &port->dev; | 326 | struct device *dev = &port->dev; |
327 | struct tty_struct *tty; | ||
328 | unsigned char *data = urb->transfer_buffer; | 327 | unsigned char *data = urb->transfer_buffer; |
329 | short todo; | 328 | short todo; |
330 | int result; | 329 | int result; |
@@ -337,16 +336,10 @@ static void cyberjack_read_bulk_callback(struct urb *urb) | |||
337 | return; | 336 | return; |
338 | } | 337 | } |
339 | 338 | ||
340 | tty = tty_port_tty_get(&port->port); | ||
341 | if (!tty) { | ||
342 | dev_dbg(dev, "%s - ignoring since device not open\n", __func__); | ||
343 | return; | ||
344 | } | ||
345 | if (urb->actual_length) { | 339 | if (urb->actual_length) { |
346 | tty_insert_flip_string(tty, data, urb->actual_length); | 340 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
347 | tty_flip_buffer_push(tty); | 341 | tty_flip_buffer_push(&port->port); |
348 | } | 342 | } |
349 | tty_kref_put(tty); | ||
350 | 343 | ||
351 | spin_lock(&priv->lock); | 344 | spin_lock(&priv->lock); |
352 | 345 | ||
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index fd8c35fd452e..8efa19d0e9fb 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1214,10 +1214,10 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1214 | spin_unlock_irqrestore(&priv->lock, flags); | 1214 | spin_unlock_irqrestore(&priv->lock, flags); |
1215 | 1215 | ||
1216 | /* process read if there is data other than line status */ | 1216 | /* process read if there is data other than line status */ |
1217 | if (tty && bytes > i) { | 1217 | if (bytes > i) { |
1218 | tty_insert_flip_string_fixed_flag(tty, data + i, | 1218 | tty_insert_flip_string_fixed_flag(&port->port, data + i, |
1219 | tty_flag, bytes - i); | 1219 | tty_flag, bytes - i); |
1220 | tty_flip_buffer_push(tty); | 1220 | tty_flip_buffer_push(&port->port); |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | spin_lock_irqsave(&priv->lock, flags); | 1223 | spin_lock_irqsave(&priv->lock, flags); |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 45d4af62967f..ebe45fa0ed50 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -1399,9 +1399,7 @@ static void digi_read_bulk_callback(struct urb *urb) | |||
1399 | 1399 | ||
1400 | static int digi_read_inb_callback(struct urb *urb) | 1400 | static int digi_read_inb_callback(struct urb *urb) |
1401 | { | 1401 | { |
1402 | |||
1403 | struct usb_serial_port *port = urb->context; | 1402 | struct usb_serial_port *port = urb->context; |
1404 | struct tty_struct *tty; | ||
1405 | struct digi_port *priv = usb_get_serial_port_data(port); | 1403 | struct digi_port *priv = usb_get_serial_port_data(port); |
1406 | int opcode = ((unsigned char *)urb->transfer_buffer)[0]; | 1404 | int opcode = ((unsigned char *)urb->transfer_buffer)[0]; |
1407 | int len = ((unsigned char *)urb->transfer_buffer)[1]; | 1405 | int len = ((unsigned char *)urb->transfer_buffer)[1]; |
@@ -1425,7 +1423,6 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1425 | return -1; | 1423 | return -1; |
1426 | } | 1424 | } |
1427 | 1425 | ||
1428 | tty = tty_port_tty_get(&port->port); | ||
1429 | spin_lock(&priv->dp_port_lock); | 1426 | spin_lock(&priv->dp_port_lock); |
1430 | 1427 | ||
1431 | /* check for throttle; if set, do not resubmit read urb */ | 1428 | /* check for throttle; if set, do not resubmit read urb */ |
@@ -1435,13 +1432,13 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1435 | priv->dp_throttle_restart = 1; | 1432 | priv->dp_throttle_restart = 1; |
1436 | 1433 | ||
1437 | /* receive data */ | 1434 | /* receive data */ |
1438 | if (tty && opcode == DIGI_CMD_RECEIVE_DATA) { | 1435 | if (opcode == DIGI_CMD_RECEIVE_DATA) { |
1439 | /* get flag from port_status */ | 1436 | /* get flag from port_status */ |
1440 | flag = 0; | 1437 | flag = 0; |
1441 | 1438 | ||
1442 | /* overrun is special, not associated with a char */ | 1439 | /* overrun is special, not associated with a char */ |
1443 | if (port_status & DIGI_OVERRUN_ERROR) | 1440 | if (port_status & DIGI_OVERRUN_ERROR) |
1444 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1441 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
1445 | 1442 | ||
1446 | /* break takes precedence over parity, */ | 1443 | /* break takes precedence over parity, */ |
1447 | /* which takes precedence over framing errors */ | 1444 | /* which takes precedence over framing errors */ |
@@ -1455,13 +1452,12 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1455 | /* data length is len-1 (one byte of len is port_status) */ | 1452 | /* data length is len-1 (one byte of len is port_status) */ |
1456 | --len; | 1453 | --len; |
1457 | if (len > 0) { | 1454 | if (len > 0) { |
1458 | tty_insert_flip_string_fixed_flag(tty, data, flag, | 1455 | tty_insert_flip_string_fixed_flag(&port->port, data, |
1459 | len); | 1456 | flag, len); |
1460 | tty_flip_buffer_push(tty); | 1457 | tty_flip_buffer_push(&port->port); |
1461 | } | 1458 | } |
1462 | } | 1459 | } |
1463 | spin_unlock(&priv->dp_port_lock); | 1460 | spin_unlock(&priv->dp_port_lock); |
1464 | tty_kref_put(tty); | ||
1465 | 1461 | ||
1466 | if (opcode == DIGI_CMD_RECEIVE_DISABLE) | 1462 | if (opcode == DIGI_CMD_RECEIVE_DISABLE) |
1467 | dev_dbg(&port->dev, "%s: got RECEIVE_DISABLE\n", __func__); | 1463 | dev_dbg(&port->dev, "%s: got RECEIVE_DISABLE\n", __func__); |
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 6e4eb57d0177..b1b2dc64b50b 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c | |||
@@ -100,7 +100,6 @@ static void f81232_process_read_urb(struct urb *urb) | |||
100 | { | 100 | { |
101 | struct usb_serial_port *port = urb->context; | 101 | struct usb_serial_port *port = urb->context; |
102 | struct f81232_private *priv = usb_get_serial_port_data(port); | 102 | struct f81232_private *priv = usb_get_serial_port_data(port); |
103 | struct tty_struct *tty; | ||
104 | unsigned char *data = urb->transfer_buffer; | 103 | unsigned char *data = urb->transfer_buffer; |
105 | char tty_flag = TTY_NORMAL; | 104 | char tty_flag = TTY_NORMAL; |
106 | unsigned long flags; | 105 | unsigned long flags; |
@@ -117,10 +116,6 @@ static void f81232_process_read_urb(struct urb *urb) | |||
117 | if (!urb->actual_length) | 116 | if (!urb->actual_length) |
118 | return; | 117 | return; |
119 | 118 | ||
120 | tty = tty_port_tty_get(&port->port); | ||
121 | if (!tty) | ||
122 | return; | ||
123 | |||
124 | /* break takes precedence over parity, */ | 119 | /* break takes precedence over parity, */ |
125 | /* which takes precedence over framing errors */ | 120 | /* which takes precedence over framing errors */ |
126 | if (line_status & UART_BREAK_ERROR) | 121 | if (line_status & UART_BREAK_ERROR) |
@@ -133,19 +128,19 @@ static void f81232_process_read_urb(struct urb *urb) | |||
133 | 128 | ||
134 | /* overrun is special, not associated with a char */ | 129 | /* overrun is special, not associated with a char */ |
135 | if (line_status & UART_OVERRUN_ERROR) | 130 | if (line_status & UART_OVERRUN_ERROR) |
136 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 131 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
137 | 132 | ||
138 | if (port->port.console && port->sysrq) { | 133 | if (port->port.console && port->sysrq) { |
139 | for (i = 0; i < urb->actual_length; ++i) | 134 | for (i = 0; i < urb->actual_length; ++i) |
140 | if (!usb_serial_handle_sysrq_char(port, data[i])) | 135 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
141 | tty_insert_flip_char(tty, data[i], tty_flag); | 136 | tty_insert_flip_char(&port->port, data[i], |
137 | tty_flag); | ||
142 | } else { | 138 | } else { |
143 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 139 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
144 | urb->actual_length); | 140 | urb->actual_length); |
145 | } | 141 | } |
146 | 142 | ||
147 | tty_flip_buffer_push(tty); | 143 | tty_flip_buffer_push(&port->port); |
148 | tty_kref_put(tty); | ||
149 | } | 144 | } |
150 | 145 | ||
151 | static int set_control_lines(struct usb_device *dev, u8 value) | 146 | static int set_control_lines(struct usb_device *dev, u8 value) |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d07fccf3bab5..edd162df49ca 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1960,9 +1960,8 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, | |||
1960 | 1960 | ||
1961 | #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) | 1961 | #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) |
1962 | 1962 | ||
1963 | static int ftdi_process_packet(struct tty_struct *tty, | 1963 | static int ftdi_process_packet(struct usb_serial_port *port, |
1964 | struct usb_serial_port *port, struct ftdi_private *priv, | 1964 | struct ftdi_private *priv, char *packet, int len) |
1965 | char *packet, int len) | ||
1966 | { | 1965 | { |
1967 | int i; | 1966 | int i; |
1968 | char status; | 1967 | char status; |
@@ -2012,7 +2011,7 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
2012 | /* Overrun is special, not associated with a char */ | 2011 | /* Overrun is special, not associated with a char */ |
2013 | if (packet[1] & FTDI_RS_OE) { | 2012 | if (packet[1] & FTDI_RS_OE) { |
2014 | priv->icount.overrun++; | 2013 | priv->icount.overrun++; |
2015 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 2014 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
2016 | } | 2015 | } |
2017 | } | 2016 | } |
2018 | 2017 | ||
@@ -2031,10 +2030,10 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
2031 | if (port->port.console && port->sysrq) { | 2030 | if (port->port.console && port->sysrq) { |
2032 | for (i = 0; i < len; i++, ch++) { | 2031 | for (i = 0; i < len; i++, ch++) { |
2033 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 2032 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
2034 | tty_insert_flip_char(tty, *ch, flag); | 2033 | tty_insert_flip_char(&port->port, *ch, flag); |
2035 | } | 2034 | } |
2036 | } else { | 2035 | } else { |
2037 | tty_insert_flip_string_fixed_flag(tty, ch, flag, len); | 2036 | tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len); |
2038 | } | 2037 | } |
2039 | 2038 | ||
2040 | return len; | 2039 | return len; |
@@ -2043,25 +2042,19 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
2043 | static void ftdi_process_read_urb(struct urb *urb) | 2042 | static void ftdi_process_read_urb(struct urb *urb) |
2044 | { | 2043 | { |
2045 | struct usb_serial_port *port = urb->context; | 2044 | struct usb_serial_port *port = urb->context; |
2046 | struct tty_struct *tty; | ||
2047 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2045 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2048 | char *data = (char *)urb->transfer_buffer; | 2046 | char *data = (char *)urb->transfer_buffer; |
2049 | int i; | 2047 | int i; |
2050 | int len; | 2048 | int len; |
2051 | int count = 0; | 2049 | int count = 0; |
2052 | 2050 | ||
2053 | tty = tty_port_tty_get(&port->port); | ||
2054 | if (!tty) | ||
2055 | return; | ||
2056 | |||
2057 | for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { | 2051 | for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { |
2058 | len = min_t(int, urb->actual_length - i, priv->max_packet_size); | 2052 | len = min_t(int, urb->actual_length - i, priv->max_packet_size); |
2059 | count += ftdi_process_packet(tty, port, priv, &data[i], len); | 2053 | count += ftdi_process_packet(port, priv, &data[i], len); |
2060 | } | 2054 | } |
2061 | 2055 | ||
2062 | if (count) | 2056 | if (count) |
2063 | tty_flip_buffer_push(tty); | 2057 | tty_flip_buffer_push(&port->port); |
2064 | tty_kref_put(tty); | ||
2065 | } | 2058 | } |
2066 | 2059 | ||
2067 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | 2060 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state) |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 203358d7e7bc..1a07b12ef341 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -252,14 +252,11 @@ static inline int isAbortTrfCmnd(const unsigned char *buf) | |||
252 | static void send_to_tty(struct usb_serial_port *port, | 252 | static void send_to_tty(struct usb_serial_port *port, |
253 | char *data, unsigned int actual_length) | 253 | char *data, unsigned int actual_length) |
254 | { | 254 | { |
255 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 255 | if (actual_length) { |
256 | |||
257 | if (tty && actual_length) { | ||
258 | usb_serial_debug_data(&port->dev, __func__, actual_length, data); | 256 | usb_serial_debug_data(&port->dev, __func__, actual_length, data); |
259 | tty_insert_flip_string(tty, data, actual_length); | 257 | tty_insert_flip_string(&port->port, data, actual_length); |
260 | tty_flip_buffer_push(tty); | 258 | tty_flip_buffer_push(&port->port); |
261 | } | 259 | } |
262 | tty_kref_put(tty); | ||
263 | } | 260 | } |
264 | 261 | ||
265 | 262 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 2ea70a631996..4c5c23f1cae5 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -313,30 +313,24 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs); | |||
313 | void usb_serial_generic_process_read_urb(struct urb *urb) | 313 | void usb_serial_generic_process_read_urb(struct urb *urb) |
314 | { | 314 | { |
315 | struct usb_serial_port *port = urb->context; | 315 | struct usb_serial_port *port = urb->context; |
316 | struct tty_struct *tty; | ||
317 | char *ch = (char *)urb->transfer_buffer; | 316 | char *ch = (char *)urb->transfer_buffer; |
318 | int i; | 317 | int i; |
319 | 318 | ||
320 | if (!urb->actual_length) | 319 | if (!urb->actual_length) |
321 | return; | 320 | return; |
322 | 321 | ||
323 | tty = tty_port_tty_get(&port->port); | ||
324 | if (!tty) | ||
325 | return; | ||
326 | |||
327 | /* The per character mucking around with sysrq path it too slow for | 322 | /* The per character mucking around with sysrq path it too slow for |
328 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases | 323 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases |
329 | where the USB serial is not a console anyway */ | 324 | where the USB serial is not a console anyway */ |
330 | if (!port->port.console || !port->sysrq) | 325 | if (!port->port.console || !port->sysrq) |
331 | tty_insert_flip_string(tty, ch, urb->actual_length); | 326 | tty_insert_flip_string(&port->port, ch, urb->actual_length); |
332 | else { | 327 | else { |
333 | for (i = 0; i < urb->actual_length; i++, ch++) { | 328 | for (i = 0; i < urb->actual_length; i++, ch++) { |
334 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 329 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
335 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 330 | tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); |
336 | } | 331 | } |
337 | } | 332 | } |
338 | tty_flip_buffer_push(tty); | 333 | tty_flip_buffer_push(&port->port); |
339 | tty_kref_put(tty); | ||
340 | } | 334 | } |
341 | EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb); | 335 | EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb); |
342 | 336 | ||
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 7b770c7f8b11..b00e5cbf741f 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -232,8 +232,8 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, | |||
232 | unsigned char *buffer, __u16 bufferLength); | 232 | unsigned char *buffer, __u16 bufferLength); |
233 | static void process_rcvd_status(struct edgeport_serial *edge_serial, | 233 | static void process_rcvd_status(struct edgeport_serial *edge_serial, |
234 | __u8 byte2, __u8 byte3); | 234 | __u8 byte2, __u8 byte3); |
235 | static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | 235 | static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data, |
236 | unsigned char *data, int length); | 236 | int length); |
237 | static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr); | 237 | static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr); |
238 | static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, | 238 | static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, |
239 | __u8 lsr, __u8 data); | 239 | __u8 lsr, __u8 data); |
@@ -1752,7 +1752,6 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, | |||
1752 | struct device *dev = &edge_serial->serial->dev->dev; | 1752 | struct device *dev = &edge_serial->serial->dev->dev; |
1753 | struct usb_serial_port *port; | 1753 | struct usb_serial_port *port; |
1754 | struct edgeport_port *edge_port; | 1754 | struct edgeport_port *edge_port; |
1755 | struct tty_struct *tty; | ||
1756 | __u16 lastBufferLength; | 1755 | __u16 lastBufferLength; |
1757 | __u16 rxLen; | 1756 | __u16 rxLen; |
1758 | 1757 | ||
@@ -1860,14 +1859,11 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, | |||
1860 | edge_serial->rxPort]; | 1859 | edge_serial->rxPort]; |
1861 | edge_port = usb_get_serial_port_data(port); | 1860 | edge_port = usb_get_serial_port_data(port); |
1862 | if (edge_port->open) { | 1861 | if (edge_port->open) { |
1863 | tty = tty_port_tty_get( | 1862 | dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n", |
1864 | &edge_port->port->port); | 1863 | __func__, rxLen, |
1865 | if (tty) { | 1864 | edge_serial->rxPort); |
1866 | dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n", | 1865 | edge_tty_recv(edge_port->port, buffer, |
1867 | __func__, rxLen, edge_serial->rxPort); | 1866 | rxLen); |
1868 | edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen); | ||
1869 | tty_kref_put(tty); | ||
1870 | } | ||
1871 | edge_port->icount.rx += rxLen; | 1867 | edge_port->icount.rx += rxLen; |
1872 | } | 1868 | } |
1873 | buffer += rxLen; | 1869 | buffer += rxLen; |
@@ -2017,20 +2013,20 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, | |||
2017 | * edge_tty_recv | 2013 | * edge_tty_recv |
2018 | * this function passes data on to the tty flip buffer | 2014 | * this function passes data on to the tty flip buffer |
2019 | *****************************************************************************/ | 2015 | *****************************************************************************/ |
2020 | static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | 2016 | static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data, |
2021 | unsigned char *data, int length) | 2017 | int length) |
2022 | { | 2018 | { |
2023 | int cnt; | 2019 | int cnt; |
2024 | 2020 | ||
2025 | cnt = tty_insert_flip_string(tty, data, length); | 2021 | cnt = tty_insert_flip_string(&port->port, data, length); |
2026 | if (cnt < length) { | 2022 | if (cnt < length) { |
2027 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 2023 | dev_err(&port->dev, "%s - dropping data, %d bytes lost\n", |
2028 | __func__, length - cnt); | 2024 | __func__, length - cnt); |
2029 | } | 2025 | } |
2030 | data += cnt; | 2026 | data += cnt; |
2031 | length -= cnt; | 2027 | length -= cnt; |
2032 | 2028 | ||
2033 | tty_flip_buffer_push(tty); | 2029 | tty_flip_buffer_push(&port->port); |
2034 | } | 2030 | } |
2035 | 2031 | ||
2036 | 2032 | ||
@@ -2086,14 +2082,9 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, | |||
2086 | } | 2082 | } |
2087 | 2083 | ||
2088 | /* Place LSR data byte into Rx buffer */ | 2084 | /* Place LSR data byte into Rx buffer */ |
2089 | if (lsrData) { | 2085 | if (lsrData) |
2090 | struct tty_struct *tty = | 2086 | edge_tty_recv(edge_port->port, &data, 1); |
2091 | tty_port_tty_get(&edge_port->port->port); | 2087 | |
2092 | if (tty) { | ||
2093 | edge_tty_recv(&edge_port->port->dev, tty, &data, 1); | ||
2094 | tty_kref_put(tty); | ||
2095 | } | ||
2096 | } | ||
2097 | /* update input line counters */ | 2088 | /* update input line counters */ |
2098 | icount = &edge_port->icount; | 2089 | icount = &edge_port->icount; |
2099 | if (newLsr & LSR_BREAK) | 2090 | if (newLsr & LSR_BREAK) |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 641ab3da2d83..c23776679f70 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -201,8 +201,8 @@ static int closing_wait = EDGE_CLOSING_WAIT; | |||
201 | static bool ignore_cpu_rev; | 201 | static bool ignore_cpu_rev; |
202 | static int default_uart_mode; /* RS232 */ | 202 | static int default_uart_mode; /* RS232 */ |
203 | 203 | ||
204 | static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | 204 | static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data, |
205 | unsigned char *data, int length); | 205 | int length); |
206 | 206 | ||
207 | static void stop_read(struct edgeport_port *edge_port); | 207 | static void stop_read(struct edgeport_port *edge_port); |
208 | static int restart_read(struct edgeport_port *edge_port); | 208 | static int restart_read(struct edgeport_port *edge_port); |
@@ -1484,7 +1484,6 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, | |||
1484 | struct async_icount *icount; | 1484 | struct async_icount *icount; |
1485 | __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | | 1485 | __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | |
1486 | LSR_FRM_ERR | LSR_BREAK)); | 1486 | LSR_FRM_ERR | LSR_BREAK)); |
1487 | struct tty_struct *tty; | ||
1488 | 1487 | ||
1489 | dev_dbg(&edge_port->port->dev, "%s - %02x\n", __func__, new_lsr); | 1488 | dev_dbg(&edge_port->port->dev, "%s - %02x\n", __func__, new_lsr); |
1490 | 1489 | ||
@@ -1498,13 +1497,8 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, | |||
1498 | new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); | 1497 | new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); |
1499 | 1498 | ||
1500 | /* Place LSR data byte into Rx buffer */ | 1499 | /* Place LSR data byte into Rx buffer */ |
1501 | if (lsr_data) { | 1500 | if (lsr_data) |
1502 | tty = tty_port_tty_get(&edge_port->port->port); | 1501 | edge_tty_recv(edge_port->port, &data, 1); |
1503 | if (tty) { | ||
1504 | edge_tty_recv(&edge_port->port->dev, tty, &data, 1); | ||
1505 | tty_kref_put(tty); | ||
1506 | } | ||
1507 | } | ||
1508 | 1502 | ||
1509 | /* update input line counters */ | 1503 | /* update input line counters */ |
1510 | icount = &edge_port->icount; | 1504 | icount = &edge_port->icount; |
@@ -1620,7 +1614,6 @@ static void edge_bulk_in_callback(struct urb *urb) | |||
1620 | struct edgeport_port *edge_port = urb->context; | 1614 | struct edgeport_port *edge_port = urb->context; |
1621 | struct device *dev = &edge_port->port->dev; | 1615 | struct device *dev = &edge_port->port->dev; |
1622 | unsigned char *data = urb->transfer_buffer; | 1616 | unsigned char *data = urb->transfer_buffer; |
1623 | struct tty_struct *tty; | ||
1624 | int retval = 0; | 1617 | int retval = 0; |
1625 | int port_number; | 1618 | int port_number; |
1626 | int status = urb->status; | 1619 | int status = urb->status; |
@@ -1659,17 +1652,16 @@ static void edge_bulk_in_callback(struct urb *urb) | |||
1659 | ++data; | 1652 | ++data; |
1660 | } | 1653 | } |
1661 | 1654 | ||
1662 | tty = tty_port_tty_get(&edge_port->port->port); | 1655 | if (urb->actual_length) { |
1663 | if (tty && urb->actual_length) { | ||
1664 | usb_serial_debug_data(dev, __func__, urb->actual_length, data); | 1656 | usb_serial_debug_data(dev, __func__, urb->actual_length, data); |
1665 | if (edge_port->close_pending) | 1657 | if (edge_port->close_pending) |
1666 | dev_dbg(dev, "%s - close pending, dropping data on the floor\n", | 1658 | dev_dbg(dev, "%s - close pending, dropping data on the floor\n", |
1667 | __func__); | 1659 | __func__); |
1668 | else | 1660 | else |
1669 | edge_tty_recv(dev, tty, data, urb->actual_length); | 1661 | edge_tty_recv(edge_port->port, data, |
1662 | urb->actual_length); | ||
1670 | edge_port->icount.rx += urb->actual_length; | 1663 | edge_port->icount.rx += urb->actual_length; |
1671 | } | 1664 | } |
1672 | tty_kref_put(tty); | ||
1673 | 1665 | ||
1674 | exit: | 1666 | exit: |
1675 | /* continue read unless stopped */ | 1667 | /* continue read unless stopped */ |
@@ -1684,16 +1676,16 @@ exit: | |||
1684 | dev_err(dev, "%s - usb_submit_urb failed with result %d\n", __func__, retval); | 1676 | dev_err(dev, "%s - usb_submit_urb failed with result %d\n", __func__, retval); |
1685 | } | 1677 | } |
1686 | 1678 | ||
1687 | static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | 1679 | static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data, |
1688 | unsigned char *data, int length) | 1680 | int length) |
1689 | { | 1681 | { |
1690 | int queued; | 1682 | int queued; |
1691 | 1683 | ||
1692 | queued = tty_insert_flip_string(tty, data, length); | 1684 | queued = tty_insert_flip_string(&port->port, data, length); |
1693 | if (queued < length) | 1685 | if (queued < length) |
1694 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1686 | dev_err(&port->dev, "%s - dropping data, %d bytes lost\n", |
1695 | __func__, length - queued); | 1687 | __func__, length - queued); |
1696 | tty_flip_buffer_push(tty); | 1688 | tty_flip_buffer_push(&port->port); |
1697 | } | 1689 | } |
1698 | 1690 | ||
1699 | static void edge_bulk_out_callback(struct urb *urb) | 1691 | static void edge_bulk_out_callback(struct urb *urb) |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index e24e2d4f4c1b..716930ab1bb1 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -287,7 +287,6 @@ static void ir_process_read_urb(struct urb *urb) | |||
287 | { | 287 | { |
288 | struct usb_serial_port *port = urb->context; | 288 | struct usb_serial_port *port = urb->context; |
289 | unsigned char *data = urb->transfer_buffer; | 289 | unsigned char *data = urb->transfer_buffer; |
290 | struct tty_struct *tty; | ||
291 | 290 | ||
292 | if (!urb->actual_length) | 291 | if (!urb->actual_length) |
293 | return; | 292 | return; |
@@ -302,12 +301,8 @@ static void ir_process_read_urb(struct urb *urb) | |||
302 | if (urb->actual_length == 1) | 301 | if (urb->actual_length == 1) |
303 | return; | 302 | return; |
304 | 303 | ||
305 | tty = tty_port_tty_get(&port->port); | 304 | tty_insert_flip_string(&port->port, data + 1, urb->actual_length - 1); |
306 | if (!tty) | 305 | tty_flip_buffer_push(&port->port); |
307 | return; | ||
308 | tty_insert_flip_string(tty, data + 1, urb->actual_length - 1); | ||
309 | tty_flip_buffer_push(tty); | ||
310 | tty_kref_put(tty); | ||
311 | } | 306 | } |
312 | 307 | ||
313 | static void ir_set_termios_callback(struct urb *urb) | 308 | static void ir_set_termios_callback(struct urb *urb) |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 1e1fbed65ef2..ff77027160aa 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -581,7 +581,6 @@ static void read_buf_callback(struct urb *urb) | |||
581 | { | 581 | { |
582 | struct usb_serial_port *port = urb->context; | 582 | struct usb_serial_port *port = urb->context; |
583 | unsigned char *data = urb->transfer_buffer; | 583 | unsigned char *data = urb->transfer_buffer; |
584 | struct tty_struct *tty; | ||
585 | int status = urb->status; | 584 | int status = urb->status; |
586 | 585 | ||
587 | if (status) { | 586 | if (status) { |
@@ -592,14 +591,12 @@ static void read_buf_callback(struct urb *urb) | |||
592 | } | 591 | } |
593 | 592 | ||
594 | dev_dbg(&port->dev, "%s - %i chars to write\n", __func__, urb->actual_length); | 593 | dev_dbg(&port->dev, "%s - %i chars to write\n", __func__, urb->actual_length); |
595 | tty = tty_port_tty_get(&port->port); | ||
596 | if (data == NULL) | 594 | if (data == NULL) |
597 | dev_dbg(&port->dev, "%s - data is NULL !!!\n", __func__); | 595 | dev_dbg(&port->dev, "%s - data is NULL !!!\n", __func__); |
598 | if (tty && urb->actual_length && data) { | 596 | if (urb->actual_length && data) { |
599 | tty_insert_flip_string(tty, data, urb->actual_length); | 597 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
600 | tty_flip_buffer_push(tty); | 598 | tty_flip_buffer_push(&port->port); |
601 | } | 599 | } |
602 | tty_kref_put(tty); | ||
603 | iuu_led_activity_on(urb); | 600 | iuu_led_activity_on(urb); |
604 | } | 601 | } |
605 | 602 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 3d95637f3d68..1fd1935c8316 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -291,7 +291,6 @@ static void usa26_indat_callback(struct urb *urb) | |||
291 | int i, err; | 291 | int i, err; |
292 | int endpoint; | 292 | int endpoint; |
293 | struct usb_serial_port *port; | 293 | struct usb_serial_port *port; |
294 | struct tty_struct *tty; | ||
295 | unsigned char *data = urb->transfer_buffer; | 294 | unsigned char *data = urb->transfer_buffer; |
296 | int status = urb->status; | 295 | int status = urb->status; |
297 | 296 | ||
@@ -304,8 +303,7 @@ static void usa26_indat_callback(struct urb *urb) | |||
304 | } | 303 | } |
305 | 304 | ||
306 | port = urb->context; | 305 | port = urb->context; |
307 | tty = tty_port_tty_get(&port->port); | 306 | if (urb->actual_length) { |
308 | if (tty && urb->actual_length) { | ||
309 | /* 0x80 bit is error flag */ | 307 | /* 0x80 bit is error flag */ |
310 | if ((data[0] & 0x80) == 0) { | 308 | if ((data[0] & 0x80) == 0) { |
311 | /* no errors on individual bytes, only | 309 | /* no errors on individual bytes, only |
@@ -315,7 +313,7 @@ static void usa26_indat_callback(struct urb *urb) | |||
315 | else | 313 | else |
316 | err = 0; | 314 | err = 0; |
317 | for (i = 1; i < urb->actual_length ; ++i) | 315 | for (i = 1; i < urb->actual_length ; ++i) |
318 | tty_insert_flip_char(tty, data[i], err); | 316 | tty_insert_flip_char(&port->port, data[i], err); |
319 | } else { | 317 | } else { |
320 | /* some bytes had errors, every byte has status */ | 318 | /* some bytes had errors, every byte has status */ |
321 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); | 319 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); |
@@ -328,12 +326,12 @@ static void usa26_indat_callback(struct urb *urb) | |||
328 | if (stat & RXERROR_PARITY) | 326 | if (stat & RXERROR_PARITY) |
329 | flag |= TTY_PARITY; | 327 | flag |= TTY_PARITY; |
330 | /* XXX should handle break (0x10) */ | 328 | /* XXX should handle break (0x10) */ |
331 | tty_insert_flip_char(tty, data[i+1], flag); | 329 | tty_insert_flip_char(&port->port, data[i+1], |
330 | flag); | ||
332 | } | 331 | } |
333 | } | 332 | } |
334 | tty_flip_buffer_push(tty); | 333 | tty_flip_buffer_push(&port->port); |
335 | } | 334 | } |
336 | tty_kref_put(tty); | ||
337 | 335 | ||
338 | /* Resubmit urb so we continue receiving */ | 336 | /* Resubmit urb so we continue receiving */ |
339 | err = usb_submit_urb(urb, GFP_ATOMIC); | 337 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -446,7 +444,6 @@ static void usa28_indat_callback(struct urb *urb) | |||
446 | { | 444 | { |
447 | int err; | 445 | int err; |
448 | struct usb_serial_port *port; | 446 | struct usb_serial_port *port; |
449 | struct tty_struct *tty; | ||
450 | unsigned char *data; | 447 | unsigned char *data; |
451 | struct keyspan_port_private *p_priv; | 448 | struct keyspan_port_private *p_priv; |
452 | int status = urb->status; | 449 | int status = urb->status; |
@@ -469,12 +466,11 @@ static void usa28_indat_callback(struct urb *urb) | |||
469 | p_priv = usb_get_serial_port_data(port); | 466 | p_priv = usb_get_serial_port_data(port); |
470 | data = urb->transfer_buffer; | 467 | data = urb->transfer_buffer; |
471 | 468 | ||
472 | tty = tty_port_tty_get(&port->port); | 469 | if (urb->actual_length) { |
473 | if (tty && urb->actual_length) { | 470 | tty_insert_flip_string(&port->port, data, |
474 | tty_insert_flip_string(tty, data, urb->actual_length); | 471 | urb->actual_length); |
475 | tty_flip_buffer_push(tty); | 472 | tty_flip_buffer_push(&port->port); |
476 | } | 473 | } |
477 | tty_kref_put(tty); | ||
478 | 474 | ||
479 | /* Resubmit urb so we continue receiving */ | 475 | /* Resubmit urb so we continue receiving */ |
480 | err = usb_submit_urb(urb, GFP_ATOMIC); | 476 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -669,7 +665,6 @@ static void usa49_indat_callback(struct urb *urb) | |||
669 | int i, err; | 665 | int i, err; |
670 | int endpoint; | 666 | int endpoint; |
671 | struct usb_serial_port *port; | 667 | struct usb_serial_port *port; |
672 | struct tty_struct *tty; | ||
673 | unsigned char *data = urb->transfer_buffer; | 668 | unsigned char *data = urb->transfer_buffer; |
674 | int status = urb->status; | 669 | int status = urb->status; |
675 | 670 | ||
@@ -682,12 +677,11 @@ static void usa49_indat_callback(struct urb *urb) | |||
682 | } | 677 | } |
683 | 678 | ||
684 | port = urb->context; | 679 | port = urb->context; |
685 | tty = tty_port_tty_get(&port->port); | 680 | if (urb->actual_length) { |
686 | if (tty && urb->actual_length) { | ||
687 | /* 0x80 bit is error flag */ | 681 | /* 0x80 bit is error flag */ |
688 | if ((data[0] & 0x80) == 0) { | 682 | if ((data[0] & 0x80) == 0) { |
689 | /* no error on any byte */ | 683 | /* no error on any byte */ |
690 | tty_insert_flip_string(tty, data + 1, | 684 | tty_insert_flip_string(&port->port, data + 1, |
691 | urb->actual_length - 1); | 685 | urb->actual_length - 1); |
692 | } else { | 686 | } else { |
693 | /* some bytes had errors, every byte has status */ | 687 | /* some bytes had errors, every byte has status */ |
@@ -700,12 +694,12 @@ static void usa49_indat_callback(struct urb *urb) | |||
700 | if (stat & RXERROR_PARITY) | 694 | if (stat & RXERROR_PARITY) |
701 | flag |= TTY_PARITY; | 695 | flag |= TTY_PARITY; |
702 | /* XXX should handle break (0x10) */ | 696 | /* XXX should handle break (0x10) */ |
703 | tty_insert_flip_char(tty, data[i+1], flag); | 697 | tty_insert_flip_char(&port->port, data[i+1], |
698 | flag); | ||
704 | } | 699 | } |
705 | } | 700 | } |
706 | tty_flip_buffer_push(tty); | 701 | tty_flip_buffer_push(&port->port); |
707 | } | 702 | } |
708 | tty_kref_put(tty); | ||
709 | 703 | ||
710 | /* Resubmit urb so we continue receiving */ | 704 | /* Resubmit urb so we continue receiving */ |
711 | err = usb_submit_urb(urb, GFP_ATOMIC); | 705 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -718,7 +712,6 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
718 | int i, len, x, err; | 712 | int i, len, x, err; |
719 | struct usb_serial *serial; | 713 | struct usb_serial *serial; |
720 | struct usb_serial_port *port; | 714 | struct usb_serial_port *port; |
721 | struct tty_struct *tty; | ||
722 | unsigned char *data = urb->transfer_buffer; | 715 | unsigned char *data = urb->transfer_buffer; |
723 | int status = urb->status; | 716 | int status = urb->status; |
724 | 717 | ||
@@ -743,7 +736,6 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
743 | return; | 736 | return; |
744 | } | 737 | } |
745 | port = serial->port[data[i++]]; | 738 | port = serial->port[data[i++]]; |
746 | tty = tty_port_tty_get(&port->port); | ||
747 | len = data[i++]; | 739 | len = data[i++]; |
748 | 740 | ||
749 | /* 0x80 bit is error flag */ | 741 | /* 0x80 bit is error flag */ |
@@ -751,7 +743,8 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
751 | /* no error on any byte */ | 743 | /* no error on any byte */ |
752 | i++; | 744 | i++; |
753 | for (x = 1; x < len ; ++x) | 745 | for (x = 1; x < len ; ++x) |
754 | tty_insert_flip_char(tty, data[i++], 0); | 746 | tty_insert_flip_char(&port->port, |
747 | data[i++], 0); | ||
755 | } else { | 748 | } else { |
756 | /* | 749 | /* |
757 | * some bytes had errors, every byte has status | 750 | * some bytes had errors, every byte has status |
@@ -765,13 +758,12 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
765 | if (stat & RXERROR_PARITY) | 758 | if (stat & RXERROR_PARITY) |
766 | flag |= TTY_PARITY; | 759 | flag |= TTY_PARITY; |
767 | /* XXX should handle break (0x10) */ | 760 | /* XXX should handle break (0x10) */ |
768 | tty_insert_flip_char(tty, | 761 | tty_insert_flip_char(&port->port, |
769 | data[i+1], flag); | 762 | data[i+1], flag); |
770 | i += 2; | 763 | i += 2; |
771 | } | 764 | } |
772 | } | 765 | } |
773 | tty_flip_buffer_push(tty); | 766 | tty_flip_buffer_push(&port->port); |
774 | tty_kref_put(tty); | ||
775 | } | 767 | } |
776 | } | 768 | } |
777 | 769 | ||
@@ -792,7 +784,6 @@ static void usa90_indat_callback(struct urb *urb) | |||
792 | int endpoint; | 784 | int endpoint; |
793 | struct usb_serial_port *port; | 785 | struct usb_serial_port *port; |
794 | struct keyspan_port_private *p_priv; | 786 | struct keyspan_port_private *p_priv; |
795 | struct tty_struct *tty; | ||
796 | unsigned char *data = urb->transfer_buffer; | 787 | unsigned char *data = urb->transfer_buffer; |
797 | int status = urb->status; | 788 | int status = urb->status; |
798 | 789 | ||
@@ -808,12 +799,12 @@ static void usa90_indat_callback(struct urb *urb) | |||
808 | p_priv = usb_get_serial_port_data(port); | 799 | p_priv = usb_get_serial_port_data(port); |
809 | 800 | ||
810 | if (urb->actual_length) { | 801 | if (urb->actual_length) { |
811 | tty = tty_port_tty_get(&port->port); | ||
812 | /* if current mode is DMA, looks like usa28 format | 802 | /* if current mode is DMA, looks like usa28 format |
813 | otherwise looks like usa26 data format */ | 803 | otherwise looks like usa26 data format */ |
814 | 804 | ||
815 | if (p_priv->baud > 57600) | 805 | if (p_priv->baud > 57600) |
816 | tty_insert_flip_string(tty, data, urb->actual_length); | 806 | tty_insert_flip_string(&port->port, data, |
807 | urb->actual_length); | ||
817 | else { | 808 | else { |
818 | /* 0x80 bit is error flag */ | 809 | /* 0x80 bit is error flag */ |
819 | if ((data[0] & 0x80) == 0) { | 810 | if ((data[0] & 0x80) == 0) { |
@@ -824,8 +815,8 @@ static void usa90_indat_callback(struct urb *urb) | |||
824 | else | 815 | else |
825 | err = 0; | 816 | err = 0; |
826 | for (i = 1; i < urb->actual_length ; ++i) | 817 | for (i = 1; i < urb->actual_length ; ++i) |
827 | tty_insert_flip_char(tty, data[i], | 818 | tty_insert_flip_char(&port->port, |
828 | err); | 819 | data[i], err); |
829 | } else { | 820 | } else { |
830 | /* some bytes had errors, every byte has status */ | 821 | /* some bytes had errors, every byte has status */ |
831 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); | 822 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); |
@@ -838,13 +829,12 @@ static void usa90_indat_callback(struct urb *urb) | |||
838 | if (stat & RXERROR_PARITY) | 829 | if (stat & RXERROR_PARITY) |
839 | flag |= TTY_PARITY; | 830 | flag |= TTY_PARITY; |
840 | /* XXX should handle break (0x10) */ | 831 | /* XXX should handle break (0x10) */ |
841 | tty_insert_flip_char(tty, data[i+1], | 832 | tty_insert_flip_char(&port->port, |
842 | flag); | 833 | data[i+1], flag); |
843 | } | 834 | } |
844 | } | 835 | } |
845 | } | 836 | } |
846 | tty_flip_buffer_push(tty); | 837 | tty_flip_buffer_push(&port->port); |
847 | tty_kref_put(tty); | ||
848 | } | 838 | } |
849 | 839 | ||
850 | /* Resubmit urb so we continue receiving */ | 840 | /* Resubmit urb so we continue receiving */ |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 41b01092af07..3b17d5d13dc8 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -138,7 +138,6 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work) | |||
138 | static void keyspan_pda_rx_interrupt(struct urb *urb) | 138 | static void keyspan_pda_rx_interrupt(struct urb *urb) |
139 | { | 139 | { |
140 | struct usb_serial_port *port = urb->context; | 140 | struct usb_serial_port *port = urb->context; |
141 | struct tty_struct *tty; | ||
142 | unsigned char *data = urb->transfer_buffer; | 141 | unsigned char *data = urb->transfer_buffer; |
143 | int retval; | 142 | int retval; |
144 | int status = urb->status; | 143 | int status = urb->status; |
@@ -163,14 +162,12 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) | |||
163 | /* see if the message is data or a status interrupt */ | 162 | /* see if the message is data or a status interrupt */ |
164 | switch (data[0]) { | 163 | switch (data[0]) { |
165 | case 0: | 164 | case 0: |
166 | tty = tty_port_tty_get(&port->port); | ||
167 | /* rest of message is rx data */ | 165 | /* rest of message is rx data */ |
168 | if (tty && urb->actual_length) { | 166 | if (urb->actual_length) { |
169 | tty_insert_flip_string(tty, data + 1, | 167 | tty_insert_flip_string(&port->port, data + 1, |
170 | urb->actual_length - 1); | 168 | urb->actual_length - 1); |
171 | tty_flip_buffer_push(tty); | 169 | tty_flip_buffer_push(&port->port); |
172 | } | 170 | } |
173 | tty_kref_put(tty); | ||
174 | break; | 171 | break; |
175 | case 1: | 172 | case 1: |
176 | /* status interrupt */ | 173 | /* status interrupt */ |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index fc9e14a1e9b3..769d910ae0a5 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -389,7 +389,6 @@ static void klsi_105_process_read_urb(struct urb *urb) | |||
389 | { | 389 | { |
390 | struct usb_serial_port *port = urb->context; | 390 | struct usb_serial_port *port = urb->context; |
391 | unsigned char *data = urb->transfer_buffer; | 391 | unsigned char *data = urb->transfer_buffer; |
392 | struct tty_struct *tty; | ||
393 | unsigned len; | 392 | unsigned len; |
394 | 393 | ||
395 | /* empty urbs seem to happen, we ignore them */ | 394 | /* empty urbs seem to happen, we ignore them */ |
@@ -401,19 +400,14 @@ static void klsi_105_process_read_urb(struct urb *urb) | |||
401 | return; | 400 | return; |
402 | } | 401 | } |
403 | 402 | ||
404 | tty = tty_port_tty_get(&port->port); | ||
405 | if (!tty) | ||
406 | return; | ||
407 | |||
408 | len = get_unaligned_le16(data); | 403 | len = get_unaligned_le16(data); |
409 | if (len > urb->actual_length - KLSI_HDR_LEN) { | 404 | if (len > urb->actual_length - KLSI_HDR_LEN) { |
410 | dev_dbg(&port->dev, "%s - packet length mismatch\n", __func__); | 405 | dev_dbg(&port->dev, "%s - packet length mismatch\n", __func__); |
411 | len = urb->actual_length - KLSI_HDR_LEN; | 406 | len = urb->actual_length - KLSI_HDR_LEN; |
412 | } | 407 | } |
413 | 408 | ||
414 | tty_insert_flip_string(tty, data + KLSI_HDR_LEN, len); | 409 | tty_insert_flip_string(&port->port, data + KLSI_HDR_LEN, len); |
415 | tty_flip_buffer_push(tty); | 410 | tty_flip_buffer_push(&port->port); |
416 | tty_kref_put(tty); | ||
417 | } | 411 | } |
418 | 412 | ||
419 | static void klsi_105_set_termios(struct tty_struct *tty, | 413 | static void klsi_105_set_termios(struct tty_struct *tty, |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index b747ba615d0b..903d938e174b 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -324,7 +324,6 @@ static void kobil_read_int_callback(struct urb *urb) | |||
324 | { | 324 | { |
325 | int result; | 325 | int result; |
326 | struct usb_serial_port *port = urb->context; | 326 | struct usb_serial_port *port = urb->context; |
327 | struct tty_struct *tty; | ||
328 | unsigned char *data = urb->transfer_buffer; | 327 | unsigned char *data = urb->transfer_buffer; |
329 | int status = urb->status; | 328 | int status = urb->status; |
330 | 329 | ||
@@ -333,8 +332,7 @@ static void kobil_read_int_callback(struct urb *urb) | |||
333 | return; | 332 | return; |
334 | } | 333 | } |
335 | 334 | ||
336 | tty = tty_port_tty_get(&port->port); | 335 | if (urb->actual_length) { |
337 | if (tty && urb->actual_length) { | ||
338 | 336 | ||
339 | /* BEGIN DEBUG */ | 337 | /* BEGIN DEBUG */ |
340 | /* | 338 | /* |
@@ -353,10 +351,9 @@ static void kobil_read_int_callback(struct urb *urb) | |||
353 | */ | 351 | */ |
354 | /* END DEBUG */ | 352 | /* END DEBUG */ |
355 | 353 | ||
356 | tty_insert_flip_string(tty, data, urb->actual_length); | 354 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
357 | tty_flip_buffer_push(tty); | 355 | tty_flip_buffer_push(&port->port); |
358 | } | 356 | } |
359 | tty_kref_put(tty); | ||
360 | 357 | ||
361 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 358 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
362 | dev_dbg(&port->dev, "%s - Send read URB returns: %i\n", __func__, result); | 359 | dev_dbg(&port->dev, "%s - Send read URB returns: %i\n", __func__, result); |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index d9c86516fed4..a64d420f687b 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -527,7 +527,6 @@ static void mct_u232_read_int_callback(struct urb *urb) | |||
527 | { | 527 | { |
528 | struct usb_serial_port *port = urb->context; | 528 | struct usb_serial_port *port = urb->context; |
529 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 529 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
530 | struct tty_struct *tty; | ||
531 | unsigned char *data = urb->transfer_buffer; | 530 | unsigned char *data = urb->transfer_buffer; |
532 | int retval; | 531 | int retval; |
533 | int status = urb->status; | 532 | int status = urb->status; |
@@ -557,13 +556,9 @@ static void mct_u232_read_int_callback(struct urb *urb) | |||
557 | */ | 556 | */ |
558 | if (urb->transfer_buffer_length > 2) { | 557 | if (urb->transfer_buffer_length > 2) { |
559 | if (urb->actual_length) { | 558 | if (urb->actual_length) { |
560 | tty = tty_port_tty_get(&port->port); | 559 | tty_insert_flip_string(&port->port, data, |
561 | if (tty) { | 560 | urb->actual_length); |
562 | tty_insert_flip_string(tty, data, | 561 | tty_flip_buffer_push(&port->port); |
563 | urb->actual_length); | ||
564 | tty_flip_buffer_push(tty); | ||
565 | } | ||
566 | tty_kref_put(tty); | ||
567 | } | 562 | } |
568 | goto exit; | 563 | goto exit; |
569 | } | 564 | } |
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 3d258448c29a..bf3c7a23553e 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c | |||
@@ -95,7 +95,6 @@ static void metrousb_read_int_callback(struct urb *urb) | |||
95 | { | 95 | { |
96 | struct usb_serial_port *port = urb->context; | 96 | struct usb_serial_port *port = urb->context; |
97 | struct metrousb_private *metro_priv = usb_get_serial_port_data(port); | 97 | struct metrousb_private *metro_priv = usb_get_serial_port_data(port); |
98 | struct tty_struct *tty; | ||
99 | unsigned char *data = urb->transfer_buffer; | 98 | unsigned char *data = urb->transfer_buffer; |
100 | int throttled = 0; | 99 | int throttled = 0; |
101 | int result = 0; | 100 | int result = 0; |
@@ -124,15 +123,13 @@ static void metrousb_read_int_callback(struct urb *urb) | |||
124 | 123 | ||
125 | 124 | ||
126 | /* Set the data read from the usb port into the serial port buffer. */ | 125 | /* Set the data read from the usb port into the serial port buffer. */ |
127 | tty = tty_port_tty_get(&port->port); | 126 | if (urb->actual_length) { |
128 | if (tty && urb->actual_length) { | ||
129 | /* Loop through the data copying each byte to the tty layer. */ | 127 | /* Loop through the data copying each byte to the tty layer. */ |
130 | tty_insert_flip_string(tty, data, urb->actual_length); | 128 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
131 | 129 | ||
132 | /* Force the data to the tty layer. */ | 130 | /* Force the data to the tty layer. */ |
133 | tty_flip_buffer_push(tty); | 131 | tty_flip_buffer_push(&port->port); |
134 | } | 132 | } |
135 | tty_kref_put(tty); | ||
136 | 133 | ||
137 | /* Set any port variables. */ | 134 | /* Set any port variables. */ |
138 | spin_lock_irqsave(&metro_priv->lock, flags); | 135 | spin_lock_irqsave(&metro_priv->lock, flags); |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index f57a6b1fe787..e0ebec3b5d6a 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -899,7 +899,6 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
899 | int retval; | 899 | int retval; |
900 | unsigned char *data ; | 900 | unsigned char *data ; |
901 | struct usb_serial_port *port; | 901 | struct usb_serial_port *port; |
902 | struct tty_struct *tty; | ||
903 | int status = urb->status; | 902 | int status = urb->status; |
904 | 903 | ||
905 | if (status) { | 904 | if (status) { |
@@ -913,12 +912,10 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
913 | 912 | ||
914 | data = urb->transfer_buffer; | 913 | data = urb->transfer_buffer; |
915 | 914 | ||
916 | tty = tty_port_tty_get(&port->port); | 915 | if (urb->actual_length) { |
917 | if (tty && urb->actual_length) { | 916 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
918 | tty_insert_flip_string(tty, data, urb->actual_length); | 917 | tty_flip_buffer_push(&port->port); |
919 | tty_flip_buffer_push(tty); | ||
920 | } | 918 | } |
921 | tty_kref_put(tty); | ||
922 | 919 | ||
923 | if (port->read_urb->status != -EINPROGRESS) { | 920 | if (port->read_urb->status != -EINPROGRESS) { |
924 | retval = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 921 | retval = usb_submit_urb(port->read_urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 66d9e088d9d9..809fb329eca5 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -744,7 +744,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
744 | struct usb_serial *serial; | 744 | struct usb_serial *serial; |
745 | struct usb_serial_port *port; | 745 | struct usb_serial_port *port; |
746 | struct moschip_port *mos7840_port; | 746 | struct moschip_port *mos7840_port; |
747 | struct tty_struct *tty; | ||
748 | int status = urb->status; | 747 | int status = urb->status; |
749 | 748 | ||
750 | mos7840_port = urb->context; | 749 | mos7840_port = urb->context; |
@@ -773,12 +772,9 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
773 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); | 772 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); |
774 | 773 | ||
775 | if (urb->actual_length) { | 774 | if (urb->actual_length) { |
776 | tty = tty_port_tty_get(&mos7840_port->port->port); | 775 | struct tty_port *tport = &mos7840_port->port->port; |
777 | if (tty) { | 776 | tty_insert_flip_string(tport, data, urb->actual_length); |
778 | tty_insert_flip_string(tty, data, urb->actual_length); | 777 | tty_flip_buffer_push(tport); |
779 | tty_flip_buffer_push(tty); | ||
780 | tty_kref_put(tty); | ||
781 | } | ||
782 | mos7840_port->icount.rx += urb->actual_length; | 778 | mos7840_port->icount.rx += urb->actual_length; |
783 | smp_wmb(); | 779 | smp_wmb(); |
784 | dev_dbg(&port->dev, "mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx); | 780 | dev_dbg(&port->dev, "mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx); |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 1566f8f500ae..38725fc8c2c8 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -32,7 +32,6 @@ static void navman_read_int_callback(struct urb *urb) | |||
32 | { | 32 | { |
33 | struct usb_serial_port *port = urb->context; | 33 | struct usb_serial_port *port = urb->context; |
34 | unsigned char *data = urb->transfer_buffer; | 34 | unsigned char *data = urb->transfer_buffer; |
35 | struct tty_struct *tty; | ||
36 | int status = urb->status; | 35 | int status = urb->status; |
37 | int result; | 36 | int result; |
38 | 37 | ||
@@ -55,12 +54,10 @@ static void navman_read_int_callback(struct urb *urb) | |||
55 | 54 | ||
56 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); | 55 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); |
57 | 56 | ||
58 | tty = tty_port_tty_get(&port->port); | 57 | if (urb->actual_length) { |
59 | if (tty && urb->actual_length) { | 58 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
60 | tty_insert_flip_string(tty, data, urb->actual_length); | 59 | tty_flip_buffer_push(&port->port); |
61 | tty_flip_buffer_push(tty); | ||
62 | } | 60 | } |
63 | tty_kref_put(tty); | ||
64 | 61 | ||
65 | exit: | 62 | exit: |
66 | result = usb_submit_urb(urb, GFP_ATOMIC); | 63 | result = usb_submit_urb(urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 7818af931a48..1e1cafe287e4 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -174,13 +174,9 @@ static void omninet_read_bulk_callback(struct urb *urb) | |||
174 | } | 174 | } |
175 | 175 | ||
176 | if (urb->actual_length && header->oh_len) { | 176 | if (urb->actual_length && header->oh_len) { |
177 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 177 | tty_insert_flip_string(&port->port, data + OMNINET_DATAOFFSET, |
178 | if (tty) { | 178 | header->oh_len); |
179 | tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET, | 179 | tty_flip_buffer_push(&port->port); |
180 | header->oh_len); | ||
181 | tty_flip_buffer_push(tty); | ||
182 | tty_kref_put(tty); | ||
183 | } | ||
184 | } | 180 | } |
185 | 181 | ||
186 | /* Continue trying to always read */ | 182 | /* Continue trying to always read */ |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index c6bfb83efb1e..e13e1a4d3e1e 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -51,15 +51,8 @@ struct opticon_private { | |||
51 | static void opticon_process_data_packet(struct usb_serial_port *port, | 51 | static void opticon_process_data_packet(struct usb_serial_port *port, |
52 | const unsigned char *buf, size_t len) | 52 | const unsigned char *buf, size_t len) |
53 | { | 53 | { |
54 | struct tty_struct *tty; | 54 | tty_insert_flip_string(&port->port, buf, len); |
55 | 55 | tty_flip_buffer_push(&port->port); | |
56 | tty = tty_port_tty_get(&port->port); | ||
57 | if (!tty) | ||
58 | return; | ||
59 | |||
60 | tty_insert_flip_string(tty, buf, len); | ||
61 | tty_flip_buffer_push(tty); | ||
62 | tty_kref_put(tty); | ||
63 | } | 56 | } |
64 | 57 | ||
65 | static void opticon_process_status_packet(struct usb_serial_port *port, | 58 | static void opticon_process_status_packet(struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index d217fd6ee43f..a958fd41b5b3 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -820,7 +820,6 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
820 | { | 820 | { |
821 | struct usb_serial_port *port = urb->context; | 821 | struct usb_serial_port *port = urb->context; |
822 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 822 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
823 | struct tty_struct *tty; | ||
824 | unsigned char *data = urb->transfer_buffer; | 823 | unsigned char *data = urb->transfer_buffer; |
825 | unsigned long flags; | 824 | unsigned long flags; |
826 | int status = urb->status; | 825 | int status = urb->status; |
@@ -835,12 +834,10 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
835 | return; | 834 | return; |
836 | } | 835 | } |
837 | 836 | ||
838 | tty = tty_port_tty_get(&port->port); | 837 | if (urb->actual_length > 0) { |
839 | if (tty != NULL && urb->actual_length > 0) { | 838 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
840 | tty_insert_flip_string(tty, data, urb->actual_length); | 839 | tty_flip_buffer_push(&port->port); |
841 | tty_flip_buffer_push(tty); | ||
842 | } | 840 | } |
843 | tty_kref_put(tty); | ||
844 | 841 | ||
845 | /* schedule the interrupt urb */ | 842 | /* schedule the interrupt urb */ |
846 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 843 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 600241901361..54adc9125e5c 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -772,7 +772,6 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
772 | { | 772 | { |
773 | struct usb_serial_port *port = urb->context; | 773 | struct usb_serial_port *port = urb->context; |
774 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 774 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
775 | struct tty_struct *tty; | ||
776 | unsigned char *data = urb->transfer_buffer; | 775 | unsigned char *data = urb->transfer_buffer; |
777 | char tty_flag = TTY_NORMAL; | 776 | char tty_flag = TTY_NORMAL; |
778 | unsigned long flags; | 777 | unsigned long flags; |
@@ -789,10 +788,6 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
789 | if (!urb->actual_length) | 788 | if (!urb->actual_length) |
790 | return; | 789 | return; |
791 | 790 | ||
792 | tty = tty_port_tty_get(&port->port); | ||
793 | if (!tty) | ||
794 | return; | ||
795 | |||
796 | /* break takes precedence over parity, */ | 791 | /* break takes precedence over parity, */ |
797 | /* which takes precedence over framing errors */ | 792 | /* which takes precedence over framing errors */ |
798 | if (line_status & UART_BREAK_ERROR) | 793 | if (line_status & UART_BREAK_ERROR) |
@@ -805,19 +800,19 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
805 | 800 | ||
806 | /* overrun is special, not associated with a char */ | 801 | /* overrun is special, not associated with a char */ |
807 | if (line_status & UART_OVERRUN_ERROR) | 802 | if (line_status & UART_OVERRUN_ERROR) |
808 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 803 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
809 | 804 | ||
810 | if (port->port.console && port->sysrq) { | 805 | if (port->port.console && port->sysrq) { |
811 | for (i = 0; i < urb->actual_length; ++i) | 806 | for (i = 0; i < urb->actual_length; ++i) |
812 | if (!usb_serial_handle_sysrq_char(port, data[i])) | 807 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
813 | tty_insert_flip_char(tty, data[i], tty_flag); | 808 | tty_insert_flip_char(&port->port, data[i], |
809 | tty_flag); | ||
814 | } else { | 810 | } else { |
815 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 811 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
816 | urb->actual_length); | 812 | urb->actual_length); |
817 | } | 813 | } |
818 | 814 | ||
819 | tty_flip_buffer_push(tty); | 815 | tty_flip_buffer_push(&port->port); |
820 | tty_kref_put(tty); | ||
821 | } | 816 | } |
822 | 817 | ||
823 | /* All of the device info needed for the PL2303 SIO serial converter */ | 818 | /* All of the device info needed for the PL2303 SIO serial converter */ |
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index a8d5110d4cc5..00e6c9bac8a3 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
@@ -609,7 +609,6 @@ void qt2_process_read_urb(struct urb *urb) | |||
609 | struct qt2_serial_private *serial_priv; | 609 | struct qt2_serial_private *serial_priv; |
610 | struct usb_serial_port *port; | 610 | struct usb_serial_port *port; |
611 | struct qt2_port_private *port_priv; | 611 | struct qt2_port_private *port_priv; |
612 | struct tty_struct *tty; | ||
613 | bool escapeflag; | 612 | bool escapeflag; |
614 | unsigned char *ch; | 613 | unsigned char *ch; |
615 | int i; | 614 | int i; |
@@ -620,15 +619,11 @@ void qt2_process_read_urb(struct urb *urb) | |||
620 | return; | 619 | return; |
621 | 620 | ||
622 | ch = urb->transfer_buffer; | 621 | ch = urb->transfer_buffer; |
623 | tty = NULL; | ||
624 | serial = urb->context; | 622 | serial = urb->context; |
625 | serial_priv = usb_get_serial_data(serial); | 623 | serial_priv = usb_get_serial_data(serial); |
626 | port = serial->port[serial_priv->current_port]; | 624 | port = serial->port[serial_priv->current_port]; |
627 | port_priv = usb_get_serial_port_data(port); | 625 | port_priv = usb_get_serial_port_data(port); |
628 | 626 | ||
629 | if (port_priv->is_open) | ||
630 | tty = tty_port_tty_get(&port->port); | ||
631 | |||
632 | for (i = 0; i < urb->actual_length; i++) { | 627 | for (i = 0; i < urb->actual_length; i++) { |
633 | ch = (unsigned char *)urb->transfer_buffer + i; | 628 | ch = (unsigned char *)urb->transfer_buffer + i; |
634 | if ((i <= (len - 3)) && | 629 | if ((i <= (len - 3)) && |
@@ -666,10 +661,7 @@ void qt2_process_read_urb(struct urb *urb) | |||
666 | __func__); | 661 | __func__); |
667 | break; | 662 | break; |
668 | } | 663 | } |
669 | if (tty) { | 664 | tty_flip_buffer_push(&port->port); |
670 | tty_flip_buffer_push(tty); | ||
671 | tty_kref_put(tty); | ||
672 | } | ||
673 | 665 | ||
674 | newport = *(ch + 3); | 666 | newport = *(ch + 3); |
675 | 667 | ||
@@ -683,10 +675,6 @@ void qt2_process_read_urb(struct urb *urb) | |||
683 | serial_priv->current_port = newport; | 675 | serial_priv->current_port = newport; |
684 | port = serial->port[serial_priv->current_port]; | 676 | port = serial->port[serial_priv->current_port]; |
685 | port_priv = usb_get_serial_port_data(port); | 677 | port_priv = usb_get_serial_port_data(port); |
686 | if (port_priv->is_open) | ||
687 | tty = tty_port_tty_get(&port->port); | ||
688 | else | ||
689 | tty = NULL; | ||
690 | i += 3; | 678 | i += 3; |
691 | escapeflag = true; | 679 | escapeflag = true; |
692 | break; | 680 | break; |
@@ -697,8 +685,8 @@ void qt2_process_read_urb(struct urb *urb) | |||
697 | escapeflag = true; | 685 | escapeflag = true; |
698 | break; | 686 | break; |
699 | case QT2_CONTROL_ESCAPE: | 687 | case QT2_CONTROL_ESCAPE: |
700 | tty_buffer_request_room(tty, 2); | 688 | tty_buffer_request_room(&port->port, 2); |
701 | tty_insert_flip_string(tty, ch, 2); | 689 | tty_insert_flip_string(&port->port, ch, 2); |
702 | i += 2; | 690 | i += 2; |
703 | escapeflag = true; | 691 | escapeflag = true; |
704 | break; | 692 | break; |
@@ -712,16 +700,11 @@ void qt2_process_read_urb(struct urb *urb) | |||
712 | continue; | 700 | continue; |
713 | } | 701 | } |
714 | 702 | ||
715 | if (tty) { | 703 | tty_buffer_request_room(&port->port, 1); |
716 | tty_buffer_request_room(tty, 1); | 704 | tty_insert_flip_string(&port->port, ch, 1); |
717 | tty_insert_flip_string(tty, ch, 1); | ||
718 | } | ||
719 | } | 705 | } |
720 | 706 | ||
721 | if (tty) { | 707 | tty_flip_buffer_push(&port->port); |
722 | tty_flip_buffer_push(tty); | ||
723 | tty_kref_put(tty); | ||
724 | } | ||
725 | } | 708 | } |
726 | 709 | ||
727 | static void qt2_write_bulk_callback(struct urb *urb) | 710 | static void qt2_write_bulk_callback(struct urb *urb) |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index c949ce6ef0c6..21cd7bf2a8cc 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -207,38 +207,31 @@ static void safe_process_read_urb(struct urb *urb) | |||
207 | unsigned char *data = urb->transfer_buffer; | 207 | unsigned char *data = urb->transfer_buffer; |
208 | unsigned char length = urb->actual_length; | 208 | unsigned char length = urb->actual_length; |
209 | int actual_length; | 209 | int actual_length; |
210 | struct tty_struct *tty; | ||
211 | __u16 fcs; | 210 | __u16 fcs; |
212 | 211 | ||
213 | if (!length) | 212 | if (!length) |
214 | return; | 213 | return; |
215 | 214 | ||
216 | tty = tty_port_tty_get(&port->port); | ||
217 | if (!tty) | ||
218 | return; | ||
219 | |||
220 | if (!safe) | 215 | if (!safe) |
221 | goto out; | 216 | goto out; |
222 | 217 | ||
223 | fcs = fcs_compute10(data, length, CRC10_INITFCS); | 218 | fcs = fcs_compute10(data, length, CRC10_INITFCS); |
224 | if (fcs) { | 219 | if (fcs) { |
225 | dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); | 220 | dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); |
226 | goto err; | 221 | return; |
227 | } | 222 | } |
228 | 223 | ||
229 | actual_length = data[length - 2] >> 2; | 224 | actual_length = data[length - 2] >> 2; |
230 | if (actual_length > (length - 2)) { | 225 | if (actual_length > (length - 2)) { |
231 | dev_err(&port->dev, "%s - inconsistent lengths %d:%d\n", | 226 | dev_err(&port->dev, "%s - inconsistent lengths %d:%d\n", |
232 | __func__, actual_length, length); | 227 | __func__, actual_length, length); |
233 | goto err; | 228 | return; |
234 | } | 229 | } |
235 | dev_info(&urb->dev->dev, "%s - actual: %d\n", __func__, actual_length); | 230 | dev_info(&urb->dev->dev, "%s - actual: %d\n", __func__, actual_length); |
236 | length = actual_length; | 231 | length = actual_length; |
237 | out: | 232 | out: |
238 | tty_insert_flip_string(tty, data, length); | 233 | tty_insert_flip_string(&port->port, data, length); |
239 | tty_flip_buffer_push(tty); | 234 | tty_flip_buffer_push(&port->port); |
240 | err: | ||
241 | tty_kref_put(tty); | ||
242 | } | 235 | } |
243 | 236 | ||
244 | static int safe_prepare_write_buffer(struct usb_serial_port *port, | 237 | static int safe_prepare_write_buffer(struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index d4426c038c32..c13f6e747748 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -569,7 +569,6 @@ static void sierra_indat_callback(struct urb *urb) | |||
569 | int err; | 569 | int err; |
570 | int endpoint; | 570 | int endpoint; |
571 | struct usb_serial_port *port; | 571 | struct usb_serial_port *port; |
572 | struct tty_struct *tty; | ||
573 | unsigned char *data = urb->transfer_buffer; | 572 | unsigned char *data = urb->transfer_buffer; |
574 | int status = urb->status; | 573 | int status = urb->status; |
575 | 574 | ||
@@ -581,16 +580,12 @@ static void sierra_indat_callback(struct urb *urb) | |||
581 | " endpoint %02x\n", __func__, status, endpoint); | 580 | " endpoint %02x\n", __func__, status, endpoint); |
582 | } else { | 581 | } else { |
583 | if (urb->actual_length) { | 582 | if (urb->actual_length) { |
584 | tty = tty_port_tty_get(&port->port); | 583 | tty_insert_flip_string(&port->port, data, |
585 | if (tty) { | 584 | urb->actual_length); |
586 | tty_insert_flip_string(tty, data, | 585 | tty_flip_buffer_push(&port->port); |
587 | urb->actual_length); | 586 | |
588 | tty_flip_buffer_push(tty); | 587 | usb_serial_debug_data(&port->dev, __func__, |
589 | 588 | urb->actual_length, data); | |
590 | tty_kref_put(tty); | ||
591 | usb_serial_debug_data(&port->dev, __func__, | ||
592 | urb->actual_length, data); | ||
593 | } | ||
594 | } else { | 589 | } else { |
595 | dev_dbg(&port->dev, "%s: empty read urb" | 590 | dev_dbg(&port->dev, "%s: empty read urb" |
596 | " received\n", __func__); | 591 | " received\n", __func__); |
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index a42536af1256..91ff8e3bddbd 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
@@ -462,7 +462,6 @@ static void spcp8x5_process_read_urb(struct urb *urb) | |||
462 | { | 462 | { |
463 | struct usb_serial_port *port = urb->context; | 463 | struct usb_serial_port *port = urb->context; |
464 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | 464 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
465 | struct tty_struct *tty; | ||
466 | unsigned char *data = urb->transfer_buffer; | 465 | unsigned char *data = urb->transfer_buffer; |
467 | unsigned long flags; | 466 | unsigned long flags; |
468 | u8 status; | 467 | u8 status; |
@@ -481,9 +480,6 @@ static void spcp8x5_process_read_urb(struct urb *urb) | |||
481 | if (!urb->actual_length) | 480 | if (!urb->actual_length) |
482 | return; | 481 | return; |
483 | 482 | ||
484 | tty = tty_port_tty_get(&port->port); | ||
485 | if (!tty) | ||
486 | return; | ||
487 | 483 | ||
488 | if (status & UART_STATE_TRANSIENT_MASK) { | 484 | if (status & UART_STATE_TRANSIENT_MASK) { |
489 | /* break takes precedence over parity, which takes precedence | 485 | /* break takes precedence over parity, which takes precedence |
@@ -498,17 +494,21 @@ static void spcp8x5_process_read_urb(struct urb *urb) | |||
498 | 494 | ||
499 | /* overrun is special, not associated with a char */ | 495 | /* overrun is special, not associated with a char */ |
500 | if (status & UART_OVERRUN_ERROR) | 496 | if (status & UART_OVERRUN_ERROR) |
501 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 497 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
502 | 498 | ||
503 | if (status & UART_DCD) | 499 | if (status & UART_DCD) { |
504 | usb_serial_handle_dcd_change(port, tty, | 500 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
505 | priv->line_status & MSR_STATUS_LINE_DCD); | 501 | if (tty) { |
502 | usb_serial_handle_dcd_change(port, tty, | ||
503 | priv->line_status & MSR_STATUS_LINE_DCD); | ||
504 | tty_kref_put(tty); | ||
505 | } | ||
506 | } | ||
506 | } | 507 | } |
507 | 508 | ||
508 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 509 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
509 | urb->actual_length); | 510 | urb->actual_length); |
510 | tty_flip_buffer_push(tty); | 511 | tty_flip_buffer_push(&port->port); |
511 | tty_kref_put(tty); | ||
512 | } | 512 | } |
513 | 513 | ||
514 | static int spcp8x5_wait_modem_info(struct usb_serial_port *port, | 514 | static int spcp8x5_wait_modem_info(struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index d938396171e8..b57cf841c5b6 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -579,8 +579,7 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, | |||
579 | 579 | ||
580 | } | 580 | } |
581 | 581 | ||
582 | static int ssu100_process_packet(struct urb *urb, | 582 | static void ssu100_process_read_urb(struct urb *urb) |
583 | struct tty_struct *tty) | ||
584 | { | 583 | { |
585 | struct usb_serial_port *port = urb->context; | 584 | struct usb_serial_port *port = urb->context; |
586 | char *packet = (char *)urb->transfer_buffer; | 585 | char *packet = (char *)urb->transfer_buffer; |
@@ -595,7 +594,8 @@ static int ssu100_process_packet(struct urb *urb, | |||
595 | if (packet[2] == 0x00) { | 594 | if (packet[2] == 0x00) { |
596 | ssu100_update_lsr(port, packet[3], &flag); | 595 | ssu100_update_lsr(port, packet[3], &flag); |
597 | if (flag == TTY_OVERRUN) | 596 | if (flag == TTY_OVERRUN) |
598 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 597 | tty_insert_flip_char(&port->port, 0, |
598 | TTY_OVERRUN); | ||
599 | } | 599 | } |
600 | if (packet[2] == 0x01) | 600 | if (packet[2] == 0x01) |
601 | ssu100_update_msr(port, packet[3]); | 601 | ssu100_update_msr(port, packet[3]); |
@@ -606,34 +606,17 @@ static int ssu100_process_packet(struct urb *urb, | |||
606 | ch = packet; | 606 | ch = packet; |
607 | 607 | ||
608 | if (!len) | 608 | if (!len) |
609 | return 0; /* status only */ | 609 | return; /* status only */ |
610 | 610 | ||
611 | if (port->port.console && port->sysrq) { | 611 | if (port->port.console && port->sysrq) { |
612 | for (i = 0; i < len; i++, ch++) { | 612 | for (i = 0; i < len; i++, ch++) { |
613 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 613 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
614 | tty_insert_flip_char(tty, *ch, flag); | 614 | tty_insert_flip_char(&port->port, *ch, flag); |
615 | } | 615 | } |
616 | } else | 616 | } else |
617 | tty_insert_flip_string_fixed_flag(tty, ch, flag, len); | 617 | tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len); |
618 | |||
619 | return len; | ||
620 | } | ||
621 | |||
622 | static void ssu100_process_read_urb(struct urb *urb) | ||
623 | { | ||
624 | struct usb_serial_port *port = urb->context; | ||
625 | struct tty_struct *tty; | ||
626 | int count; | ||
627 | |||
628 | tty = tty_port_tty_get(&port->port); | ||
629 | if (!tty) | ||
630 | return; | ||
631 | |||
632 | count = ssu100_process_packet(urb, tty); | ||
633 | 618 | ||
634 | if (count) | 619 | tty_flip_buffer_push(&port->port); |
635 | tty_flip_buffer_push(tty); | ||
636 | tty_kref_put(tty); | ||
637 | } | 620 | } |
638 | 621 | ||
639 | static struct usb_serial_driver ssu100_device = { | 622 | static struct usb_serial_driver ssu100_device = { |
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index 701fffa8431f..be05e6caf9a3 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -48,7 +48,6 @@ static void symbol_int_callback(struct urb *urb) | |||
48 | unsigned char *data = urb->transfer_buffer; | 48 | unsigned char *data = urb->transfer_buffer; |
49 | struct usb_serial_port *port = priv->port; | 49 | struct usb_serial_port *port = priv->port; |
50 | int status = urb->status; | 50 | int status = urb->status; |
51 | struct tty_struct *tty; | ||
52 | int result; | 51 | int result; |
53 | int data_length; | 52 | int data_length; |
54 | 53 | ||
@@ -82,12 +81,8 @@ static void symbol_int_callback(struct urb *urb) | |||
82 | * we pretty much just ignore the size and send everything | 81 | * we pretty much just ignore the size and send everything |
83 | * else to the tty layer. | 82 | * else to the tty layer. |
84 | */ | 83 | */ |
85 | tty = tty_port_tty_get(&port->port); | 84 | tty_insert_flip_string(&port->port, &data[1], data_length); |
86 | if (tty) { | 85 | tty_flip_buffer_push(&port->port); |
87 | tty_insert_flip_string(tty, &data[1], data_length); | ||
88 | tty_flip_buffer_push(tty); | ||
89 | tty_kref_put(tty); | ||
90 | } | ||
91 | } else { | 86 | } else { |
92 | dev_dbg(&priv->udev->dev, | 87 | dev_dbg(&priv->udev->dev, |
93 | "Improper amount of data received from the device, " | 88 | "Improper amount of data received from the device, " |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index f2530d2ef3c4..39cb9b807c3c 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -121,8 +121,8 @@ static void ti_interrupt_callback(struct urb *urb); | |||
121 | static void ti_bulk_in_callback(struct urb *urb); | 121 | static void ti_bulk_in_callback(struct urb *urb); |
122 | static void ti_bulk_out_callback(struct urb *urb); | 122 | static void ti_bulk_out_callback(struct urb *urb); |
123 | 123 | ||
124 | static void ti_recv(struct device *dev, struct tty_struct *tty, | 124 | static void ti_recv(struct usb_serial_port *port, unsigned char *data, |
125 | unsigned char *data, int length); | 125 | int length); |
126 | static void ti_send(struct ti_port *tport); | 126 | static void ti_send(struct ti_port *tport); |
127 | static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); | 127 | static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); |
128 | static int ti_get_lsr(struct ti_port *tport); | 128 | static int ti_get_lsr(struct ti_port *tport); |
@@ -1118,7 +1118,6 @@ static void ti_bulk_in_callback(struct urb *urb) | |||
1118 | struct device *dev = &urb->dev->dev; | 1118 | struct device *dev = &urb->dev->dev; |
1119 | int status = urb->status; | 1119 | int status = urb->status; |
1120 | int retval = 0; | 1120 | int retval = 0; |
1121 | struct tty_struct *tty; | ||
1122 | 1121 | ||
1123 | switch (status) { | 1122 | switch (status) { |
1124 | case 0: | 1123 | case 0: |
@@ -1145,24 +1144,18 @@ static void ti_bulk_in_callback(struct urb *urb) | |||
1145 | return; | 1144 | return; |
1146 | } | 1145 | } |
1147 | 1146 | ||
1148 | tty = tty_port_tty_get(&port->port); | 1147 | if (urb->actual_length) { |
1149 | if (tty) { | 1148 | usb_serial_debug_data(dev, __func__, urb->actual_length, |
1150 | if (urb->actual_length) { | 1149 | urb->transfer_buffer); |
1151 | usb_serial_debug_data(dev, __func__, urb->actual_length, | ||
1152 | urb->transfer_buffer); | ||
1153 | 1150 | ||
1154 | if (!tport->tp_is_open) | 1151 | if (!tport->tp_is_open) |
1155 | dev_dbg(dev, "%s - port closed, dropping data\n", | 1152 | dev_dbg(dev, "%s - port closed, dropping data\n", |
1156 | __func__); | 1153 | __func__); |
1157 | else | 1154 | else |
1158 | ti_recv(&urb->dev->dev, tty, | 1155 | ti_recv(port, urb->transfer_buffer, urb->actual_length); |
1159 | urb->transfer_buffer, | 1156 | spin_lock(&tport->tp_lock); |
1160 | urb->actual_length); | 1157 | tport->tp_icount.rx += urb->actual_length; |
1161 | spin_lock(&tport->tp_lock); | 1158 | spin_unlock(&tport->tp_lock); |
1162 | tport->tp_icount.rx += urb->actual_length; | ||
1163 | spin_unlock(&tport->tp_lock); | ||
1164 | } | ||
1165 | tty_kref_put(tty); | ||
1166 | } | 1159 | } |
1167 | 1160 | ||
1168 | exit: | 1161 | exit: |
@@ -1210,24 +1203,23 @@ static void ti_bulk_out_callback(struct urb *urb) | |||
1210 | } | 1203 | } |
1211 | 1204 | ||
1212 | 1205 | ||
1213 | static void ti_recv(struct device *dev, struct tty_struct *tty, | 1206 | static void ti_recv(struct usb_serial_port *port, unsigned char *data, |
1214 | unsigned char *data, int length) | 1207 | int length) |
1215 | { | 1208 | { |
1216 | int cnt; | 1209 | int cnt; |
1217 | 1210 | ||
1218 | do { | 1211 | do { |
1219 | cnt = tty_insert_flip_string(tty, data, length); | 1212 | cnt = tty_insert_flip_string(&port->port, data, length); |
1220 | if (cnt < length) { | 1213 | if (cnt < length) { |
1221 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1214 | dev_err(&port->dev, "%s - dropping data, %d bytes lost\n", |
1222 | __func__, length - cnt); | 1215 | __func__, length - cnt); |
1223 | if (cnt == 0) | 1216 | if (cnt == 0) |
1224 | break; | 1217 | break; |
1225 | } | 1218 | } |
1226 | tty_flip_buffer_push(tty); | 1219 | tty_flip_buffer_push(&port->port); |
1227 | data += cnt; | 1220 | data += cnt; |
1228 | length -= cnt; | 1221 | length -= cnt; |
1229 | } while (length > 0); | 1222 | } while (length > 0); |
1230 | |||
1231 | } | 1223 | } |
1232 | 1224 | ||
1233 | 1225 | ||
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 1355a6cd4508..571965aa1cc0 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -273,7 +273,6 @@ static void usb_wwan_indat_callback(struct urb *urb) | |||
273 | int err; | 273 | int err; |
274 | int endpoint; | 274 | int endpoint; |
275 | struct usb_serial_port *port; | 275 | struct usb_serial_port *port; |
276 | struct tty_struct *tty; | ||
277 | struct device *dev; | 276 | struct device *dev; |
278 | unsigned char *data = urb->transfer_buffer; | 277 | unsigned char *data = urb->transfer_buffer; |
279 | int status = urb->status; | 278 | int status = urb->status; |
@@ -286,16 +285,12 @@ static void usb_wwan_indat_callback(struct urb *urb) | |||
286 | dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n", | 285 | dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n", |
287 | __func__, status, endpoint); | 286 | __func__, status, endpoint); |
288 | } else { | 287 | } else { |
289 | tty = tty_port_tty_get(&port->port); | 288 | if (urb->actual_length) { |
290 | if (tty) { | 289 | tty_insert_flip_string(&port->port, data, |
291 | if (urb->actual_length) { | 290 | urb->actual_length); |
292 | tty_insert_flip_string(tty, data, | 291 | tty_flip_buffer_push(&port->port); |
293 | urb->actual_length); | 292 | } else |
294 | tty_flip_buffer_push(tty); | 293 | dev_dbg(dev, "%s: empty read urb received\n", __func__); |
295 | } else | ||
296 | dev_dbg(dev, "%s: empty read urb received\n", __func__); | ||
297 | tty_kref_put(tty); | ||
298 | } | ||
299 | 294 | ||
300 | /* Resubmit urb so we continue receiving */ | 295 | /* Resubmit urb so we continue receiving */ |
301 | err = usb_submit_urb(urb, GFP_ATOMIC); | 296 | err = usb_submit_urb(urb, GFP_ATOMIC); |
diff --git a/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c index 97f79356141e..53846cb534d4 100644 --- a/drivers/video/auo_k190x.c +++ b/drivers/video/auo_k190x.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/gpio.h> | 13 | #include <linux/gpio.h> |
14 | #include <linux/platform_device.h> | ||
14 | #include <linux/pm_runtime.h> | 15 | #include <linux/pm_runtime.h> |
15 | #include <linux/fb.h> | 16 | #include <linux/fb.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c index 469cf0f109d2..fdbb6ee5027c 100644 --- a/drivers/video/backlight/ot200_bl.c +++ b/drivers/video/backlight/ot200_bl.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/fb.h> | 14 | #include <linux/fb.h> |
15 | #include <linux/backlight.h> | 15 | #include <linux/backlight.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/platform_device.h> | ||
17 | #include <linux/cs5535.h> | 18 | #include <linux/cs5535.h> |
18 | 19 | ||
19 | static struct cs5535_mfgpt_timer *pwm_timer; | 20 | static struct cs5535_mfgpt_timer *pwm_timer; |
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c index 5a7af0deced2..f00980607b8f 100644 --- a/drivers/video/clps711xfb.c +++ b/drivers/video/clps711xfb.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/fb.h> | 26 | #include <linux/fb.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/platform_device.h> | ||
29 | 30 | ||
30 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
31 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c index 3cd29a4fc10a..c70cb8926df6 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_common.c +++ b/drivers/video/exynos/exynos_mipi_dsi_common.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/memory.h> | 26 | #include <linux/memory.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/irqreturn.h> | ||
28 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
29 | 30 | ||
30 | #include <video/mipi_display.h> | 31 | #include <video/mipi_display.h> |
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c index 0ef38ce72af6..95cb99a1fe2d 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c +++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/ctype.h> | 23 | #include <linux/ctype.h> |
24 | #include <linux/platform_device.h> | ||
24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
25 | 26 | ||
26 | #include <video/exynos_mipi_dsim.h> | 27 | #include <video/exynos_mipi_dsim.h> |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 981b05601931..712f24db9600 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -8,7 +8,8 @@ proc-y := nommu.o task_nommu.o | |||
8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o | 8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o |
9 | 9 | ||
10 | proc-y += inode.o root.o base.o generic.o array.o \ | 10 | proc-y += inode.o root.o base.o generic.o array.o \ |
11 | proc_tty.o fd.o | 11 | fd.o |
12 | proc-$(CONFIG_TTY) += proc_tty.o | ||
12 | proc-y += cmdline.o | 13 | proc-y += cmdline.o |
13 | proc-y += consoles.o | 14 | proc-y += consoles.o |
14 | proc-y += cpuinfo.o | 15 | proc-y += cpuinfo.o |
diff --git a/include/linux/console.h b/include/linux/console.h index dedb082fe50f..3b709da1786e 100644 --- a/include/linux/console.h +++ b/include/linux/console.h | |||
@@ -157,7 +157,12 @@ extern int is_console_locked(void); | |||
157 | extern int braille_register_console(struct console *, int index, | 157 | extern int braille_register_console(struct console *, int index, |
158 | char *console_options, char *braille_options); | 158 | char *console_options, char *braille_options); |
159 | extern int braille_unregister_console(struct console *); | 159 | extern int braille_unregister_console(struct console *); |
160 | #ifdef CONFIG_TTY | ||
160 | extern void console_sysfs_notify(void); | 161 | extern void console_sysfs_notify(void); |
162 | #else | ||
163 | static inline void console_sysfs_notify(void) | ||
164 | { } | ||
165 | #endif | ||
161 | extern bool console_suspend_enabled; | 166 | extern bool console_suspend_enabled; |
162 | 167 | ||
163 | /* Suspend and resume console messages over PM events */ | 168 | /* Suspend and resume console messages over PM events */ |
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 4dff0c6ed58f..c6e091bf39a5 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h | |||
@@ -13,7 +13,6 @@ | |||
13 | #ifndef _KGDB_H_ | 13 | #ifndef _KGDB_H_ |
14 | #define _KGDB_H_ | 14 | #define _KGDB_H_ |
15 | 15 | ||
16 | #include <linux/serial_8250.h> | ||
17 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/atomic.h> | 18 | #include <linux/atomic.h> |
diff --git a/include/linux/of_serial.h b/include/linux/of_serial.h deleted file mode 100644 index 4a73ed80b4c0..000000000000 --- a/include/linux/of_serial.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | #ifndef __LINUX_OF_SERIAL_H | ||
2 | #define __LINUX_OF_SERIAL_H | ||
3 | |||
4 | /* | ||
5 | * FIXME remove this file when tegra finishes conversion to open firmware, | ||
6 | * expectation is that all quirks will then be self-contained in | ||
7 | * drivers/tty/serial/of_serial.c. | ||
8 | */ | ||
9 | #ifdef CONFIG_ARCH_TEGRA | ||
10 | extern void tegra_serial_handle_break(struct uart_port *port); | ||
11 | #else | ||
12 | static inline void tegra_serial_handle_break(struct uart_port *port) | ||
13 | { | ||
14 | } | ||
15 | #endif | ||
16 | |||
17 | #endif /* __LINUX_OF_SERIAL */ | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 6938ccfa42d5..31717bd287fd 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -1870,8 +1870,23 @@ | |||
1870 | #define PCI_VENDOR_ID_QUATECH 0x135C | 1870 | #define PCI_VENDOR_ID_QUATECH 0x135C |
1871 | #define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 | 1871 | #define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 |
1872 | #define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 | 1872 | #define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 |
1873 | #define PCI_DEVICE_ID_QUATECH_DSC200 0x0030 | ||
1874 | #define PCI_DEVICE_ID_QUATECH_QSC200 0x0040 | ||
1873 | #define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 | 1875 | #define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 |
1874 | #define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 | 1876 | #define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 |
1877 | #define PCI_DEVICE_ID_QUATECH_QSCP100 0x0120 | ||
1878 | #define PCI_DEVICE_ID_QUATECH_DSCP100 0x0130 | ||
1879 | #define PCI_DEVICE_ID_QUATECH_QSCP200 0x0140 | ||
1880 | #define PCI_DEVICE_ID_QUATECH_DSCP200 0x0150 | ||
1881 | #define PCI_DEVICE_ID_QUATECH_QSCLP100 0x0170 | ||
1882 | #define PCI_DEVICE_ID_QUATECH_DSCLP100 0x0180 | ||
1883 | #define PCI_DEVICE_ID_QUATECH_DSC100E 0x0181 | ||
1884 | #define PCI_DEVICE_ID_QUATECH_SSCLP100 0x0190 | ||
1885 | #define PCI_DEVICE_ID_QUATECH_QSCLP200 0x01A0 | ||
1886 | #define PCI_DEVICE_ID_QUATECH_DSCLP200 0x01B0 | ||
1887 | #define PCI_DEVICE_ID_QUATECH_DSC200E 0x01B1 | ||
1888 | #define PCI_DEVICE_ID_QUATECH_SSCLP200 0x01C0 | ||
1889 | #define PCI_DEVICE_ID_QUATECH_ESCLP100 0x01E0 | ||
1875 | #define PCI_DEVICE_ID_QUATECH_SPPXP_100 0x0278 | 1890 | #define PCI_DEVICE_ID_QUATECH_SPPXP_100 0x0278 |
1876 | 1891 | ||
1877 | #define PCI_VENDOR_ID_SEALEVEL 0x135e | 1892 | #define PCI_VENDOR_ID_SEALEVEL 0x135e |
diff --git a/include/linux/platform_data/s3c-hsotg.h b/include/linux/platform_data/s3c-hsotg.h index 8b79e0967f9c..3f1cbf95ec3b 100644 --- a/include/linux/platform_data/s3c-hsotg.h +++ b/include/linux/platform_data/s3c-hsotg.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #ifndef __LINUX_USB_S3C_HSOTG_H | 15 | #ifndef __LINUX_USB_S3C_HSOTG_H |
16 | #define __LINUX_USB_S3C_HSOTG_H | 16 | #define __LINUX_USB_S3C_HSOTG_H |
17 | 17 | ||
18 | struct platform_device; | ||
19 | |||
18 | enum s3c_hsotg_dmamode { | 20 | enum s3c_hsotg_dmamode { |
19 | S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */ | 21 | S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */ |
20 | S3C_HSOTG_DMA_ONLY, /* always use DMA */ | 22 | S3C_HSOTG_DMA_ONLY, /* always use DMA */ |
diff --git a/include/linux/platform_data/sccnxp.h b/include/linux/platform_data/serial-sccnxp.h index 7311ccd3217f..215574d1e81d 100644 --- a/include/linux/platform_data/sccnxp.h +++ b/include/linux/platform_data/serial-sccnxp.h | |||
@@ -11,8 +11,8 @@ | |||
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #ifndef __SCCNXP_H | 14 | #ifndef _PLATFORM_DATA_SERIAL_SCCNXP_H_ |
15 | #define __SCCNXP_H | 15 | #define _PLATFORM_DATA_SERIAL_SCCNXP_H_ |
16 | 16 | ||
17 | #define SCCNXP_MAX_UARTS 2 | 17 | #define SCCNXP_MAX_UARTS 2 |
18 | 18 | ||
@@ -84,6 +84,8 @@ struct sccnxp_pdata { | |||
84 | const u8 reg_shift; | 84 | const u8 reg_shift; |
85 | /* Modem control lines configuration */ | 85 | /* Modem control lines configuration */ |
86 | const u32 mctrl_cfg[SCCNXP_MAX_UARTS]; | 86 | const u32 mctrl_cfg[SCCNXP_MAX_UARTS]; |
87 | /* Timer value for polling mode (usecs) */ | ||
88 | const unsigned int poll_time_us; | ||
87 | /* Called during startup */ | 89 | /* Called during startup */ |
88 | void (*init)(void); | 90 | void (*init)(void); |
89 | /* Called before finish */ | 91 | /* Called before finish */ |
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h index 0cc45ae1afd5..7db3eb93a079 100644 --- a/include/linux/pps_kernel.h +++ b/include/linux/pps_kernel.h | |||
@@ -43,7 +43,7 @@ struct pps_source_info { | |||
43 | int event, void *data); /* PPS echo function */ | 43 | int event, void *data); /* PPS echo function */ |
44 | 44 | ||
45 | struct module *owner; | 45 | struct module *owner; |
46 | struct device *dev; | 46 | struct device *dev; /* Parent device for device_create */ |
47 | }; | 47 | }; |
48 | 48 | ||
49 | struct pps_event_time { | 49 | struct pps_event_time { |
@@ -69,6 +69,7 @@ struct pps_device { | |||
69 | wait_queue_head_t queue; /* PPS event queue */ | 69 | wait_queue_head_t queue; /* PPS event queue */ |
70 | 70 | ||
71 | unsigned int id; /* PPS source unique ID */ | 71 | unsigned int id; /* PPS source unique ID */ |
72 | void const *lookup_cookie; /* pps_lookup_dev only */ | ||
72 | struct cdev cdev; | 73 | struct cdev cdev; |
73 | struct device *dev; | 74 | struct device *dev; |
74 | struct fasync_struct *async_queue; /* fasync method */ | 75 | struct fasync_struct *async_queue; /* fasync method */ |
@@ -82,16 +83,26 @@ struct pps_device { | |||
82 | extern struct device_attribute pps_attrs[]; | 83 | extern struct device_attribute pps_attrs[]; |
83 | 84 | ||
84 | /* | 85 | /* |
86 | * Internal functions. | ||
87 | * | ||
88 | * These are not actually part of the exported API, but this is a | ||
89 | * convenient header file to put them in. | ||
90 | */ | ||
91 | |||
92 | extern int pps_register_cdev(struct pps_device *pps); | ||
93 | extern void pps_unregister_cdev(struct pps_device *pps); | ||
94 | |||
95 | /* | ||
85 | * Exported functions | 96 | * Exported functions |
86 | */ | 97 | */ |
87 | 98 | ||
88 | extern struct pps_device *pps_register_source( | 99 | extern struct pps_device *pps_register_source( |
89 | struct pps_source_info *info, int default_params); | 100 | struct pps_source_info *info, int default_params); |
90 | extern void pps_unregister_source(struct pps_device *pps); | 101 | extern void pps_unregister_source(struct pps_device *pps); |
91 | extern int pps_register_cdev(struct pps_device *pps); | ||
92 | extern void pps_unregister_cdev(struct pps_device *pps); | ||
93 | extern void pps_event(struct pps_device *pps, | 102 | extern void pps_event(struct pps_device *pps, |
94 | struct pps_event_time *ts, int event, void *data); | 103 | struct pps_event_time *ts, int event, void *data); |
104 | /* Look up a pps device by magic cookie */ | ||
105 | struct pps_device *pps_lookup_dev(void const *cookie); | ||
95 | 106 | ||
96 | static inline void timespec_to_pps_ktime(struct pps_ktime *kt, | 107 | static inline void timespec_to_pps_ktime(struct pps_ktime *kt, |
97 | struct timespec ts) | 108 | struct timespec ts) |
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index d0a1f2ca1c3f..8307f2f94d86 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h | |||
@@ -127,7 +127,12 @@ extern void pid_ns_release_proc(struct pid_namespace *ns); | |||
127 | * proc_tty.c | 127 | * proc_tty.c |
128 | */ | 128 | */ |
129 | struct tty_driver; | 129 | struct tty_driver; |
130 | #ifdef CONFIG_TTY | ||
130 | extern void proc_tty_init(void); | 131 | extern void proc_tty_init(void); |
132 | #else | ||
133 | static inline void proc_tty_init(void) | ||
134 | { } | ||
135 | #endif | ||
131 | extern void proc_tty_register_driver(struct tty_driver *driver); | 136 | extern void proc_tty_register_driver(struct tty_driver *driver); |
132 | extern void proc_tty_unregister_driver(struct tty_driver *driver); | 137 | extern void proc_tty_unregister_driver(struct tty_driver *driver); |
133 | 138 | ||
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index c490d20b3fb8..af47a8af6024 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h | |||
@@ -59,6 +59,8 @@ enum { | |||
59 | PLAT8250_DEV_SM501, | 59 | PLAT8250_DEV_SM501, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | struct uart_8250_dma; | ||
63 | |||
62 | /* | 64 | /* |
63 | * This should be used by drivers which want to register | 65 | * This should be used by drivers which want to register |
64 | * their own 8250 ports without registering their own | 66 | * their own 8250 ports without registering their own |
@@ -91,6 +93,8 @@ struct uart_8250_port { | |||
91 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | 93 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA |
92 | unsigned char msr_saved_flags; | 94 | unsigned char msr_saved_flags; |
93 | 95 | ||
96 | struct uart_8250_dma *dma; | ||
97 | |||
94 | /* 8250 specific callbacks */ | 98 | /* 8250 specific callbacks */ |
95 | int (*dl_read)(struct uart_8250_port *); | 99 | int (*dl_read)(struct uart_8250_port *); |
96 | void (*dl_write)(struct uart_8250_port *, int); | 100 | void (*dl_write)(struct uart_8250_port *, int); |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index c6690a2a27fb..87d4bbc773fc 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/tty.h> | 29 | #include <linux/tty.h> |
30 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
31 | #include <linux/sysrq.h> | 31 | #include <linux/sysrq.h> |
32 | #include <linux/pps_kernel.h> | ||
33 | #include <uapi/linux/serial_core.h> | 32 | #include <uapi/linux/serial_core.h> |
34 | 33 | ||
35 | struct uart_port; | 34 | struct uart_port; |
@@ -37,8 +36,8 @@ struct serial_struct; | |||
37 | struct device; | 36 | struct device; |
38 | 37 | ||
39 | /* | 38 | /* |
40 | * This structure describes all the operations that can be | 39 | * This structure describes all the operations that can be done on the |
41 | * done on the physical hardware. | 40 | * physical hardware. See Documentation/serial/driver for details. |
42 | */ | 41 | */ |
43 | struct uart_ops { | 42 | struct uart_ops { |
44 | unsigned int (*tx_empty)(struct uart_port *); | 43 | unsigned int (*tx_empty)(struct uart_port *); |
@@ -65,7 +64,7 @@ struct uart_ops { | |||
65 | /* | 64 | /* |
66 | * Return a string describing the type of the port | 65 | * Return a string describing the type of the port |
67 | */ | 66 | */ |
68 | const char *(*type)(struct uart_port *); | 67 | const char *(*type)(struct uart_port *); |
69 | 68 | ||
70 | /* | 69 | /* |
71 | * Release IO and memory resources used by the port. | 70 | * Release IO and memory resources used by the port. |
@@ -83,7 +82,7 @@ struct uart_ops { | |||
83 | int (*ioctl)(struct uart_port *, unsigned int, unsigned long); | 82 | int (*ioctl)(struct uart_port *, unsigned int, unsigned long); |
84 | #ifdef CONFIG_CONSOLE_POLL | 83 | #ifdef CONFIG_CONSOLE_POLL |
85 | int (*poll_init)(struct uart_port *); | 84 | int (*poll_init)(struct uart_port *); |
86 | void (*poll_put_char)(struct uart_port *, unsigned char); | 85 | void (*poll_put_char)(struct uart_port *, unsigned char); |
87 | int (*poll_get_char)(struct uart_port *); | 86 | int (*poll_get_char)(struct uart_port *); |
88 | #endif | 87 | #endif |
89 | }; | 88 | }; |
@@ -134,9 +133,8 @@ struct uart_port { | |||
134 | #define UPIO_HUB6 (1) | 133 | #define UPIO_HUB6 (1) |
135 | #define UPIO_MEM (2) | 134 | #define UPIO_MEM (2) |
136 | #define UPIO_MEM32 (3) | 135 | #define UPIO_MEM32 (3) |
137 | #define UPIO_AU (4) /* Au1x00 type IO */ | 136 | #define UPIO_AU (4) /* Au1x00 and RT288x type IO */ |
138 | #define UPIO_TSI (5) /* Tsi108/109 type IO */ | 137 | #define UPIO_TSI (5) /* Tsi108/109 type IO */ |
139 | #define UPIO_RM9000 (6) /* RM9000 type IO */ | ||
140 | 138 | ||
141 | unsigned int read_status_mask; /* driver specific */ | 139 | unsigned int read_status_mask; /* driver specific */ |
142 | unsigned int ignore_status_mask; /* driver specific */ | 140 | unsigned int ignore_status_mask; /* driver specific */ |
@@ -208,13 +206,25 @@ static inline void serial_port_out(struct uart_port *up, int offset, int value) | |||
208 | up->serial_out(up, offset, value); | 206 | up->serial_out(up, offset, value); |
209 | } | 207 | } |
210 | 208 | ||
209 | /** | ||
210 | * enum uart_pm_state - power states for UARTs | ||
211 | * @UART_PM_STATE_ON: UART is powered, up and operational | ||
212 | * @UART_PM_STATE_OFF: UART is powered off | ||
213 | * @UART_PM_STATE_UNDEFINED: sentinel | ||
214 | */ | ||
215 | enum uart_pm_state { | ||
216 | UART_PM_STATE_ON = 0, | ||
217 | UART_PM_STATE_OFF = 3, /* number taken from ACPI */ | ||
218 | UART_PM_STATE_UNDEFINED, | ||
219 | }; | ||
220 | |||
211 | /* | 221 | /* |
212 | * This is the state information which is persistent across opens. | 222 | * This is the state information which is persistent across opens. |
213 | */ | 223 | */ |
214 | struct uart_state { | 224 | struct uart_state { |
215 | struct tty_port port; | 225 | struct tty_port port; |
216 | 226 | ||
217 | int pm_state; | 227 | enum uart_pm_state pm_state; |
218 | struct circ_buf xmit; | 228 | struct circ_buf xmit; |
219 | 229 | ||
220 | struct uart_port *uart_port; | 230 | struct uart_port *uart_port; |
diff --git a/include/linux/sunserialcore.h b/include/linux/sunserialcore.h index 68e7430bb0fe..dbe4d7fca1b8 100644 --- a/include/linux/sunserialcore.h +++ b/include/linux/sunserialcore.h | |||
@@ -13,6 +13,10 @@ | |||
13 | #ifndef _SERIAL_SUN_H | 13 | #ifndef _SERIAL_SUN_H |
14 | #define _SERIAL_SUN_H | 14 | #define _SERIAL_SUN_H |
15 | 15 | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/serial_core.h> | ||
18 | #include <linux/console.h> | ||
19 | |||
16 | /* Serial keyboard defines for L1-A processing... */ | 20 | /* Serial keyboard defines for L1-A processing... */ |
17 | #define SUNKBD_RESET 0xff | 21 | #define SUNKBD_RESET 0xff |
18 | #define SUNKBD_L1 0x01 | 22 | #define SUNKBD_L1 0x01 |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 8db1b569c37a..c75d886b0307 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -202,7 +202,8 @@ struct tty_port { | |||
202 | unsigned long iflags; /* TTYP_ internal flags */ | 202 | unsigned long iflags; /* TTYP_ internal flags */ |
203 | #define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */ | 203 | #define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */ |
204 | #define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */ | 204 | #define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */ |
205 | unsigned char console:1; /* port is a console */ | 205 | unsigned char console:1, /* port is a console */ |
206 | low_latency:1; /* direct buffer flush */ | ||
206 | struct mutex mutex; /* Locking */ | 207 | struct mutex mutex; /* Locking */ |
207 | struct mutex buf_mutex; /* Buffer alloc lock */ | 208 | struct mutex buf_mutex; /* Buffer alloc lock */ |
208 | unsigned char *xmit_buf; /* Optional buffer */ | 209 | unsigned char *xmit_buf; /* Optional buffer */ |
@@ -254,7 +255,7 @@ struct tty_struct { | |||
254 | int count; | 255 | int count; |
255 | struct winsize winsize; /* termios mutex */ | 256 | struct winsize winsize; /* termios mutex */ |
256 | 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; |
257 | unsigned char low_latency:1, warned:1; | 258 | unsigned char warned:1; |
258 | unsigned char ctrl_status; /* ctrl_lock */ | 259 | unsigned char ctrl_status; /* ctrl_lock */ |
259 | unsigned int receive_room; /* Bytes free for queue */ | 260 | unsigned int receive_room; /* Bytes free for queue */ |
260 | 261 | ||
@@ -317,11 +318,43 @@ struct tty_file_private { | |||
317 | 318 | ||
318 | #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) | 319 | #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) |
319 | 320 | ||
321 | #ifdef CONFIG_TTY | ||
322 | extern void console_init(void); | ||
323 | extern void tty_kref_put(struct tty_struct *tty); | ||
324 | extern struct pid *tty_get_pgrp(struct tty_struct *tty); | ||
325 | extern void tty_vhangup_self(void); | ||
326 | extern void disassociate_ctty(int priv); | ||
327 | extern dev_t tty_devnum(struct tty_struct *tty); | ||
328 | extern void proc_clear_tty(struct task_struct *p); | ||
329 | extern struct tty_struct *get_current_tty(void); | ||
330 | /* tty_io.c */ | ||
331 | extern int __init tty_init(void); | ||
332 | #else | ||
333 | static inline void console_init(void) | ||
334 | { } | ||
335 | static inline void tty_kref_put(struct tty_struct *tty) | ||
336 | { } | ||
337 | static inline struct pid *tty_get_pgrp(struct tty_struct *tty) | ||
338 | { return NULL; } | ||
339 | static inline void tty_vhangup_self(void) | ||
340 | { } | ||
341 | static inline void disassociate_ctty(int priv) | ||
342 | { } | ||
343 | static inline dev_t tty_devnum(struct tty_struct *tty) | ||
344 | { return 0; } | ||
345 | static inline void proc_clear_tty(struct task_struct *p) | ||
346 | { } | ||
347 | static inline struct tty_struct *get_current_tty(void) | ||
348 | { return NULL; } | ||
349 | /* tty_io.c */ | ||
350 | static inline int __init tty_init(void) | ||
351 | { return 0; } | ||
352 | #endif | ||
353 | |||
320 | extern void tty_write_flush(struct tty_struct *); | 354 | extern void tty_write_flush(struct tty_struct *); |
321 | 355 | ||
322 | extern struct ktermios tty_std_termios; | 356 | extern struct ktermios tty_std_termios; |
323 | 357 | ||
324 | extern void console_init(void); | ||
325 | extern int vcs_init(void); | 358 | extern int vcs_init(void); |
326 | 359 | ||
327 | extern struct class *tty_class; | 360 | extern struct class *tty_class; |
@@ -341,7 +374,6 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) | |||
341 | kref_get(&tty->kref); | 374 | kref_get(&tty->kref); |
342 | return tty; | 375 | return tty; |
343 | } | 376 | } |
344 | extern void tty_kref_put(struct tty_struct *tty); | ||
345 | 377 | ||
346 | extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, | 378 | extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, |
347 | const char *routine); | 379 | const char *routine); |
@@ -373,20 +405,16 @@ extern void tty_driver_remove_tty(struct tty_driver *driver, | |||
373 | struct tty_struct *tty); | 405 | struct tty_struct *tty); |
374 | extern void tty_free_termios(struct tty_struct *tty); | 406 | extern void tty_free_termios(struct tty_struct *tty); |
375 | extern int is_current_pgrp_orphaned(void); | 407 | extern int is_current_pgrp_orphaned(void); |
376 | extern struct pid *tty_get_pgrp(struct tty_struct *tty); | ||
377 | extern int is_ignored(int sig); | 408 | extern int is_ignored(int sig); |
378 | extern int tty_signal(int sig, struct tty_struct *tty); | 409 | extern int tty_signal(int sig, struct tty_struct *tty); |
379 | extern void tty_hangup(struct tty_struct *tty); | 410 | extern void tty_hangup(struct tty_struct *tty); |
380 | extern void tty_vhangup(struct tty_struct *tty); | 411 | extern void tty_vhangup(struct tty_struct *tty); |
381 | extern void tty_vhangup_locked(struct tty_struct *tty); | 412 | extern void tty_vhangup_locked(struct tty_struct *tty); |
382 | extern void tty_vhangup_self(void); | ||
383 | extern void tty_unhangup(struct file *filp); | 413 | extern void tty_unhangup(struct file *filp); |
384 | extern int tty_hung_up_p(struct file *filp); | 414 | extern int tty_hung_up_p(struct file *filp); |
385 | extern void do_SAK(struct tty_struct *tty); | 415 | extern void do_SAK(struct tty_struct *tty); |
386 | extern void __do_SAK(struct tty_struct *tty); | 416 | extern void __do_SAK(struct tty_struct *tty); |
387 | extern void disassociate_ctty(int priv); | ||
388 | extern void no_tty(void); | 417 | extern void no_tty(void); |
389 | extern void tty_flip_buffer_push(struct tty_struct *tty); | ||
390 | extern void tty_flush_to_ldisc(struct tty_struct *tty); | 418 | extern void tty_flush_to_ldisc(struct tty_struct *tty); |
391 | extern void tty_buffer_free_all(struct tty_port *port); | 419 | extern void tty_buffer_free_all(struct tty_port *port); |
392 | extern void tty_buffer_flush(struct tty_struct *tty); | 420 | extern void tty_buffer_flush(struct tty_struct *tty); |
@@ -415,9 +443,6 @@ extern long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | |||
415 | extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | 443 | extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file, |
416 | unsigned int cmd, unsigned long arg); | 444 | unsigned int cmd, unsigned long arg); |
417 | extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg); | 445 | extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg); |
418 | extern dev_t tty_devnum(struct tty_struct *tty); | ||
419 | extern void proc_clear_tty(struct task_struct *p); | ||
420 | extern struct tty_struct *get_current_tty(void); | ||
421 | extern void tty_default_fops(struct file_operations *fops); | 446 | extern void tty_default_fops(struct file_operations *fops); |
422 | extern struct tty_struct *alloc_tty_struct(void); | 447 | extern struct tty_struct *alloc_tty_struct(void); |
423 | extern int tty_alloc_file(struct file *file); | 448 | extern int tty_alloc_file(struct file *file); |
@@ -543,9 +568,6 @@ static inline int tty_audit_push_task(struct task_struct *tsk, | |||
543 | } | 568 | } |
544 | #endif | 569 | #endif |
545 | 570 | ||
546 | /* tty_io.c */ | ||
547 | extern int __init tty_init(void); | ||
548 | |||
549 | /* tty_ioctl.c */ | 571 | /* tty_ioctl.c */ |
550 | extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | 572 | extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
551 | unsigned int cmd, unsigned long arg); | 573 | unsigned int cmd, unsigned long arg); |
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index dd976cfb6131..756a60989294 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h | |||
@@ -40,6 +40,7 @@ | |||
40 | * void (*close)(struct tty_struct * tty, struct file * filp); | 40 | * void (*close)(struct tty_struct * tty, struct file * filp); |
41 | * | 41 | * |
42 | * This routine is called when a particular tty device is closed. | 42 | * This routine is called when a particular tty device is closed. |
43 | * Note: called even if the corresponding open() failed. | ||
43 | * | 44 | * |
44 | * Required method. | 45 | * Required method. |
45 | * | 46 | * |
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index 2002344ed36a..e0f252633b47 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h | |||
@@ -1,28 +1,34 @@ | |||
1 | #ifndef _LINUX_TTY_FLIP_H | 1 | #ifndef _LINUX_TTY_FLIP_H |
2 | #define _LINUX_TTY_FLIP_H | 2 | #define _LINUX_TTY_FLIP_H |
3 | 3 | ||
4 | extern int tty_buffer_request_room(struct tty_struct *tty, size_t size); | 4 | extern int tty_buffer_request_room(struct tty_port *port, size_t size); |
5 | extern int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size); | 5 | extern int tty_insert_flip_string_flags(struct tty_port *port, |
6 | extern int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, const unsigned char *chars, char flag, size_t size); | 6 | const unsigned char *chars, const char *flags, size_t size); |
7 | extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size); | 7 | extern int tty_insert_flip_string_fixed_flag(struct tty_port *port, |
8 | extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size); | 8 | const unsigned char *chars, char flag, size_t size); |
9 | void tty_schedule_flip(struct tty_struct *tty); | 9 | extern int tty_prepare_flip_string(struct tty_port *port, |
10 | unsigned char **chars, size_t size); | ||
11 | extern int tty_prepare_flip_string_flags(struct tty_port *port, | ||
12 | unsigned char **chars, char **flags, size_t size); | ||
13 | extern void tty_flip_buffer_push(struct tty_port *port); | ||
14 | void tty_schedule_flip(struct tty_port *port); | ||
10 | 15 | ||
11 | static inline int tty_insert_flip_char(struct tty_struct *tty, | 16 | static inline int tty_insert_flip_char(struct tty_port *port, |
12 | unsigned char ch, char flag) | 17 | unsigned char ch, char flag) |
13 | { | 18 | { |
14 | struct tty_buffer *tb = tty->port->buf.tail; | 19 | struct tty_buffer *tb = port->buf.tail; |
15 | if (tb && tb->used < tb->size) { | 20 | if (tb && tb->used < tb->size) { |
16 | tb->flag_buf_ptr[tb->used] = flag; | 21 | tb->flag_buf_ptr[tb->used] = flag; |
17 | tb->char_buf_ptr[tb->used++] = ch; | 22 | tb->char_buf_ptr[tb->used++] = ch; |
18 | return 1; | 23 | return 1; |
19 | } | 24 | } |
20 | return tty_insert_flip_string_flags(tty, &ch, &flag, 1); | 25 | return tty_insert_flip_string_flags(port, &ch, &flag, 1); |
21 | } | 26 | } |
22 | 27 | ||
23 | static inline int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size) | 28 | static inline int tty_insert_flip_string(struct tty_port *port, |
29 | const unsigned char *chars, size_t size) | ||
24 | { | 30 | { |
25 | return tty_insert_flip_string_fixed_flag(tty, chars, TTY_NORMAL, size); | 31 | return tty_insert_flip_string_fixed_flag(port, chars, TTY_NORMAL, size); |
26 | } | 32 | } |
27 | 33 | ||
28 | #endif /* _LINUX_TTY_FLIP_H */ | 34 | #endif /* _LINUX_TTY_FLIP_H */ |
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index fb79dd8d1537..455a0d7bf220 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h | |||
@@ -100,16 +100,14 @@ | |||
100 | * seek to perform this action quickly but should wait until | 100 | * seek to perform this action quickly but should wait until |
101 | * any pending driver I/O is completed. | 101 | * any pending driver I/O is completed. |
102 | * | 102 | * |
103 | * void (*dcd_change)(struct tty_struct *tty, unsigned int status, | 103 | * void (*dcd_change)(struct tty_struct *tty, unsigned int status) |
104 | * struct pps_event_time *ts) | ||
105 | * | 104 | * |
106 | * Tells the discipline that the DCD pin has changed its status and | 105 | * Tells the discipline that the DCD pin has changed its status. |
107 | * the relative timestamp. Pointer ts cannot be NULL. | 106 | * Used exclusively by the N_PPS (Pulse-Per-Second) line discipline. |
108 | */ | 107 | */ |
109 | 108 | ||
110 | #include <linux/fs.h> | 109 | #include <linux/fs.h> |
111 | #include <linux/wait.h> | 110 | #include <linux/wait.h> |
112 | #include <linux/pps_kernel.h> | ||
113 | #include <linux/wait.h> | 111 | #include <linux/wait.h> |
114 | 112 | ||
115 | struct tty_ldisc_ops { | 113 | struct tty_ldisc_ops { |
@@ -144,8 +142,7 @@ struct tty_ldisc_ops { | |||
144 | void (*receive_buf)(struct tty_struct *, const unsigned char *cp, | 142 | void (*receive_buf)(struct tty_struct *, const unsigned char *cp, |
145 | char *fp, int count); | 143 | char *fp, int count); |
146 | void (*write_wakeup)(struct tty_struct *); | 144 | void (*write_wakeup)(struct tty_struct *); |
147 | void (*dcd_change)(struct tty_struct *, unsigned int, | 145 | void (*dcd_change)(struct tty_struct *, unsigned int); |
148 | struct pps_event_time *); | ||
149 | 146 | ||
150 | struct module *owner; | 147 | struct module *owner; |
151 | 148 | ||
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 2c6c85f18ea0..b6a23a483d74 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h | |||
@@ -50,7 +50,7 @@ | |||
50 | #define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */ | 50 | #define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */ |
51 | #define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */ | 51 | #define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */ |
52 | #define PORT_XR17V35X 24 /* Exar XR17V35x UARTs */ | 52 | #define PORT_XR17V35X 24 /* Exar XR17V35x UARTs */ |
53 | #define PORT_BRCM_TRUMANAGE 24 | 53 | #define PORT_BRCM_TRUMANAGE 25 |
54 | #define PORT_MAX_8250 25 /* max port ID */ | 54 | #define PORT_MAX_8250 25 /* max port ID */ |
55 | 55 | ||
56 | /* | 56 | /* |
@@ -220,4 +220,7 @@ | |||
220 | /* ARC (Synopsys) on-chip UART */ | 220 | /* ARC (Synopsys) on-chip UART */ |
221 | #define PORT_ARC 101 | 221 | #define PORT_ARC 101 |
222 | 222 | ||
223 | /* Rocketport EXPRESS/INFINITY */ | ||
224 | #define PORT_RP2 102 | ||
225 | |||
223 | #endif /* _UAPILINUX_SERIAL_CORE_H */ | 226 | #endif /* _UAPILINUX_SERIAL_CORE_H */ |
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 9a61738cefc8..c26278fd4851 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | #include <linux/pid_namespace.h> | 30 | #include <linux/pid_namespace.h> |
31 | #include <linux/clocksource.h> | 31 | #include <linux/clocksource.h> |
32 | #include <linux/serial_core.h> | ||
32 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
33 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
34 | #include <linux/console.h> | 35 | #include <linux/console.h> |
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index ce615e064482..38573f35a5ad 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/kgdb.h> | 32 | #include <linux/kgdb.h> |
33 | #include <linux/kdb.h> | 33 | #include <linux/kdb.h> |
34 | #include <linux/serial_core.h> | ||
34 | #include <linux/reboot.h> | 35 | #include <linux/reboot.h> |
35 | #include <linux/uaccess.h> | 36 | #include <linux/uaccess.h> |
36 | #include <asm/cacheflush.h> | 37 | #include <asm/cacheflush.h> |
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index 77439eb8528d..dbb58ae1b8e0 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb | |||
@@ -22,6 +22,7 @@ config KGDB_SERIAL_CONSOLE | |||
22 | tristate "KGDB: use kgdb over the serial console" | 22 | tristate "KGDB: use kgdb over the serial console" |
23 | select CONSOLE_POLL | 23 | select CONSOLE_POLL |
24 | select MAGIC_SYSRQ | 24 | select MAGIC_SYSRQ |
25 | depends on TTY | ||
25 | default y | 26 | default y |
26 | help | 27 | help |
27 | Share a serial console with kgdb. Sysrq-g must be used | 28 | Share a serial console with kgdb. Sysrq-g must be used |
diff --git a/net/bluetooth/rfcomm/Kconfig b/net/bluetooth/rfcomm/Kconfig index 22e718b554e4..18d352ea2bc7 100644 --- a/net/bluetooth/rfcomm/Kconfig +++ b/net/bluetooth/rfcomm/Kconfig | |||
@@ -12,6 +12,7 @@ config BT_RFCOMM | |||
12 | config BT_RFCOMM_TTY | 12 | config BT_RFCOMM_TTY |
13 | bool "RFCOMM TTY support" | 13 | bool "RFCOMM TTY support" |
14 | depends on BT_RFCOMM | 14 | depends on BT_RFCOMM |
15 | depends on TTY | ||
15 | help | 16 | help |
16 | This option enables TTY emulation support for RFCOMM channels. | 17 | This option enables TTY emulation support for RFCOMM channels. |
17 | 18 | ||
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index bd6fd0f43d2b..b6e44ad6cca6 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -541,23 +541,21 @@ int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | |||
541 | static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) | 541 | static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) |
542 | { | 542 | { |
543 | struct rfcomm_dev *dev = dlc->owner; | 543 | struct rfcomm_dev *dev = dlc->owner; |
544 | struct tty_struct *tty; | ||
545 | 544 | ||
546 | if (!dev) { | 545 | if (!dev) { |
547 | kfree_skb(skb); | 546 | kfree_skb(skb); |
548 | return; | 547 | return; |
549 | } | 548 | } |
550 | 549 | ||
551 | tty = dev->port.tty; | 550 | if (!skb_queue_empty(&dev->pending)) { |
552 | if (!tty || !skb_queue_empty(&dev->pending)) { | ||
553 | skb_queue_tail(&dev->pending, skb); | 551 | skb_queue_tail(&dev->pending, skb); |
554 | return; | 552 | return; |
555 | } | 553 | } |
556 | 554 | ||
557 | BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); | 555 | BT_DBG("dlc %p len %d", dlc, skb->len); |
558 | 556 | ||
559 | tty_insert_flip_string(tty, skb->data, skb->len); | 557 | tty_insert_flip_string(&dev->port, skb->data, skb->len); |
560 | tty_flip_buffer_push(tty); | 558 | tty_flip_buffer_push(&dev->port); |
561 | 559 | ||
562 | kfree_skb(skb); | 560 | kfree_skb(skb); |
563 | } | 561 | } |
@@ -621,26 +619,23 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig) | |||
621 | /* ---- TTY functions ---- */ | 619 | /* ---- TTY functions ---- */ |
622 | static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev) | 620 | static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev) |
623 | { | 621 | { |
624 | struct tty_struct *tty = dev->port.tty; | ||
625 | struct sk_buff *skb; | 622 | struct sk_buff *skb; |
626 | int inserted = 0; | 623 | int inserted = 0; |
627 | 624 | ||
628 | if (!tty) | 625 | BT_DBG("dev %p", dev); |
629 | return; | ||
630 | |||
631 | BT_DBG("dev %p tty %p", dev, tty); | ||
632 | 626 | ||
633 | rfcomm_dlc_lock(dev->dlc); | 627 | rfcomm_dlc_lock(dev->dlc); |
634 | 628 | ||
635 | while ((skb = skb_dequeue(&dev->pending))) { | 629 | while ((skb = skb_dequeue(&dev->pending))) { |
636 | inserted += tty_insert_flip_string(tty, skb->data, skb->len); | 630 | inserted += tty_insert_flip_string(&dev->port, skb->data, |
631 | skb->len); | ||
637 | kfree_skb(skb); | 632 | kfree_skb(skb); |
638 | } | 633 | } |
639 | 634 | ||
640 | rfcomm_dlc_unlock(dev->dlc); | 635 | rfcomm_dlc_unlock(dev->dlc); |
641 | 636 | ||
642 | if (inserted > 0) | 637 | if (inserted > 0) |
643 | tty_flip_buffer_push(tty); | 638 | tty_flip_buffer_push(&dev->port); |
644 | } | 639 | } |
645 | 640 | ||
646 | static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) | 641 | static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) |
diff --git a/net/irda/ircomm/Kconfig b/net/irda/ircomm/Kconfig index 2d4c6b4a78d6..19492c1707b7 100644 --- a/net/irda/ircomm/Kconfig +++ b/net/irda/ircomm/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config IRCOMM | 1 | config IRCOMM |
2 | tristate "IrCOMM protocol" | 2 | tristate "IrCOMM protocol" |
3 | depends on IRDA | 3 | depends on IRDA && TTY |
4 | help | 4 | help |
5 | Say Y here if you want to build support for the IrCOMM protocol. | 5 | Say Y here if you want to build support for the IrCOMM protocol. |
6 | To compile it as modules, choose M here: the modules will be | 6 | To compile it as modules, choose M here: the modules will be |
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index a68c88cdec6e..9a5fd3c3e530 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
@@ -452,7 +452,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
452 | self->line, self->port.count); | 452 | self->line, self->port.count); |
453 | 453 | ||
454 | /* Not really used by us, but lets do it anyway */ | 454 | /* Not really used by us, but lets do it anyway */ |
455 | tty->low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 455 | self->port.low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
456 | 456 | ||
457 | /* | 457 | /* |
458 | * If the port is the middle of closing, bail out now | 458 | * If the port is the middle of closing, bail out now |
@@ -1136,14 +1136,14 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1136 | ircomm_tty_send_initial_parameters(self); | 1136 | ircomm_tty_send_initial_parameters(self); |
1137 | ircomm_tty_link_established(self); | 1137 | ircomm_tty_link_established(self); |
1138 | } | 1138 | } |
1139 | tty_kref_put(tty); | ||
1139 | 1140 | ||
1140 | /* | 1141 | /* |
1141 | * Use flip buffer functions since the code may be called from interrupt | 1142 | * Use flip buffer functions since the code may be called from interrupt |
1142 | * context | 1143 | * context |
1143 | */ | 1144 | */ |
1144 | tty_insert_flip_string(tty, skb->data, skb->len); | 1145 | tty_insert_flip_string(&self->port, skb->data, skb->len); |
1145 | tty_flip_buffer_push(tty); | 1146 | tty_flip_buffer_push(&self->port); |
1146 | tty_kref_put(tty); | ||
1147 | 1147 | ||
1148 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ | 1148 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ |
1149 | 1149 | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 133025fbb6d4..45b72561c615 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -34,7 +34,7 @@ config SND_SOC_ALL_CODECS | |||
34 | select SND_SOC_CS42L73 if I2C | 34 | select SND_SOC_CS42L73 if I2C |
35 | select SND_SOC_CS4270 if I2C | 35 | select SND_SOC_CS4270 if I2C |
36 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI | 36 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI |
37 | select SND_SOC_CX20442 | 37 | select SND_SOC_CX20442 if TTY |
38 | select SND_SOC_DA7210 if I2C | 38 | select SND_SOC_DA7210 if I2C |
39 | select SND_SOC_DA7213 if I2C | 39 | select SND_SOC_DA7213 if I2C |
40 | select SND_SOC_DA732X if I2C | 40 | select SND_SOC_DA732X if I2C |
@@ -237,6 +237,7 @@ config SND_SOC_CS4271 | |||
237 | 237 | ||
238 | config SND_SOC_CX20442 | 238 | config SND_SOC_CX20442 |
239 | tristate | 239 | tristate |
240 | depends on TTY | ||
240 | 241 | ||
241 | config SND_SOC_JZ4740_CODEC | 242 | config SND_SOC_JZ4740_CODEC |
242 | select REGMAP_MMIO | 243 | select REGMAP_MMIO |