diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-20 23:57:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-20 23:57:27 -0400 |
commit | e10abc629f38efd9b6936cf3612583cc846104d9 (patch) | |
tree | 58fb8f6dba5d085d4b0352137d18faf7cfa47a69 | |
parent | 0eff4589c36edd03d50b835d0768b2c2ef3f20bd (diff) | |
parent | d20bb59af64667a16f2468b54fc0adb2f824a3b6 (diff) |
Merge tag 'tty-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty and serial driver updates from Greg KH:
"Here's the large TTY and Serial driver update for 4.7-rc1.
A few new serial drivers are added here, and Peter has fixed a bunch
of long-standing bugs in the tty layer and serial drivers as normal.
Full details in the shortlog.
All of these have been in linux-next for a while with no reported
issues"
* tag 'tty-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (88 commits)
MAINTAINERS: 8250: remove website reference
serial: core: Fix port mutex assert if lockdep disabled
serial: 8250_dw: fix wrong logic in dw8250_check_lcr()
tty: vt, finish looping on duplicate
tty: vt, return error when con_startup fails
QE-UART: add "fsl,t1040-ucc-uart" to of_device_id
serial: mctrl_gpio: Drop support for out1-gpios and out2-gpios
serial: 8250dw: Add device HID for future AMD UART controller
Fix OpenSSH pty regression on close
serial: mctrl_gpio: add IRQ locking
serial: 8250: Integrate Fintek into 8250_base
serial: mps2-uart: add support for early console
serial: mps2-uart: add MPS2 UART driver
dt-bindings: document the MPS2 UART bindings
serial: sirf: Use generic uart-has-rtscts DT property
serial: sirf: Introduce helper variable struct device_node *np
serial: mxs-auart: Use generic uart-has-rtscts DT property
serial: imx: Use generic uart-has-rtscts DT property
doc: DT: Add Generic Serial Device Tree Bindings
serial: 8250: of: Make tegra_serial_handle_break() static
...
104 files changed, 2528 insertions, 1174 deletions
diff --git a/Documentation/devicetree/bindings/serial/arm,mps2-uart.txt b/Documentation/devicetree/bindings/serial/arm,mps2-uart.txt new file mode 100644 index 000000000000..128cc6aed001 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/arm,mps2-uart.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | ARM MPS2 UART | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : Should be "arm,mps2-uart" | ||
5 | - reg : Address and length of the register set | ||
6 | - interrupts : Reference to the UART RX, TX and overrun interrupts | ||
7 | |||
8 | Required clocking property: | ||
9 | - clocks : The input clock of the UART | ||
10 | |||
11 | |||
12 | Examples: | ||
13 | |||
14 | uart0: serial@40004000 { | ||
15 | compatible = "arm,mps2-uart"; | ||
16 | reg = <0x40004000 0x1000>; | ||
17 | interrupts = <0 1 12>; | ||
18 | clocks = <&sysclk>; | ||
19 | }; | ||
diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt index ed94c217c98d..1e82802d8e32 100644 --- a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt +++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt | |||
@@ -6,7 +6,7 @@ Required properties: | |||
6 | - interrupts : Should contain uart interrupt | 6 | - interrupts : Should contain uart interrupt |
7 | 7 | ||
8 | Optional properties: | 8 | Optional properties: |
9 | - fsl,uart-has-rtscts : Indicate the uart has rts and cts | 9 | - uart-has-rtscts : Indicate the uart has rts and cts |
10 | - fsl,irda-mode : Indicate the uart supports irda mode | 10 | - fsl,irda-mode : Indicate the uart supports irda mode |
11 | - fsl,dte-mode : Indicate the uart works in DTE mode. The uart works | 11 | - fsl,dte-mode : Indicate the uart works in DTE mode. The uart works |
12 | in DCE mode by default. | 12 | in DCE mode by default. |
@@ -24,6 +24,6 @@ uart1: serial@73fbc000 { | |||
24 | compatible = "fsl,imx51-uart", "fsl,imx21-uart"; | 24 | compatible = "fsl,imx51-uart", "fsl,imx21-uart"; |
25 | reg = <0x73fbc000 0x4000>; | 25 | reg = <0x73fbc000 0x4000>; |
26 | interrupts = <31>; | 26 | interrupts = <31>; |
27 | fsl,uart-has-rtscts; | 27 | uart-has-rtscts; |
28 | fsl,dte-mode; | 28 | fsl,dte-mode; |
29 | }; | 29 | }; |
diff --git a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt index 7c408c87e613..5c96d41899f1 100644 --- a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +++ b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt | |||
@@ -1,8 +1,10 @@ | |||
1 | * Freescale MXS Application UART (AUART) | 1 | * Freescale MXS Application UART (AUART) |
2 | 2 | ||
3 | Required properties: | 3 | Required properties for all SoCs: |
4 | - compatible : Should be "fsl,<soc>-auart". The supported SoCs include | 4 | - compatible : Should be one of fallowing variants: |
5 | imx23 and imx28. | 5 | "fsl,imx23-auart" - Freescale i.MX23 |
6 | "fsl,imx28-auart" - Freescale i.MX28 | ||
7 | "alphascale,asm9260-auart" - Alphascale ASM9260 | ||
6 | - reg : Address and length of the register set for the device | 8 | - reg : Address and length of the register set for the device |
7 | - interrupts : Should contain the auart interrupt numbers | 9 | - interrupts : Should contain the auart interrupt numbers |
8 | - dmas: DMA specifier, consisting of a phandle to DMA controller node | 10 | - dmas: DMA specifier, consisting of a phandle to DMA controller node |
@@ -10,8 +12,14 @@ Required properties: | |||
10 | Refer to dma.txt and fsl-mxs-dma.txt for details. | 12 | Refer to dma.txt and fsl-mxs-dma.txt for details. |
11 | - dma-names: "rx" for RX channel, "tx" for TX channel. | 13 | - dma-names: "rx" for RX channel, "tx" for TX channel. |
12 | 14 | ||
15 | Required properties for "alphascale,asm9260-auart": | ||
16 | - clocks : the clocks feeding the watchdog timer. See clock-bindings.txt | ||
17 | - clock-names : should be set to | ||
18 | "mod" - source for tick counter. | ||
19 | "ahb" - ahb gate. | ||
20 | |||
13 | Optional properties: | 21 | Optional properties: |
14 | - fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines | 22 | - uart-has-rtscts : Indicate the UART has RTS and CTS lines |
15 | for hardware flow control, | 23 | for hardware flow control, |
16 | it also means you enable the DMA support for this UART. | 24 | it also means you enable the DMA support for this UART. |
17 | - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD | 25 | - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD |
diff --git a/Documentation/devicetree/bindings/serial/serial.txt b/Documentation/devicetree/bindings/serial/serial.txt new file mode 100644 index 000000000000..fd970f76a7b8 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/serial.txt | |||
@@ -0,0 +1,57 @@ | |||
1 | Generic Serial DT Bindings | ||
2 | |||
3 | This document lists a set of generic properties for describing UARTs in a | ||
4 | device tree. Whether these properties apply to a particular device depends on | ||
5 | the DT bindings for the actual device. | ||
6 | |||
7 | Optional properties: | ||
8 | - cts-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be | ||
9 | used as the UART's CTS line. | ||
10 | - dcd-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be | ||
11 | used as the UART's DCD line. | ||
12 | - dsr-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be | ||
13 | used as the UART's DSR line. | ||
14 | - dtr-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be | ||
15 | used as the UART's DTR line. | ||
16 | - rng-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be | ||
17 | used as the UART's RNG line. | ||
18 | - rts-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be | ||
19 | used as the UART's RTS line. | ||
20 | |||
21 | - uart-has-rtscts: The presence of this property indicates that the | ||
22 | UART has dedicated lines for RTS/CTS hardware flow control, and that | ||
23 | they are available for use (wired and enabled by pinmux configuration). | ||
24 | This depends on both the UART hardware and the board wiring. | ||
25 | Note that this property is mutually-exclusive with "cts-gpios" and | ||
26 | "rts-gpios" above. | ||
27 | |||
28 | |||
29 | Examples: | ||
30 | |||
31 | uart1: serial@48022000 { | ||
32 | compatible = "ti,am3352-uart", "ti,omap3-uart"; | ||
33 | ti,hwmods = "uart2"; | ||
34 | clock-frequency = <48000000>; | ||
35 | reg = <0x48022000 0x2000>; | ||
36 | interrupts = <73>; | ||
37 | dmas = <&edma 28 0>, <&edma 29 0>; | ||
38 | dma-names = "tx", "rx"; | ||
39 | dtr-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; | ||
40 | dsr-gpios = <&gpio2 23 GPIO_ACTIVE_LOW>; | ||
41 | dcd-gpios = <&gpio2 24 GPIO_ACTIVE_LOW>; | ||
42 | rng-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>; | ||
43 | cts-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; | ||
44 | rts-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; | ||
45 | status = "okay"; | ||
46 | }; | ||
47 | |||
48 | scifa4: serial@e6c80000 { | ||
49 | compatible = "renesas,scifa-sh73a0", "renesas,scifa"; | ||
50 | reg = <0xe6c80000 0x100>; | ||
51 | interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; | ||
52 | clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>; | ||
53 | clock-names = "fck"; | ||
54 | power-domains = <&pd_a3sp>; | ||
55 | uart-has-rtscts; | ||
56 | status = "okay"; | ||
57 | }; | ||
diff --git a/Documentation/devicetree/bindings/serial/sirf-uart.txt b/Documentation/devicetree/bindings/serial/sirf-uart.txt index 67e2a0aeb042..1e48bbbeecc6 100644 --- a/Documentation/devicetree/bindings/serial/sirf-uart.txt +++ b/Documentation/devicetree/bindings/serial/sirf-uart.txt | |||
@@ -9,9 +9,9 @@ Required properties: | |||
9 | - clocks : Should contain uart clock number | 9 | - clocks : Should contain uart clock number |
10 | 10 | ||
11 | Optional properties: | 11 | Optional properties: |
12 | - sirf,uart-has-rtscts: we have hardware flow controller pins in hardware | 12 | - uart-has-rtscts: we have hardware flow controller pins in hardware |
13 | - rts-gpios: RTS pin for USP-based UART if sirf,uart-has-rtscts is true | 13 | - rts-gpios: RTS pin for USP-based UART if uart-has-rtscts is true |
14 | - cts-gpios: CTS pin for USP-based UART if sirf,uart-has-rtscts is true | 14 | - cts-gpios: CTS pin for USP-based UART if uart-has-rtscts is true |
15 | 15 | ||
16 | Example: | 16 | Example: |
17 | 17 | ||
@@ -28,7 +28,7 @@ On the board-specific dts, we can put rts-gpios and cts-gpios like | |||
28 | 28 | ||
29 | usp@b0090000 { | 29 | usp@b0090000 { |
30 | compatible = "sirf,prima2-usp-uart"; | 30 | compatible = "sirf,prima2-usp-uart"; |
31 | sirf,uart-has-rtscts; | 31 | uart-has-rtscts; |
32 | rts-gpios = <&gpio 15 0>; | 32 | rts-gpios = <&gpio 15 0>; |
33 | cts-gpios = <&gpio 46 0>; | 33 | cts-gpios = <&gpio 46 0>; |
34 | }; | 34 | }; |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4e76a349b6f8..82b42c958d1c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1054,6 +1054,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1054 | the driver will use only 32-bit accessors to read/write | 1054 | the driver will use only 32-bit accessors to read/write |
1055 | the device registers. | 1055 | the device registers. |
1056 | 1056 | ||
1057 | meson,<addr> | ||
1058 | Start an early, polled-mode console on a meson serial | ||
1059 | port at the specified address. The serial port must | ||
1060 | already be setup and configured. Options are not yet | ||
1061 | supported. | ||
1062 | |||
1057 | msm_serial,<addr> | 1063 | msm_serial,<addr> |
1058 | Start an early, polled-mode console on an msm serial | 1064 | Start an early, polled-mode console on an msm serial |
1059 | port at the specified address. The serial port | 1065 | port at the specified address. The serial port |
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt index 798cba82c762..b48780977a68 100644 --- a/Documentation/serial/tty.txt +++ b/Documentation/serial/tty.txt | |||
@@ -210,9 +210,6 @@ TTY_IO_ERROR If set, causes all subsequent userspace read/write | |||
210 | 210 | ||
211 | TTY_OTHER_CLOSED Device is a pty and the other side has closed. | 211 | TTY_OTHER_CLOSED Device is a pty and the other side has closed. |
212 | 212 | ||
213 | TTY_OTHER_DONE Device is a pty and the other side has closed and | ||
214 | all pending input processing has been completed. | ||
215 | |||
216 | TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into | 213 | TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into |
217 | smaller chunks. | 214 | smaller chunks. |
218 | 215 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index e8408315a696..832f070cbf0f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -175,7 +175,6 @@ F: drivers/net/ethernet/realtek/r8169.c | |||
175 | 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER | 175 | 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER |
176 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 176 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
177 | L: linux-serial@vger.kernel.org | 177 | L: linux-serial@vger.kernel.org |
178 | W: http://serial.sourceforge.net | ||
179 | S: Maintained | 178 | S: Maintained |
180 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git | 179 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git |
181 | F: drivers/tty/serial/8250* | 180 | F: drivers/tty/serial/8250* |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index e70cadec7ce6..21fd50def270 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -300,7 +300,7 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) | |||
300 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 300 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
301 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && | 301 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && |
302 | (cmd != TIOCMIWAIT)) { | 302 | (cmd != TIOCMIWAIT)) { |
303 | if (tty->flags & (1 << TTY_IO_ERROR)) | 303 | if (tty_io_error(tty)) |
304 | return -EIO; | 304 | return -EIO; |
305 | } | 305 | } |
306 | 306 | ||
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c index b955fafc58ba..d1adc59af5bf 100644 --- a/arch/mips/ath79/early_printk.c +++ b/arch/mips/ath79/early_printk.c | |||
@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val) | |||
31 | } while (1); | 31 | } while (1); |
32 | } | 32 | } |
33 | 33 | ||
34 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
35 | |||
34 | static void prom_putchar_ar71xx(unsigned char ch) | 36 | static void prom_putchar_ar71xx(unsigned char ch) |
35 | { | 37 | { |
36 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); | 38 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); |
37 | 39 | ||
38 | prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); | 40 | prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY); |
39 | __raw_writel(ch, base + UART_TX * 4); | 41 | __raw_writel(ch, base + UART_TX * 4); |
40 | prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); | 42 | prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY); |
41 | } | 43 | } |
42 | 44 | ||
43 | static void prom_putchar_ar933x(unsigned char ch) | 45 | static void prom_putchar_ar933x(unsigned char ch) |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index e524e8302da6..d28922df01d7 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -1101,7 +1101,7 @@ static void dcd_change(MGSLPC_INFO *info, struct tty_struct *tty) | |||
1101 | wake_up_interruptible(&info->status_event_wait_q); | 1101 | wake_up_interruptible(&info->status_event_wait_q); |
1102 | wake_up_interruptible(&info->event_wait_q); | 1102 | wake_up_interruptible(&info->event_wait_q); |
1103 | 1103 | ||
1104 | if (info->port.flags & ASYNC_CHECK_CD) { | 1104 | if (tty_port_check_carrier(&info->port)) { |
1105 | if (debug_level >= DEBUG_LEVEL_ISR) | 1105 | if (debug_level >= DEBUG_LEVEL_ISR) |
1106 | printk("%s CD now %s...", info->device_name, | 1106 | printk("%s CD now %s...", info->device_name, |
1107 | (info->serial_signals & SerialSignal_DCD) ? "on" : "off"); | 1107 | (info->serial_signals & SerialSignal_DCD) ? "on" : "off"); |
@@ -1272,7 +1272,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty) | |||
1272 | if (debug_level >= DEBUG_LEVEL_INFO) | 1272 | if (debug_level >= DEBUG_LEVEL_INFO) |
1273 | printk("%s(%d):startup(%s)\n", __FILE__, __LINE__, info->device_name); | 1273 | printk("%s(%d):startup(%s)\n", __FILE__, __LINE__, info->device_name); |
1274 | 1274 | ||
1275 | if (info->port.flags & ASYNC_INITIALIZED) | 1275 | if (tty_port_initialized(&info->port)) |
1276 | return 0; | 1276 | return 0; |
1277 | 1277 | ||
1278 | if (!info->tx_buf) { | 1278 | if (!info->tx_buf) { |
@@ -1311,7 +1311,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty) | |||
1311 | if (tty) | 1311 | if (tty) |
1312 | clear_bit(TTY_IO_ERROR, &tty->flags); | 1312 | clear_bit(TTY_IO_ERROR, &tty->flags); |
1313 | 1313 | ||
1314 | info->port.flags |= ASYNC_INITIALIZED; | 1314 | tty_port_set_initialized(&info->port, 1); |
1315 | 1315 | ||
1316 | return 0; | 1316 | return 0; |
1317 | } | 1317 | } |
@@ -1322,7 +1322,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) | |||
1322 | { | 1322 | { |
1323 | unsigned long flags; | 1323 | unsigned long flags; |
1324 | 1324 | ||
1325 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1325 | if (!tty_port_initialized(&info->port)) |
1326 | return; | 1326 | return; |
1327 | 1327 | ||
1328 | if (debug_level >= DEBUG_LEVEL_INFO) | 1328 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -1361,7 +1361,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) | |||
1361 | if (tty) | 1361 | if (tty) |
1362 | set_bit(TTY_IO_ERROR, &tty->flags); | 1362 | set_bit(TTY_IO_ERROR, &tty->flags); |
1363 | 1363 | ||
1364 | info->port.flags &= ~ASYNC_INITIALIZED; | 1364 | tty_port_set_initialized(&info->port, 0); |
1365 | } | 1365 | } |
1366 | 1366 | ||
1367 | static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty) | 1367 | static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty) |
@@ -1466,15 +1466,8 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty) | |||
1466 | } | 1466 | } |
1467 | info->timeout += HZ/50; /* Add .02 seconds of slop */ | 1467 | info->timeout += HZ/50; /* Add .02 seconds of slop */ |
1468 | 1468 | ||
1469 | if (cflag & CRTSCTS) | 1469 | tty_port_set_cts_flow(&info->port, cflag & CRTSCTS); |
1470 | info->port.flags |= ASYNC_CTS_FLOW; | 1470 | tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL); |
1471 | else | ||
1472 | info->port.flags &= ~ASYNC_CTS_FLOW; | ||
1473 | |||
1474 | if (cflag & CLOCAL) | ||
1475 | info->port.flags &= ~ASYNC_CHECK_CD; | ||
1476 | else | ||
1477 | info->port.flags |= ASYNC_CHECK_CD; | ||
1478 | 1471 | ||
1479 | /* process tty input control flags */ | 1472 | /* process tty input control flags */ |
1480 | 1473 | ||
@@ -2246,7 +2239,7 @@ static int mgslpc_ioctl(struct tty_struct *tty, | |||
2246 | 2239 | ||
2247 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 2240 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
2248 | (cmd != TIOCMIWAIT)) { | 2241 | (cmd != TIOCMIWAIT)) { |
2249 | if (tty->flags & (1 << TTY_IO_ERROR)) | 2242 | if (tty_io_error(tty)) |
2250 | return -EIO; | 2243 | return -EIO; |
2251 | } | 2244 | } |
2252 | 2245 | ||
@@ -2316,7 +2309,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2316 | /* Handle transition away from B0 status */ | 2309 | /* Handle transition away from B0 status */ |
2317 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { | 2310 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
2318 | info->serial_signals |= SerialSignal_DTR; | 2311 | info->serial_signals |= SerialSignal_DTR; |
2319 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) | 2312 | if (!C_CRTSCTS(tty) || !tty_throttled(tty)) |
2320 | info->serial_signals |= SerialSignal_RTS; | 2313 | info->serial_signals |= SerialSignal_RTS; |
2321 | spin_lock_irqsave(&info->lock, flags); | 2314 | spin_lock_irqsave(&info->lock, flags); |
2322 | set_signals(info); | 2315 | set_signals(info); |
@@ -2345,7 +2338,7 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp) | |||
2345 | if (tty_port_close_start(port, tty, filp) == 0) | 2338 | if (tty_port_close_start(port, tty, filp) == 0) |
2346 | goto cleanup; | 2339 | goto cleanup; |
2347 | 2340 | ||
2348 | if (port->flags & ASYNC_INITIALIZED) | 2341 | if (tty_port_initialized(port)) |
2349 | mgslpc_wait_until_sent(tty, info->timeout); | 2342 | mgslpc_wait_until_sent(tty, info->timeout); |
2350 | 2343 | ||
2351 | mgslpc_flush_buffer(tty); | 2344 | mgslpc_flush_buffer(tty); |
@@ -2378,7 +2371,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2378 | if (mgslpc_paranoia_check(info, tty->name, "mgslpc_wait_until_sent")) | 2371 | if (mgslpc_paranoia_check(info, tty->name, "mgslpc_wait_until_sent")) |
2379 | return; | 2372 | return; |
2380 | 2373 | ||
2381 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 2374 | if (!tty_port_initialized(&info->port)) |
2382 | goto exit; | 2375 | goto exit; |
2383 | 2376 | ||
2384 | orig_jiffies = jiffies; | 2377 | orig_jiffies = jiffies; |
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 035d5449227e..75dd15d66df6 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c | |||
@@ -629,8 +629,7 @@ static void ipoctal_hangup(struct tty_struct *tty) | |||
629 | tty_port_hangup(&channel->tty_port); | 629 | tty_port_hangup(&channel->tty_port); |
630 | 630 | ||
631 | ipoctal_reset_channel(channel); | 631 | ipoctal_reset_channel(channel); |
632 | 632 | tty_port_set_initialized(&channel->tty_port, 0); | |
633 | clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); | ||
634 | wake_up_interruptible(&channel->tty_port.open_wait); | 633 | wake_up_interruptible(&channel->tty_port.open_wait); |
635 | } | 634 | } |
636 | 635 | ||
@@ -642,7 +641,7 @@ static void ipoctal_shutdown(struct tty_struct *tty) | |||
642 | return; | 641 | return; |
643 | 642 | ||
644 | ipoctal_reset_channel(channel); | 643 | ipoctal_reset_channel(channel); |
645 | clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); | 644 | tty_port_set_initialized(&channel->tty_port, 0); |
646 | } | 645 | } |
647 | 646 | ||
648 | static void ipoctal_cleanup(struct tty_struct *tty) | 647 | static void ipoctal_cleanup(struct tty_struct *tty) |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 947d5c978b8f..63eaa0a9f8a1 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1043,17 +1043,13 @@ isdn_tty_change_speed(modem_info *info) | |||
1043 | if (!(cflag & PARODD)) | 1043 | if (!(cflag & PARODD)) |
1044 | cval |= UART_LCR_EPAR; | 1044 | cval |= UART_LCR_EPAR; |
1045 | 1045 | ||
1046 | if (cflag & CLOCAL) | 1046 | tty_port_set_check_carrier(port, ~cflag & CLOCAL); |
1047 | port->flags &= ~ASYNC_CHECK_CD; | ||
1048 | else { | ||
1049 | port->flags |= ASYNC_CHECK_CD; | ||
1050 | } | ||
1051 | } | 1047 | } |
1052 | 1048 | ||
1053 | static int | 1049 | static int |
1054 | isdn_tty_startup(modem_info *info) | 1050 | isdn_tty_startup(modem_info *info) |
1055 | { | 1051 | { |
1056 | if (info->port.flags & ASYNC_INITIALIZED) | 1052 | if (tty_port_initialized(&info->port)) |
1057 | return 0; | 1053 | return 0; |
1058 | isdn_lock_drivers(); | 1054 | isdn_lock_drivers(); |
1059 | #ifdef ISDN_DEBUG_MODEM_OPEN | 1055 | #ifdef ISDN_DEBUG_MODEM_OPEN |
@@ -1070,7 +1066,7 @@ isdn_tty_startup(modem_info *info) | |||
1070 | */ | 1066 | */ |
1071 | isdn_tty_change_speed(info); | 1067 | isdn_tty_change_speed(info); |
1072 | 1068 | ||
1073 | info->port.flags |= ASYNC_INITIALIZED; | 1069 | tty_port_set_initialized(&info->port, 1); |
1074 | info->msr |= (UART_MSR_DSR | UART_MSR_CTS); | 1070 | info->msr |= (UART_MSR_DSR | UART_MSR_CTS); |
1075 | info->send_outstanding = 0; | 1071 | info->send_outstanding = 0; |
1076 | return 0; | 1072 | return 0; |
@@ -1083,7 +1079,7 @@ isdn_tty_startup(modem_info *info) | |||
1083 | static void | 1079 | static void |
1084 | isdn_tty_shutdown(modem_info *info) | 1080 | isdn_tty_shutdown(modem_info *info) |
1085 | { | 1081 | { |
1086 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1082 | if (!tty_port_initialized(&info->port)) |
1087 | return; | 1083 | return; |
1088 | #ifdef ISDN_DEBUG_MODEM_OPEN | 1084 | #ifdef ISDN_DEBUG_MODEM_OPEN |
1089 | printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line); | 1085 | printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line); |
@@ -1103,7 +1099,7 @@ isdn_tty_shutdown(modem_info *info) | |||
1103 | if (info->port.tty) | 1099 | if (info->port.tty) |
1104 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 1100 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
1105 | 1101 | ||
1106 | info->port.flags &= ~ASYNC_INITIALIZED; | 1102 | tty_port_set_initialized(&info->port, 0); |
1107 | } | 1103 | } |
1108 | 1104 | ||
1109 | /* isdn_tty_write() is the main send-routine. It is called from the upper | 1105 | /* isdn_tty_write() is the main send-routine. It is called from the upper |
@@ -1351,7 +1347,7 @@ isdn_tty_tiocmget(struct tty_struct *tty) | |||
1351 | 1347 | ||
1352 | if (isdn_tty_paranoia_check(info, tty->name, __func__)) | 1348 | if (isdn_tty_paranoia_check(info, tty->name, __func__)) |
1353 | return -ENODEV; | 1349 | return -ENODEV; |
1354 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1350 | if (tty_io_error(tty)) |
1355 | return -EIO; | 1351 | return -EIO; |
1356 | 1352 | ||
1357 | mutex_lock(&modem_info_mutex); | 1353 | mutex_lock(&modem_info_mutex); |
@@ -1378,7 +1374,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, | |||
1378 | 1374 | ||
1379 | if (isdn_tty_paranoia_check(info, tty->name, __func__)) | 1375 | if (isdn_tty_paranoia_check(info, tty->name, __func__)) |
1380 | return -ENODEV; | 1376 | return -ENODEV; |
1381 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1377 | if (tty_io_error(tty)) |
1382 | return -EIO; | 1378 | return -EIO; |
1383 | 1379 | ||
1384 | #ifdef ISDN_DEBUG_MODEM_IOCTL | 1380 | #ifdef ISDN_DEBUG_MODEM_IOCTL |
@@ -1419,7 +1415,7 @@ isdn_tty_ioctl(struct tty_struct *tty, uint cmd, ulong arg) | |||
1419 | 1415 | ||
1420 | if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_ioctl")) | 1416 | if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_ioctl")) |
1421 | return -ENODEV; | 1417 | return -ENODEV; |
1422 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1418 | if (tty_io_error(tty)) |
1423 | return -EIO; | 1419 | return -EIO; |
1424 | switch (cmd) { | 1420 | switch (cmd) { |
1425 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 1421 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
@@ -1581,7 +1577,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) | |||
1581 | * interrupt driver to stop checking the data ready bit in the | 1577 | * interrupt driver to stop checking the data ready bit in the |
1582 | * line status register. | 1578 | * line status register. |
1583 | */ | 1579 | */ |
1584 | if (port->flags & ASYNC_INITIALIZED) { | 1580 | if (tty_port_initialized(port)) { |
1585 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ | 1581 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ |
1586 | /* | 1582 | /* |
1587 | * Before we drop DTR, make sure the UART transmitter | 1583 | * Before we drop DTR, make sure the UART transmitter |
@@ -1622,7 +1618,7 @@ isdn_tty_hangup(struct tty_struct *tty) | |||
1622 | return; | 1618 | return; |
1623 | isdn_tty_shutdown(info); | 1619 | isdn_tty_shutdown(info); |
1624 | port->count = 0; | 1620 | port->count = 0; |
1625 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | 1621 | tty_port_set_active(port, 0); |
1626 | port->tty = NULL; | 1622 | port->tty = NULL; |
1627 | wake_up_interruptible(&port->open_wait); | 1623 | wake_up_interruptible(&port->open_wait); |
1628 | } | 1624 | } |
@@ -1979,7 +1975,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup) | |||
1979 | #endif | 1975 | #endif |
1980 | if ( | 1976 | if ( |
1981 | #ifndef FIX_FILE_TRANSFER | 1977 | #ifndef FIX_FILE_TRANSFER |
1982 | (info->port.flags & ASYNC_NORMAL_ACTIVE) && | 1978 | tty_port_active(&info->port) && |
1983 | #endif | 1979 | #endif |
1984 | (info->isdn_driver == -1) && | 1980 | (info->isdn_driver == -1) && |
1985 | (info->isdn_channel == -1) && | 1981 | (info->isdn_channel == -1) && |
@@ -2018,8 +2014,6 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup) | |||
2018 | return (wret == 2) ? 3 : 0; | 2014 | return (wret == 2) ? 3 : 0; |
2019 | } | 2015 | } |
2020 | 2016 | ||
2021 | #define TTY_IS_ACTIVE(info) (info->port.flags & ASYNC_NORMAL_ACTIVE) | ||
2022 | |||
2023 | int | 2017 | int |
2024 | isdn_tty_stat_callback(int i, isdn_ctrl *c) | 2018 | isdn_tty_stat_callback(int i, isdn_ctrl *c) |
2025 | { | 2019 | { |
@@ -2077,7 +2071,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) | |||
2077 | #ifdef ISDN_TTY_STAT_DEBUG | 2071 | #ifdef ISDN_TTY_STAT_DEBUG |
2078 | printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line); | 2072 | printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line); |
2079 | #endif | 2073 | #endif |
2080 | if (TTY_IS_ACTIVE(info)) { | 2074 | if (tty_port_active(&info->port)) { |
2081 | if (info->dialing == 1) { | 2075 | if (info->dialing == 1) { |
2082 | info->dialing = 2; | 2076 | info->dialing = 2; |
2083 | return 1; | 2077 | return 1; |
@@ -2088,7 +2082,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) | |||
2088 | #ifdef ISDN_TTY_STAT_DEBUG | 2082 | #ifdef ISDN_TTY_STAT_DEBUG |
2089 | printk(KERN_DEBUG "tty_STAT_DHUP ttyI%d\n", info->line); | 2083 | printk(KERN_DEBUG "tty_STAT_DHUP ttyI%d\n", info->line); |
2090 | #endif | 2084 | #endif |
2091 | if (TTY_IS_ACTIVE(info)) { | 2085 | if (tty_port_active(&info->port)) { |
2092 | if (info->dialing == 1) | 2086 | if (info->dialing == 1) |
2093 | isdn_tty_modem_result(RESULT_BUSY, info); | 2087 | isdn_tty_modem_result(RESULT_BUSY, info); |
2094 | if (info->dialing > 1) | 2088 | if (info->dialing > 1) |
@@ -2118,7 +2112,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) | |||
2118 | * waiting for it and | 2112 | * waiting for it and |
2119 | * set DCD-bit of its modem-status. | 2113 | * set DCD-bit of its modem-status. |
2120 | */ | 2114 | */ |
2121 | if (TTY_IS_ACTIVE(info) || | 2115 | if (tty_port_active(&info->port) || |
2122 | (info->port.blocked_open && | 2116 | (info->port.blocked_open && |
2123 | (info->emu.mdmreg[REG_DCD] & BIT_DCD))) { | 2117 | (info->emu.mdmreg[REG_DCD] & BIT_DCD))) { |
2124 | info->msr |= UART_MSR_DCD; | 2118 | info->msr |= UART_MSR_DCD; |
@@ -2145,7 +2139,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) | |||
2145 | #ifdef ISDN_TTY_STAT_DEBUG | 2139 | #ifdef ISDN_TTY_STAT_DEBUG |
2146 | printk(KERN_DEBUG "tty_STAT_BHUP ttyI%d\n", info->line); | 2140 | printk(KERN_DEBUG "tty_STAT_BHUP ttyI%d\n", info->line); |
2147 | #endif | 2141 | #endif |
2148 | if (TTY_IS_ACTIVE(info)) { | 2142 | if (tty_port_active(&info->port)) { |
2149 | #ifdef ISDN_DEBUG_MODEM_HUP | 2143 | #ifdef ISDN_DEBUG_MODEM_HUP |
2150 | printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n"); | 2144 | printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n"); |
2151 | #endif | 2145 | #endif |
@@ -2157,7 +2151,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) | |||
2157 | #ifdef ISDN_TTY_STAT_DEBUG | 2151 | #ifdef ISDN_TTY_STAT_DEBUG |
2158 | printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line); | 2152 | printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line); |
2159 | #endif | 2153 | #endif |
2160 | if (TTY_IS_ACTIVE(info)) { | 2154 | if (tty_port_active(&info->port)) { |
2161 | if (info->dialing) { | 2155 | if (info->dialing) { |
2162 | info->dialing = 0; | 2156 | info->dialing = 0; |
2163 | info->last_l2 = -1; | 2157 | info->last_l2 = -1; |
@@ -2183,14 +2177,14 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) | |||
2183 | return 1; | 2177 | return 1; |
2184 | #ifdef CONFIG_ISDN_TTY_FAX | 2178 | #ifdef CONFIG_ISDN_TTY_FAX |
2185 | case ISDN_STAT_FAXIND: | 2179 | case ISDN_STAT_FAXIND: |
2186 | if (TTY_IS_ACTIVE(info)) { | 2180 | if (tty_port_active(&info->port)) { |
2187 | isdn_tty_fax_command(info, c); | 2181 | isdn_tty_fax_command(info, c); |
2188 | } | 2182 | } |
2189 | break; | 2183 | break; |
2190 | #endif | 2184 | #endif |
2191 | #ifdef CONFIG_ISDN_AUDIO | 2185 | #ifdef CONFIG_ISDN_AUDIO |
2192 | case ISDN_STAT_AUDIO: | 2186 | case ISDN_STAT_AUDIO: |
2193 | if (TTY_IS_ACTIVE(info)) { | 2187 | if (tty_port_active(&info->port)) { |
2194 | switch (c->parm.num[0]) { | 2188 | switch (c->parm.num[0]) { |
2195 | case ISDN_AUDIO_DTMF: | 2189 | case ISDN_AUDIO_DTMF: |
2196 | if (info->vonline) { | 2190 | if (info->vonline) { |
@@ -2528,7 +2522,7 @@ isdn_tty_modem_result(int code, modem_info *info) | |||
2528 | if (info->closing || (!info->port.tty)) | 2522 | if (info->closing || (!info->port.tty)) |
2529 | return; | 2523 | return; |
2530 | 2524 | ||
2531 | if (info->port.flags & ASYNC_CHECK_CD) | 2525 | if (tty_port_check_carrier(&info->port)) |
2532 | tty_hangup(info->port.tty); | 2526 | tty_hangup(info->port.tty); |
2533 | } | 2527 | } |
2534 | } | 2528 | } |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 5415056f9aa5..5af6fb9a9ce2 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -895,7 +895,7 @@ static void sdio_uart_set_termios(struct tty_struct *tty, | |||
895 | /* Handle transition away from B0 status */ | 895 | /* Handle transition away from B0 status */ |
896 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { | 896 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
897 | unsigned int mask = TIOCM_DTR; | 897 | unsigned int mask = TIOCM_DTR; |
898 | if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) | 898 | if (!(cflag & CRTSCTS) || !tty_throttled(tty)) |
899 | mask |= TIOCM_RTS; | 899 | mask |= TIOCM_RTS; |
900 | sdio_uart_set_mctrl(port, mask); | 900 | sdio_uart_set_mctrl(port, mask); |
901 | } | 901 | } |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 111d907e0c11..4b4458616693 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -2029,7 +2029,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) | |||
2029 | 2029 | ||
2030 | tty = tty_port_tty_get(&serial->port); | 2030 | tty = tty_port_tty_get(&serial->port); |
2031 | 2031 | ||
2032 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { | 2032 | if (tty && tty_throttled(tty)) { |
2033 | tty_kref_put(tty); | 2033 | tty_kref_put(tty); |
2034 | return -1; | 2034 | return -1; |
2035 | } | 2035 | } |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index e7e078b3c7e6..931d10e86837 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -289,7 +289,7 @@ static void raw3215_timeout(unsigned long __data) | |||
289 | 289 | ||
290 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 290 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
291 | raw->flags &= ~RAW3215_TIMER_RUNS; | 291 | raw->flags &= ~RAW3215_TIMER_RUNS; |
292 | if (!(raw->port.flags & ASYNC_SUSPENDED)) { | 292 | if (!tty_port_suspended(&raw->port)) { |
293 | raw3215_mk_write_req(raw); | 293 | raw3215_mk_write_req(raw); |
294 | raw3215_start_io(raw); | 294 | raw3215_start_io(raw); |
295 | if ((raw->queued_read || raw->queued_write) && | 295 | if ((raw->queued_read || raw->queued_write) && |
@@ -311,8 +311,7 @@ static void raw3215_timeout(unsigned long __data) | |||
311 | */ | 311 | */ |
312 | static inline void raw3215_try_io(struct raw3215_info *raw) | 312 | static inline void raw3215_try_io(struct raw3215_info *raw) |
313 | { | 313 | { |
314 | if (!(raw->port.flags & ASYNC_INITIALIZED) || | 314 | if (!tty_port_initialized(&raw->port) || tty_port_suspended(&raw->port)) |
315 | (raw->port.flags & ASYNC_SUSPENDED)) | ||
316 | return; | 315 | return; |
317 | if (raw->queued_read != NULL) | 316 | if (raw->queued_read != NULL) |
318 | raw3215_start_io(raw); | 317 | raw3215_start_io(raw); |
@@ -494,7 +493,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length) | |||
494 | /* While console is frozen for suspend we have no other | 493 | /* While console is frozen for suspend we have no other |
495 | * choice but to drop message from the buffer to make | 494 | * choice but to drop message from the buffer to make |
496 | * room for even more messages. */ | 495 | * room for even more messages. */ |
497 | if (raw->port.flags & ASYNC_SUSPENDED) { | 496 | if (tty_port_suspended(&raw->port)) { |
498 | raw3215_drop_line(raw); | 497 | raw3215_drop_line(raw); |
499 | continue; | 498 | continue; |
500 | } | 499 | } |
@@ -616,10 +615,10 @@ static int raw3215_startup(struct raw3215_info *raw) | |||
616 | { | 615 | { |
617 | unsigned long flags; | 616 | unsigned long flags; |
618 | 617 | ||
619 | if (raw->port.flags & ASYNC_INITIALIZED) | 618 | if (tty_port_initialized(&raw->port)) |
620 | return 0; | 619 | return 0; |
621 | raw->line_pos = 0; | 620 | raw->line_pos = 0; |
622 | raw->port.flags |= ASYNC_INITIALIZED; | 621 | tty_port_set_initialized(&raw->port, 1); |
623 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 622 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
624 | raw3215_try_io(raw); | 623 | raw3215_try_io(raw); |
625 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); | 624 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); |
@@ -635,8 +634,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) | |||
635 | DECLARE_WAITQUEUE(wait, current); | 634 | DECLARE_WAITQUEUE(wait, current); |
636 | unsigned long flags; | 635 | unsigned long flags; |
637 | 636 | ||
638 | if (!(raw->port.flags & ASYNC_INITIALIZED) || | 637 | if (!tty_port_initialized(&raw->port) || (raw->flags & RAW3215_FIXED)) |
639 | (raw->flags & RAW3215_FIXED)) | ||
640 | return; | 638 | return; |
641 | /* Wait for outstanding requests, then free irq */ | 639 | /* Wait for outstanding requests, then free irq */ |
642 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 640 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
@@ -650,7 +648,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) | |||
650 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 648 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
651 | remove_wait_queue(&raw->empty_wait, &wait); | 649 | remove_wait_queue(&raw->empty_wait, &wait); |
652 | set_current_state(TASK_RUNNING); | 650 | set_current_state(TASK_RUNNING); |
653 | raw->port.flags &= ~ASYNC_INITIALIZED; | 651 | tty_port_set_initialized(&raw->port, 1); |
654 | } | 652 | } |
655 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); | 653 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); |
656 | } | 654 | } |
@@ -773,7 +771,7 @@ static int raw3215_pm_stop(struct ccw_device *cdev) | |||
773 | raw = dev_get_drvdata(&cdev->dev); | 771 | raw = dev_get_drvdata(&cdev->dev); |
774 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 772 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
775 | raw3215_make_room(raw, RAW3215_BUFFER_SIZE); | 773 | raw3215_make_room(raw, RAW3215_BUFFER_SIZE); |
776 | raw->port.flags |= ASYNC_SUSPENDED; | 774 | tty_port_set_suspended(&raw->port, 1); |
777 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); | 775 | spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); |
778 | return 0; | 776 | return 0; |
779 | } | 777 | } |
@@ -786,7 +784,7 @@ static int raw3215_pm_start(struct ccw_device *cdev) | |||
786 | /* Allow I/O again and flush output buffer. */ | 784 | /* Allow I/O again and flush output buffer. */ |
787 | raw = dev_get_drvdata(&cdev->dev); | 785 | raw = dev_get_drvdata(&cdev->dev); |
788 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 786 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
789 | raw->port.flags &= ~ASYNC_SUSPENDED; | 787 | tty_port_set_suspended(&raw->port, 0); |
790 | raw->flags |= RAW3215_FLUSHING; | 788 | raw->flags |= RAW3215_FLUSHING; |
791 | raw3215_try_io(raw); | 789 | raw3215_try_io(raw); |
792 | raw->flags &= ~RAW3215_FLUSHING; | 790 | raw->flags &= ~RAW3215_FLUSHING; |
@@ -859,7 +857,7 @@ static void con3215_flush(void) | |||
859 | unsigned long flags; | 857 | unsigned long flags; |
860 | 858 | ||
861 | raw = raw3215[0]; /* console 3215 is the first one */ | 859 | raw = raw3215[0]; /* console 3215 is the first one */ |
862 | if (raw->port.flags & ASYNC_SUSPENDED) | 860 | if (tty_port_suspended(&raw->port)) |
863 | /* The console is still frozen for suspend. */ | 861 | /* The console is still frozen for suspend. */ |
864 | if (ccw_device_force_console(raw->cdev)) | 862 | if (ccw_device_force_console(raw->cdev)) |
865 | /* Forcing didn't work, no panic message .. */ | 863 | /* Forcing didn't work, no panic message .. */ |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 0a9f219fdc7c..272cb6cd1b2a 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
@@ -1860,7 +1860,7 @@ static int tty3270_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
1860 | tp = tty->driver_data; | 1860 | tp = tty->driver_data; |
1861 | if (!tp) | 1861 | if (!tp) |
1862 | return -ENODEV; | 1862 | return -ENODEV; |
1863 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1863 | if (tty_io_error(tty)) |
1864 | return -EIO; | 1864 | return -EIO; |
1865 | return kbd_ioctl(tp->kbd, cmd, arg); | 1865 | return kbd_ioctl(tp->kbd, cmd, arg); |
1866 | } | 1866 | } |
@@ -1874,7 +1874,7 @@ static long tty3270_compat_ioctl(struct tty_struct *tty, | |||
1874 | tp = tty->driver_data; | 1874 | tp = tty->driver_data; |
1875 | if (!tp) | 1875 | if (!tp) |
1876 | return -ENODEV; | 1876 | return -ENODEV; |
1877 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1877 | if (tty_io_error(tty)) |
1878 | return -EIO; | 1878 | return -EIO; |
1879 | return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg)); | 1879 | return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg)); |
1880 | } | 1880 | } |
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index bcd2bdfb9c8f..5c221593a0c6 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c | |||
@@ -1255,7 +1255,7 @@ static int dgnc_block_til_ready(struct tty_struct *tty, | |||
1255 | if (file->f_flags & O_NONBLOCK) | 1255 | if (file->f_flags & O_NONBLOCK) |
1256 | break; | 1256 | break; |
1257 | 1257 | ||
1258 | if (tty->flags & (1 << TTY_IO_ERROR)) { | 1258 | if (tty_io_error(tty)) { |
1259 | retval = -EIO; | 1259 | retval = -EIO; |
1260 | break; | 1260 | break; |
1261 | } | 1261 | } |
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 9b23b5c95f5e..1f9389d8c152 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c | |||
@@ -1305,7 +1305,7 @@ static void fwtty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1305 | if ((baud == 0) && (old->c_cflag & CBAUD)) { | 1305 | if ((baud == 0) && (old->c_cflag & CBAUD)) { |
1306 | port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS); | 1306 | port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS); |
1307 | } else if ((baud != 0) && !(old->c_cflag & CBAUD)) { | 1307 | } else if ((baud != 0) && !(old->c_cflag & CBAUD)) { |
1308 | if (C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) | 1308 | if (C_CRTSCTS(tty) || !tty_throttled(tty)) |
1309 | port->mctrl |= TIOCM_DTR | TIOCM_RTS; | 1309 | port->mctrl |= TIOCM_DTR | TIOCM_RTS; |
1310 | else | 1310 | else |
1311 | port->mctrl |= TIOCM_DTR; | 1311 | port->mctrl |= TIOCM_DTR; |
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index 41ef099b7aa6..0149edc1e0ae 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c | |||
@@ -150,7 +150,7 @@ static void __speakup_paste_selection(struct work_struct *work) | |||
150 | add_wait_queue(&vc->paste_wait, &wait); | 150 | add_wait_queue(&vc->paste_wait, &wait); |
151 | while (sel_buffer && sel_buffer_lth > pasted) { | 151 | while (sel_buffer && sel_buffer_lth > pasted) { |
152 | set_current_state(TASK_INTERRUPTIBLE); | 152 | set_current_state(TASK_INTERRUPTIBLE); |
153 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 153 | if (tty_throttled(tty)) { |
154 | schedule(); | 154 | schedule(); |
155 | continue; | 155 | continue; |
156 | } | 156 | } |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index eacf4c9f3b29..208f573495dc 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -398,7 +398,7 @@ static void check_modem_status(struct serial_state *info) | |||
398 | wake_up_interruptible(&port->delta_msr_wait); | 398 | wake_up_interruptible(&port->delta_msr_wait); |
399 | } | 399 | } |
400 | 400 | ||
401 | if ((port->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) { | 401 | if (tty_port_check_carrier(port) && (dstatus & SER_DCD)) { |
402 | #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) | 402 | #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) |
403 | printk("ttyS%d CD now %s...", info->line, | 403 | printk("ttyS%d CD now %s...", info->line, |
404 | (!(status & SER_DCD)) ? "on" : "off"); | 404 | (!(status & SER_DCD)) ? "on" : "off"); |
@@ -525,7 +525,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info) | |||
525 | 525 | ||
526 | local_irq_save(flags); | 526 | local_irq_save(flags); |
527 | 527 | ||
528 | if (port->flags & ASYNC_INITIALIZED) { | 528 | if (tty_port_initialized(port)) { |
529 | free_page(page); | 529 | free_page(page); |
530 | goto errout; | 530 | goto errout; |
531 | } | 531 | } |
@@ -586,7 +586,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info) | |||
586 | */ | 586 | */ |
587 | change_speed(tty, info, NULL); | 587 | change_speed(tty, info, NULL); |
588 | 588 | ||
589 | port->flags |= ASYNC_INITIALIZED; | 589 | tty_port_set_initialized(port, 1); |
590 | local_irq_restore(flags); | 590 | local_irq_restore(flags); |
591 | return 0; | 591 | return 0; |
592 | 592 | ||
@@ -604,7 +604,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info) | |||
604 | unsigned long flags; | 604 | unsigned long flags; |
605 | struct serial_state *state; | 605 | struct serial_state *state; |
606 | 606 | ||
607 | if (!(info->tport.flags & ASYNC_INITIALIZED)) | 607 | if (!tty_port_initialized(&info->tport)) |
608 | return; | 608 | return; |
609 | 609 | ||
610 | state = info; | 610 | state = info; |
@@ -645,7 +645,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info) | |||
645 | 645 | ||
646 | set_bit(TTY_IO_ERROR, &tty->flags); | 646 | set_bit(TTY_IO_ERROR, &tty->flags); |
647 | 647 | ||
648 | info->tport.flags &= ~ASYNC_INITIALIZED; | 648 | tty_port_set_initialized(&info->tport, 0); |
649 | local_irq_restore(flags); | 649 | local_irq_restore(flags); |
650 | } | 650 | } |
651 | 651 | ||
@@ -727,17 +727,12 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, | |||
727 | info->IER &= ~UART_IER_MSI; | 727 | info->IER &= ~UART_IER_MSI; |
728 | if (port->flags & ASYNC_HARDPPS_CD) | 728 | if (port->flags & ASYNC_HARDPPS_CD) |
729 | info->IER |= UART_IER_MSI; | 729 | info->IER |= UART_IER_MSI; |
730 | if (cflag & CRTSCTS) { | 730 | tty_port_set_cts_flow(port, cflag & CRTSCTS); |
731 | port->flags |= ASYNC_CTS_FLOW; | 731 | if (cflag & CRTSCTS) |
732 | info->IER |= UART_IER_MSI; | 732 | info->IER |= UART_IER_MSI; |
733 | } else | 733 | tty_port_set_check_carrier(port, ~cflag & CLOCAL); |
734 | port->flags &= ~ASYNC_CTS_FLOW; | 734 | if (~cflag & CLOCAL) |
735 | if (cflag & CLOCAL) | ||
736 | port->flags &= ~ASYNC_CHECK_CD; | ||
737 | else { | ||
738 | port->flags |= ASYNC_CHECK_CD; | ||
739 | info->IER |= UART_IER_MSI; | 735 | info->IER |= UART_IER_MSI; |
740 | } | ||
741 | /* TBD: | 736 | /* TBD: |
742 | * Does clearing IER_MSI imply that we should disable the VBL interrupt ? | 737 | * Does clearing IER_MSI imply that we should disable the VBL interrupt ? |
743 | */ | 738 | */ |
@@ -1089,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
1089 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1084 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1090 | 1085 | ||
1091 | check_and_exit: | 1086 | check_and_exit: |
1092 | if (port->flags & ASYNC_INITIALIZED) { | 1087 | if (tty_port_initialized(port)) { |
1093 | if (change_spd) { | 1088 | if (change_spd) { |
1094 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 1089 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
1095 | tty->alt_speed = 57600; | 1090 | tty->alt_speed = 57600; |
@@ -1143,7 +1138,7 @@ static int rs_tiocmget(struct tty_struct *tty) | |||
1143 | 1138 | ||
1144 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) | 1139 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
1145 | return -ENODEV; | 1140 | return -ENODEV; |
1146 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1141 | if (tty_io_error(tty)) |
1147 | return -EIO; | 1142 | return -EIO; |
1148 | 1143 | ||
1149 | control = info->MCR; | 1144 | control = info->MCR; |
@@ -1165,7 +1160,7 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set, | |||
1165 | 1160 | ||
1166 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) | 1161 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
1167 | return -ENODEV; | 1162 | return -ENODEV; |
1168 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1163 | if (tty_io_error(tty)) |
1169 | return -EIO; | 1164 | return -EIO; |
1170 | 1165 | ||
1171 | local_irq_save(flags); | 1166 | local_irq_save(flags); |
@@ -1250,7 +1245,7 @@ static int rs_ioctl(struct tty_struct *tty, | |||
1250 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1245 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1251 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && | 1246 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && |
1252 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 1247 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { |
1253 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1248 | if (tty_io_error(tty)) |
1254 | return -EIO; | 1249 | return -EIO; |
1255 | } | 1250 | } |
1256 | 1251 | ||
@@ -1342,7 +1337,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1342 | /* Handle transition away from B0 status */ | 1337 | /* Handle transition away from B0 status */ |
1343 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { | 1338 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
1344 | info->MCR |= SER_DTR; | 1339 | info->MCR |= SER_DTR; |
1345 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) | 1340 | if (!C_CRTSCTS(tty) || !tty_throttled(tty)) |
1346 | info->MCR |= SER_RTS; | 1341 | info->MCR |= SER_RTS; |
1347 | local_irq_save(flags); | 1342 | local_irq_save(flags); |
1348 | rtsdtr_ctrl(info->MCR); | 1343 | rtsdtr_ctrl(info->MCR); |
@@ -1395,7 +1390,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1395 | * line status register. | 1390 | * line status register. |
1396 | */ | 1391 | */ |
1397 | state->read_status_mask &= ~UART_LSR_DR; | 1392 | state->read_status_mask &= ~UART_LSR_DR; |
1398 | if (port->flags & ASYNC_INITIALIZED) { | 1393 | if (tty_port_initialized(port)) { |
1399 | /* disable receive interrupts */ | 1394 | /* disable receive interrupts */ |
1400 | custom.intena = IF_RBF; | 1395 | custom.intena = IF_RBF; |
1401 | mb(); | 1396 | mb(); |
@@ -1495,7 +1490,7 @@ static void rs_hangup(struct tty_struct *tty) | |||
1495 | rs_flush_buffer(tty); | 1490 | rs_flush_buffer(tty); |
1496 | shutdown(tty, info); | 1491 | shutdown(tty, info); |
1497 | info->tport.count = 0; | 1492 | info->tport.count = 0; |
1498 | info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; | 1493 | tty_port_set_active(&info->tport, 0); |
1499 | info->tport.tty = NULL; | 1494 | info->tport.tty = NULL; |
1500 | wake_up_interruptible(&info->tport.open_wait); | 1495 | wake_up_interruptible(&info->tport.open_wait); |
1501 | } | 1496 | } |
@@ -1543,7 +1538,7 @@ static inline void line_info(struct seq_file *m, int line, | |||
1543 | 1538 | ||
1544 | local_irq_save(flags); | 1539 | local_irq_save(flags); |
1545 | status = ciab.pra; | 1540 | status = ciab.pra; |
1546 | control = (state->tport.flags & ASYNC_INITIALIZED) ? state->MCR : status; | 1541 | control = tty_port_initialized(&state->tport) ? state->MCR : status; |
1547 | local_irq_restore(flags); | 1542 | local_irq_restore(flags); |
1548 | 1543 | ||
1549 | stat_buf[0] = 0; | 1544 | stat_buf[0] = 0; |
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index d67e542bab1c..3840d6b421c4 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -714,7 +714,7 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, | |||
714 | wake_up_interruptible(&info->port.delta_msr_wait); | 714 | wake_up_interruptible(&info->port.delta_msr_wait); |
715 | } | 715 | } |
716 | 716 | ||
717 | if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) { | 717 | if ((mdm_change & CyDCD) && tty_port_check_carrier(&info->port)) { |
718 | if (mdm_status & CyDCD) | 718 | if (mdm_status & CyDCD) |
719 | wake_up_interruptible(&info->port.open_wait); | 719 | wake_up_interruptible(&info->port.open_wait); |
720 | else | 720 | else |
@@ -1119,7 +1119,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1119 | case C_CM_MDCD: | 1119 | case C_CM_MDCD: |
1120 | info->icount.dcd++; | 1120 | info->icount.dcd++; |
1121 | delta_count++; | 1121 | delta_count++; |
1122 | if (info->port.flags & ASYNC_CHECK_CD) { | 1122 | if (tty_port_check_carrier(&info->port)) { |
1123 | u32 dcd = fw_ver > 241 ? param : | 1123 | u32 dcd = fw_ver > 241 ? param : |
1124 | readl(&info->u.cyz.ch_ctrl->rs_status); | 1124 | readl(&info->u.cyz.ch_ctrl->rs_status); |
1125 | if (dcd & C_RS_DCD) | 1125 | if (dcd & C_RS_DCD) |
@@ -1279,7 +1279,7 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty) | |||
1279 | 1279 | ||
1280 | spin_lock_irqsave(&card->card_lock, flags); | 1280 | spin_lock_irqsave(&card->card_lock, flags); |
1281 | 1281 | ||
1282 | if (info->port.flags & ASYNC_INITIALIZED) | 1282 | if (tty_port_initialized(&info->port)) |
1283 | goto errout; | 1283 | goto errout; |
1284 | 1284 | ||
1285 | if (!info->type) { | 1285 | if (!info->type) { |
@@ -1364,7 +1364,7 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty) | |||
1364 | /* enable send, recv, modem !!! */ | 1364 | /* enable send, recv, modem !!! */ |
1365 | } | 1365 | } |
1366 | 1366 | ||
1367 | info->port.flags |= ASYNC_INITIALIZED; | 1367 | tty_port_set_initialized(&info->port, 1); |
1368 | 1368 | ||
1369 | clear_bit(TTY_IO_ERROR, &tty->flags); | 1369 | clear_bit(TTY_IO_ERROR, &tty->flags); |
1370 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 1370 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
@@ -1424,7 +1424,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1424 | struct cyclades_card *card; | 1424 | struct cyclades_card *card; |
1425 | unsigned long flags; | 1425 | unsigned long flags; |
1426 | 1426 | ||
1427 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1427 | if (!tty_port_initialized(&info->port)) |
1428 | return; | 1428 | return; |
1429 | 1429 | ||
1430 | card = info->card; | 1430 | card = info->card; |
@@ -1448,7 +1448,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1448 | some later date (after testing)!!! */ | 1448 | some later date (after testing)!!! */ |
1449 | 1449 | ||
1450 | set_bit(TTY_IO_ERROR, &tty->flags); | 1450 | set_bit(TTY_IO_ERROR, &tty->flags); |
1451 | info->port.flags &= ~ASYNC_INITIALIZED; | 1451 | tty_port_set_initialized(&info->port, 0); |
1452 | spin_unlock_irqrestore(&card->card_lock, flags); | 1452 | spin_unlock_irqrestore(&card->card_lock, flags); |
1453 | } else { | 1453 | } else { |
1454 | #ifdef CY_DEBUG_OPEN | 1454 | #ifdef CY_DEBUG_OPEN |
@@ -1473,7 +1473,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1473 | tty_port_lower_dtr_rts(&info->port); | 1473 | tty_port_lower_dtr_rts(&info->port); |
1474 | 1474 | ||
1475 | set_bit(TTY_IO_ERROR, &tty->flags); | 1475 | set_bit(TTY_IO_ERROR, &tty->flags); |
1476 | info->port.flags &= ~ASYNC_INITIALIZED; | 1476 | tty_port_set_initialized(&info->port, 0); |
1477 | 1477 | ||
1478 | spin_unlock_irqrestore(&card->card_lock, flags); | 1478 | spin_unlock_irqrestore(&card->card_lock, flags); |
1479 | } | 1479 | } |
@@ -1711,7 +1711,7 @@ static void cy_do_close(struct tty_port *port) | |||
1711 | /* Stop accepting input */ | 1711 | /* Stop accepting input */ |
1712 | cyy_writeb(info, CyCAR, channel & 0x03); | 1712 | cyy_writeb(info, CyCAR, channel & 0x03); |
1713 | cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData); | 1713 | cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData); |
1714 | if (info->port.flags & ASYNC_INITIALIZED) { | 1714 | if (tty_port_initialized(&info->port)) { |
1715 | /* Waiting for on-board buffers to be empty before | 1715 | /* Waiting for on-board buffers to be empty before |
1716 | closing the port */ | 1716 | closing the port */ |
1717 | spin_unlock_irqrestore(&card->card_lock, flags); | 1717 | spin_unlock_irqrestore(&card->card_lock, flags); |
@@ -2083,17 +2083,12 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) | |||
2083 | info->cor1 |= CyPARITY_NONE; | 2083 | info->cor1 |= CyPARITY_NONE; |
2084 | 2084 | ||
2085 | /* CTS flow control flag */ | 2085 | /* CTS flow control flag */ |
2086 | if (cflag & CRTSCTS) { | 2086 | tty_port_set_cts_flow(&info->port, cflag & CRTSCTS); |
2087 | info->port.flags |= ASYNC_CTS_FLOW; | 2087 | if (cflag & CRTSCTS) |
2088 | info->cor2 |= CyCtsAE; | 2088 | info->cor2 |= CyCtsAE; |
2089 | } else { | ||
2090 | info->port.flags &= ~ASYNC_CTS_FLOW; | ||
2091 | info->cor2 &= ~CyCtsAE; | ||
2092 | } | ||
2093 | if (cflag & CLOCAL) | ||
2094 | info->port.flags &= ~ASYNC_CHECK_CD; | ||
2095 | else | 2089 | else |
2096 | info->port.flags |= ASYNC_CHECK_CD; | 2090 | info->cor2 &= ~CyCtsAE; |
2091 | tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL); | ||
2097 | 2092 | ||
2098 | /*********************************************** | 2093 | /*********************************************** |
2099 | The hardware option, CyRtsAO, presents RTS when | 2094 | The hardware option, CyRtsAO, presents RTS when |
@@ -2234,7 +2229,7 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) | |||
2234 | } | 2229 | } |
2235 | /* As the HW flow control is done in firmware, the driver | 2230 | /* As the HW flow control is done in firmware, the driver |
2236 | doesn't need to care about it */ | 2231 | doesn't need to care about it */ |
2237 | info->port.flags &= ~ASYNC_CTS_FLOW; | 2232 | tty_port_set_cts_flow(&info->port, 0); |
2238 | 2233 | ||
2239 | /* XON/XOFF/XANY flow control flags */ | 2234 | /* XON/XOFF/XANY flow control flags */ |
2240 | sw_flow = 0; | 2235 | sw_flow = 0; |
@@ -2252,10 +2247,7 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) | |||
2252 | } | 2247 | } |
2253 | 2248 | ||
2254 | /* CD sensitivity */ | 2249 | /* CD sensitivity */ |
2255 | if (cflag & CLOCAL) | 2250 | tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL); |
2256 | info->port.flags &= ~ASYNC_CHECK_CD; | ||
2257 | else | ||
2258 | info->port.flags |= ASYNC_CHECK_CD; | ||
2259 | 2251 | ||
2260 | if (baud == 0) { /* baud rate is zero, turn off line */ | 2252 | if (baud == 0) { /* baud rate is zero, turn off line */ |
2261 | cy_writel(&ch_ctrl->rs_control, | 2253 | cy_writel(&ch_ctrl->rs_control, |
@@ -2342,7 +2334,7 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, | |||
2342 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; | 2334 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; |
2343 | 2335 | ||
2344 | check_and_exit: | 2336 | check_and_exit: |
2345 | if (info->port.flags & ASYNC_INITIALIZED) { | 2337 | if (tty_port_initialized(&info->port)) { |
2346 | cy_set_line_char(info, tty); | 2338 | cy_set_line_char(info, tty); |
2347 | ret = 0; | 2339 | ret = 0; |
2348 | } else { | 2340 | } else { |
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index e46d628998f5..ce864875330e 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
@@ -632,7 +632,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
632 | goto bail; | 632 | goto bail; |
633 | 633 | ||
634 | /* Now check if we can get data (are we throttled ?) */ | 634 | /* Now check if we can get data (are we throttled ?) */ |
635 | if (test_bit(TTY_THROTTLED, &tty->flags)) | 635 | if (tty_throttled(tty)) |
636 | goto throttled; | 636 | goto throttled; |
637 | 637 | ||
638 | /* If we aren't notifier driven and aren't throttled, we always | 638 | /* If we aren't notifier driven and aren't throttled, we always |
@@ -814,7 +814,7 @@ static int hvc_poll_get_char(struct tty_driver *driver, int line) | |||
814 | 814 | ||
815 | n = hp->ops->get_chars(hp->vtermno, &ch, 1); | 815 | n = hp->ops->get_chars(hp->vtermno, &ch, 1); |
816 | 816 | ||
817 | if (n == 0) | 817 | if (n <= 0) |
818 | return NO_POLL_CHAR; | 818 | return NO_POLL_CHAR; |
819 | 819 | ||
820 | return ch; | 820 | return ch; |
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 5997b1731111..3c4d7c2b4ade 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
@@ -600,7 +600,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
600 | 600 | ||
601 | hvcs_try_write(hvcsd); | 601 | hvcs_try_write(hvcsd); |
602 | 602 | ||
603 | if (!tty || test_bit(TTY_THROTTLED, &tty->flags)) { | 603 | if (!tty || tty_throttled(tty)) { |
604 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); | 604 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); |
605 | goto bail; | 605 | goto bail; |
606 | } else if (!(hvcsd->todo_mask & (HVCS_READ_MASK))) | 606 | } else if (!(hvcsd->todo_mask & (HVCS_READ_MASK))) |
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index a75146f600cb..96ce6bd1cc6f 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c | |||
@@ -509,7 +509,7 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg) | |||
509 | } | 509 | } |
510 | 510 | ||
511 | spin_lock_irqsave(&hp->lock, flags); | 511 | spin_lock_irqsave(&hp->lock, flags); |
512 | if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) { | 512 | if (tty && hp->n_throttle && !tty_throttled(tty)) { |
513 | /* we weren't hung up and we weren't throttled, so we can | 513 | /* we weren't hung up and we weren't throttled, so we can |
514 | * deliver the rest now */ | 514 | * deliver the rest now */ |
515 | hvsi_send_overflow(hp); | 515 | hvsi_send_overflow(hp); |
diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index ad7031a4f3c4..df0204b6148f 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c | |||
@@ -1572,6 +1572,11 @@ static void handle_received_SETUP_packet(struct ipw_hardware *hw, | |||
1572 | sizeof(struct ipw_setup_reboot_msg_ack), | 1572 | sizeof(struct ipw_setup_reboot_msg_ack), |
1573 | ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP, | 1573 | ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP, |
1574 | TL_SETUP_SIGNO_REBOOT_MSG_ACK); | 1574 | TL_SETUP_SIGNO_REBOOT_MSG_ACK); |
1575 | if (!packet) { | ||
1576 | pr_err(IPWIRELESS_PCCARD_NAME | ||
1577 | ": Not enough memory to send reboot packet"); | ||
1578 | break; | ||
1579 | } | ||
1575 | packet->header.length = | 1580 | packet->header.length = |
1576 | sizeof(struct TlSetupRebootMsgAck); | 1581 | sizeof(struct TlSetupRebootMsgAck); |
1577 | send_packet(hw, PRIO_SETUP, &packet->header); | 1582 | send_packet(hw, PRIO_SETUP, &packet->header); |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 8bf67630018b..b70187b46d9d 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
@@ -438,8 +438,8 @@ static void isicom_tx(unsigned long _data) | |||
438 | 438 | ||
439 | for (; count > 0; count--, port++) { | 439 | for (; count > 0; count--, port++) { |
440 | /* port not active or tx disabled to force flow control */ | 440 | /* port not active or tx disabled to force flow control */ |
441 | if (!(port->port.flags & ASYNC_INITIALIZED) || | 441 | if (!tty_port_initialized(&port->port) || |
442 | !(port->status & ISI_TXOK)) | 442 | !(port->status & ISI_TXOK)) |
443 | continue; | 443 | continue; |
444 | 444 | ||
445 | txcount = min_t(short, TX_SIZE, port->xmit_cnt); | 445 | txcount = min_t(short, TX_SIZE, port->xmit_cnt); |
@@ -553,7 +553,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
553 | return IRQ_HANDLED; | 553 | return IRQ_HANDLED; |
554 | } | 554 | } |
555 | port = card->ports + channel; | 555 | port = card->ports + channel; |
556 | if (!(port->port.flags & ASYNC_INITIALIZED)) { | 556 | if (!tty_port_initialized(&port->port)) { |
557 | outw(0x0000, base+0x04); /* enable interrupts */ | 557 | outw(0x0000, base+0x04); /* enable interrupts */ |
558 | spin_unlock(&card->card_lock); | 558 | spin_unlock(&card->card_lock); |
559 | return IRQ_HANDLED; | 559 | return IRQ_HANDLED; |
@@ -577,7 +577,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
577 | header = inw(base); | 577 | header = inw(base); |
578 | switch (header & 0xff) { | 578 | switch (header & 0xff) { |
579 | case 0: /* Change in EIA signals */ | 579 | case 0: /* Change in EIA signals */ |
580 | if (port->port.flags & ASYNC_CHECK_CD) { | 580 | if (tty_port_check_carrier(&port->port)) { |
581 | if (port->status & ISI_DCD) { | 581 | if (port->status & ISI_DCD) { |
582 | if (!(header & ISI_DCD)) { | 582 | if (!(header & ISI_DCD)) { |
583 | /* Carrier has been lost */ | 583 | /* Carrier has been lost */ |
@@ -758,18 +758,13 @@ static void isicom_config_port(struct tty_struct *tty) | |||
758 | outw(channel_setup, base); | 758 | outw(channel_setup, base); |
759 | InterruptTheCard(base); | 759 | InterruptTheCard(base); |
760 | } | 760 | } |
761 | if (C_CLOCAL(tty)) | 761 | tty_port_set_check_carrier(&port->port, !C_CLOCAL(tty)); |
762 | port->port.flags &= ~ASYNC_CHECK_CD; | ||
763 | else | ||
764 | port->port.flags |= ASYNC_CHECK_CD; | ||
765 | 762 | ||
766 | /* flow control settings ...*/ | 763 | /* flow control settings ...*/ |
767 | flow_ctrl = 0; | 764 | flow_ctrl = 0; |
768 | port->port.flags &= ~ASYNC_CTS_FLOW; | 765 | tty_port_set_cts_flow(&port->port, C_CRTSCTS(tty)); |
769 | if (C_CRTSCTS(tty)) { | 766 | if (C_CRTSCTS(tty)) |
770 | port->port.flags |= ASYNC_CTS_FLOW; | ||
771 | flow_ctrl |= ISICOM_CTSRTS; | 767 | flow_ctrl |= ISICOM_CTSRTS; |
772 | } | ||
773 | if (I_IXON(tty)) | 768 | if (I_IXON(tty)) |
774 | flow_ctrl |= ISICOM_RESPOND_XONXOFF; | 769 | flow_ctrl |= ISICOM_RESPOND_XONXOFF; |
775 | if (I_IXOFF(tty)) | 770 | if (I_IXOFF(tty)) |
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 92982d7c0489..60d37b225589 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
@@ -912,7 +912,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
912 | 912 | ||
913 | /* pci hot-un-plug support */ | 913 | /* pci hot-un-plug support */ |
914 | for (a = 0; a < brd->numPorts; a++) | 914 | for (a = 0; a < brd->numPorts; a++) |
915 | if (brd->ports[a].port.flags & ASYNC_INITIALIZED) | 915 | if (tty_port_initialized(&brd->ports[a].port)) |
916 | tty_port_tty_hangup(&brd->ports[a].port, false); | 916 | tty_port_tty_hangup(&brd->ports[a].port, false); |
917 | 917 | ||
918 | for (a = 0; a < MAX_PORTS_PER_BOARD; a++) | 918 | for (a = 0; a < MAX_PORTS_PER_BOARD; a++) |
@@ -921,7 +921,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
921 | while (1) { | 921 | while (1) { |
922 | opened = 0; | 922 | opened = 0; |
923 | for (a = 0; a < brd->numPorts; a++) | 923 | for (a = 0; a < brd->numPorts; a++) |
924 | if (brd->ports[a].port.flags & ASYNC_INITIALIZED) | 924 | if (tty_port_initialized(&brd->ports[a].port)) |
925 | opened++; | 925 | opened++; |
926 | mutex_unlock(&moxa_openlock); | 926 | mutex_unlock(&moxa_openlock); |
927 | if (!opened) | 927 | if (!opened) |
@@ -1192,13 +1192,13 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1192 | tty->driver_data = ch; | 1192 | tty->driver_data = ch; |
1193 | tty_port_tty_set(&ch->port, tty); | 1193 | tty_port_tty_set(&ch->port, tty); |
1194 | mutex_lock(&ch->port.mutex); | 1194 | mutex_lock(&ch->port.mutex); |
1195 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { | 1195 | if (!tty_port_initialized(&ch->port)) { |
1196 | ch->statusflags = 0; | 1196 | ch->statusflags = 0; |
1197 | moxa_set_tty_param(tty, &tty->termios); | 1197 | moxa_set_tty_param(tty, &tty->termios); |
1198 | MoxaPortLineCtrl(ch, 1, 1); | 1198 | MoxaPortLineCtrl(ch, 1, 1); |
1199 | MoxaPortEnable(ch); | 1199 | MoxaPortEnable(ch); |
1200 | MoxaSetFifo(ch, ch->type == PORT_16550A); | 1200 | MoxaSetFifo(ch, ch->type == PORT_16550A); |
1201 | ch->port.flags |= ASYNC_INITIALIZED; | 1201 | tty_port_set_initialized(&ch->port, 1); |
1202 | } | 1202 | } |
1203 | mutex_unlock(&ch->port.mutex); | 1203 | mutex_unlock(&ch->port.mutex); |
1204 | mutex_unlock(&moxa_openlock); | 1204 | mutex_unlock(&moxa_openlock); |
@@ -1379,7 +1379,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1379 | { | 1379 | { |
1380 | struct tty_struct *tty = tty_port_tty_get(&p->port); | 1380 | struct tty_struct *tty = tty_port_tty_get(&p->port); |
1381 | void __iomem *ofsAddr; | 1381 | void __iomem *ofsAddr; |
1382 | unsigned int inited = p->port.flags & ASYNC_INITIALIZED; | 1382 | unsigned int inited = tty_port_initialized(&p->port); |
1383 | u16 intr; | 1383 | u16 intr; |
1384 | 1384 | ||
1385 | if (tty) { | 1385 | if (tty) { |
@@ -1394,7 +1394,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1394 | tty_wakeup(tty); | 1394 | tty_wakeup(tty); |
1395 | } | 1395 | } |
1396 | 1396 | ||
1397 | if (inited && !test_bit(TTY_THROTTLED, &tty->flags) && | 1397 | if (inited && !tty_throttled(tty) && |
1398 | MoxaPortRxQueue(p) > 0) { /* RX */ | 1398 | MoxaPortRxQueue(p) > 0) { /* RX */ |
1399 | MoxaPortReadData(p); | 1399 | MoxaPortReadData(p); |
1400 | tty_schedule_flip(&p->port); | 1400 | tty_schedule_flip(&p->port); |
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 2f12bb9f4336..98d2bd16706d 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -711,8 +711,8 @@ static int mxser_change_speed(struct tty_struct *tty, | |||
711 | /* CTS flow control flag and modem status interrupts */ | 711 | /* CTS flow control flag and modem status interrupts */ |
712 | info->IER &= ~UART_IER_MSI; | 712 | info->IER &= ~UART_IER_MSI; |
713 | info->MCR &= ~UART_MCR_AFE; | 713 | info->MCR &= ~UART_MCR_AFE; |
714 | tty_port_set_cts_flow(&info->port, cflag & CRTSCTS); | ||
714 | if (cflag & CRTSCTS) { | 715 | if (cflag & CRTSCTS) { |
715 | info->port.flags |= ASYNC_CTS_FLOW; | ||
716 | info->IER |= UART_IER_MSI; | 716 | info->IER |= UART_IER_MSI; |
717 | if ((info->type == PORT_16550A) || (info->board->chip_flag)) { | 717 | if ((info->type == PORT_16550A) || (info->board->chip_flag)) { |
718 | info->MCR |= UART_MCR_AFE; | 718 | info->MCR |= UART_MCR_AFE; |
@@ -744,16 +744,11 @@ static int mxser_change_speed(struct tty_struct *tty, | |||
744 | } | 744 | } |
745 | } | 745 | } |
746 | } | 746 | } |
747 | } else { | ||
748 | info->port.flags &= ~ASYNC_CTS_FLOW; | ||
749 | } | 747 | } |
750 | outb(info->MCR, info->ioaddr + UART_MCR); | 748 | outb(info->MCR, info->ioaddr + UART_MCR); |
751 | if (cflag & CLOCAL) { | 749 | tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL); |
752 | info->port.flags &= ~ASYNC_CHECK_CD; | 750 | if (~cflag & CLOCAL) |
753 | } else { | ||
754 | info->port.flags |= ASYNC_CHECK_CD; | ||
755 | info->IER |= UART_IER_MSI; | 751 | info->IER |= UART_IER_MSI; |
756 | } | ||
757 | outb(info->IER, info->ioaddr + UART_IER); | 752 | outb(info->IER, info->ioaddr + UART_IER); |
758 | 753 | ||
759 | /* | 754 | /* |
@@ -826,7 +821,7 @@ static void mxser_check_modem_status(struct tty_struct *tty, | |||
826 | port->mon_data.modem_status = status; | 821 | port->mon_data.modem_status = status; |
827 | wake_up_interruptible(&port->port.delta_msr_wait); | 822 | wake_up_interruptible(&port->port.delta_msr_wait); |
828 | 823 | ||
829 | if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { | 824 | if (tty_port_check_carrier(&port->port) && (status & UART_MSR_DDCD)) { |
830 | if (status & UART_MSR_DCD) | 825 | if (status & UART_MSR_DCD) |
831 | wake_up_interruptible(&port->port.open_wait); | 826 | wake_up_interruptible(&port->port.open_wait); |
832 | } | 827 | } |
@@ -1086,12 +1081,10 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1086 | mutex_lock(&port->mutex); | 1081 | mutex_lock(&port->mutex); |
1087 | mxser_close_port(port); | 1082 | mxser_close_port(port); |
1088 | mxser_flush_buffer(tty); | 1083 | mxser_flush_buffer(tty); |
1089 | if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { | 1084 | if (tty_port_initialized(port) && C_HUPCL(tty)) |
1090 | if (C_HUPCL(tty)) | 1085 | tty_port_lower_dtr_rts(port); |
1091 | tty_port_lower_dtr_rts(port); | ||
1092 | } | ||
1093 | mxser_shutdown_port(port); | 1086 | mxser_shutdown_port(port); |
1094 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | 1087 | tty_port_set_initialized(port, 0); |
1095 | mutex_unlock(&port->mutex); | 1088 | mutex_unlock(&port->mutex); |
1096 | info->closing = 0; | 1089 | info->closing = 0; |
1097 | /* Right now the tty_port set is done outside of the close_end helper | 1090 | /* Right now the tty_port set is done outside of the close_end helper |
@@ -1287,7 +1280,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1287 | 1280 | ||
1288 | process_txrx_fifo(info); | 1281 | process_txrx_fifo(info); |
1289 | 1282 | ||
1290 | if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { | 1283 | if (tty_port_initialized(port)) { |
1291 | if (flags != (port->flags & ASYNC_SPD_MASK)) { | 1284 | if (flags != (port->flags & ASYNC_SPD_MASK)) { |
1292 | spin_lock_irqsave(&info->slock, sl_flags); | 1285 | spin_lock_irqsave(&info->slock, sl_flags); |
1293 | mxser_change_speed(tty, NULL); | 1286 | mxser_change_speed(tty, NULL); |
@@ -1296,7 +1289,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1296 | } else { | 1289 | } else { |
1297 | retval = mxser_activate(port, tty); | 1290 | retval = mxser_activate(port, tty); |
1298 | if (retval == 0) | 1291 | if (retval == 0) |
1299 | set_bit(ASYNCB_INITIALIZED, &port->flags); | 1292 | tty_port_set_initialized(port, 1); |
1300 | } | 1293 | } |
1301 | return retval; | 1294 | return retval; |
1302 | } | 1295 | } |
@@ -1334,7 +1327,7 @@ static int mxser_tiocmget(struct tty_struct *tty) | |||
1334 | 1327 | ||
1335 | if (tty->index == MXSER_PORTS) | 1328 | if (tty->index == MXSER_PORTS) |
1336 | return -ENOIOCTLCMD; | 1329 | return -ENOIOCTLCMD; |
1337 | if (test_bit(TTY_IO_ERROR, &tty->flags)) | 1330 | if (tty_io_error(tty)) |
1338 | return -EIO; | 1331 | return -EIO; |
1339 | 1332 | ||
1340 | control = info->MCR; | 1333 | control = info->MCR; |
@@ -1361,7 +1354,7 @@ static int mxser_tiocmset(struct tty_struct *tty, | |||
1361 | 1354 | ||
1362 | if (tty->index == MXSER_PORTS) | 1355 | if (tty->index == MXSER_PORTS) |
1363 | return -ENOIOCTLCMD; | 1356 | return -ENOIOCTLCMD; |
1364 | if (test_bit(TTY_IO_ERROR, &tty->flags)) | 1357 | if (tty_io_error(tty)) |
1365 | return -EIO; | 1358 | return -EIO; |
1366 | 1359 | ||
1367 | spin_lock_irqsave(&info->slock, flags); | 1360 | spin_lock_irqsave(&info->slock, flags); |
@@ -1715,8 +1708,7 @@ static int mxser_ioctl(struct tty_struct *tty, | |||
1715 | return 0; | 1708 | return 0; |
1716 | } | 1709 | } |
1717 | 1710 | ||
1718 | if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && | 1711 | if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && tty_io_error(tty)) |
1719 | test_bit(TTY_IO_ERROR, &tty->flags)) | ||
1720 | return -EIO; | 1712 | return -EIO; |
1721 | 1713 | ||
1722 | switch (cmd) { | 1714 | switch (cmd) { |
@@ -2257,7 +2249,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2257 | iir &= MOXA_MUST_IIR_MASK; | 2249 | iir &= MOXA_MUST_IIR_MASK; |
2258 | tty = tty_port_tty_get(&port->port); | 2250 | tty = tty_port_tty_get(&port->port); |
2259 | if (!tty || port->closing || | 2251 | if (!tty || port->closing || |
2260 | !(port->port.flags & ASYNC_INITIALIZED)) { | 2252 | !tty_port_initialized(&port->port)) { |
2261 | status = inb(port->ioaddr + UART_LSR); | 2253 | status = inb(port->ioaddr + UART_LSR); |
2262 | outb(0x27, port->ioaddr + UART_FCR); | 2254 | outb(0x27, port->ioaddr + UART_FCR); |
2263 | inb(port->ioaddr + UART_MSR); | 2255 | inb(port->ioaddr + UART_MSR); |
@@ -2400,7 +2392,6 @@ static int mxser_initbrd(struct mxser_board *brd, | |||
2400 | if (brd->chip_flag != MOXA_OTHER_UART) | 2392 | if (brd->chip_flag != MOXA_OTHER_UART) |
2401 | mxser_enable_must_enchance_mode(info->ioaddr); | 2393 | mxser_enable_must_enchance_mode(info->ioaddr); |
2402 | 2394 | ||
2403 | info->port.flags = ASYNC_SHARE_IRQ; | ||
2404 | info->type = brd->uart_type; | 2395 | info->type = brd->uart_type; |
2405 | 2396 | ||
2406 | process_txrx_fifo(info); | 2397 | process_txrx_fifo(info); |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 0c27a00ab42d..54cab59e20ed 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -2045,7 +2045,9 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
2045 | } | 2045 | } |
2046 | } | 2046 | } |
2047 | spin_unlock(&gsm_mux_lock); | 2047 | spin_unlock(&gsm_mux_lock); |
2048 | WARN_ON(i == MAX_MUX); | 2048 | /* open failed before registering => nothing to do */ |
2049 | if (i == MAX_MUX) | ||
2050 | return; | ||
2049 | 2051 | ||
2050 | /* In theory disconnecting DLCI 0 is sufficient but for some | 2052 | /* In theory disconnecting DLCI 0 is sufficient but for some |
2051 | modems this is apparently not the case. */ | 2053 | modems this is apparently not the case. */ |
@@ -2947,7 +2949,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) | |||
2947 | dlci->modem_rx = 0; | 2949 | dlci->modem_rx = 0; |
2948 | /* We could in theory open and close before we wait - eg if we get | 2950 | /* We could in theory open and close before we wait - eg if we get |
2949 | a DM straight back. This is ok as that will have caused a hangup */ | 2951 | a DM straight back. This is ok as that will have caused a hangup */ |
2950 | set_bit(ASYNCB_INITIALIZED, &port->flags); | 2952 | tty_port_set_initialized(port, 1); |
2951 | /* Start sending off SABM messages */ | 2953 | /* Start sending off SABM messages */ |
2952 | gsm_dlci_begin_open(dlci); | 2954 | gsm_dlci_begin_open(dlci); |
2953 | /* And wait for virtual carrier */ | 2955 | /* And wait for virtual carrier */ |
@@ -2970,10 +2972,8 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) | |||
2970 | if (tty_port_close_start(&dlci->port, tty, filp) == 0) | 2972 | if (tty_port_close_start(&dlci->port, tty, filp) == 0) |
2971 | return; | 2973 | return; |
2972 | gsm_dlci_begin_close(dlci); | 2974 | gsm_dlci_begin_close(dlci); |
2973 | if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { | 2975 | if (tty_port_initialized(&dlci->port) && C_HUPCL(tty)) |
2974 | if (C_HUPCL(tty)) | 2976 | tty_port_lower_dtr_rts(&dlci->port); |
2975 | tty_port_lower_dtr_rts(&dlci->port); | ||
2976 | } | ||
2977 | tty_port_close_end(&dlci->port, tty); | 2977 | tty_port_close_end(&dlci->port, tty); |
2978 | tty_port_tty_set(&dlci->port, NULL); | 2978 | tty_port_tty_set(&dlci->port, NULL); |
2979 | return; | 2979 | return; |
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index bcaba17688f6..a7fa016f31eb 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c | |||
@@ -599,7 +599,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
599 | add_wait_queue(&tty->read_wait, &wait); | 599 | add_wait_queue(&tty->read_wait, &wait); |
600 | 600 | ||
601 | for (;;) { | 601 | for (;;) { |
602 | if (test_bit(TTY_OTHER_DONE, &tty->flags)) { | 602 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { |
603 | ret = -EIO; | 603 | ret = -EIO; |
604 | break; | 604 | break; |
605 | } | 605 | } |
@@ -827,7 +827,7 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp, | |||
827 | /* set bits for operations that won't block */ | 827 | /* set bits for operations that won't block */ |
828 | if (n_hdlc->rx_buf_list.head) | 828 | if (n_hdlc->rx_buf_list.head) |
829 | mask |= POLLIN | POLLRDNORM; /* readable */ | 829 | mask |= POLLIN | POLLRDNORM; /* readable */ |
830 | if (test_bit(TTY_OTHER_DONE, &tty->flags)) | 830 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) |
831 | mask |= POLLHUP; | 831 | mask |= POLLHUP; |
832 | if (tty_hung_up_p(filp)) | 832 | if (tty_hung_up_p(filp)) |
833 | mask |= POLLHUP; | 833 | mask |= POLLHUP; |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index fb76a7d80e7e..bdf0e6e89991 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -1917,18 +1917,6 @@ static inline int input_available_p(struct tty_struct *tty, int poll) | |||
1917 | return ldata->commit_head - ldata->read_tail >= amt; | 1917 | return ldata->commit_head - ldata->read_tail >= amt; |
1918 | } | 1918 | } |
1919 | 1919 | ||
1920 | static inline int check_other_done(struct tty_struct *tty) | ||
1921 | { | ||
1922 | int done = test_bit(TTY_OTHER_DONE, &tty->flags); | ||
1923 | if (done) { | ||
1924 | /* paired with cmpxchg() in check_other_closed(); ensures | ||
1925 | * read buffer head index is not stale | ||
1926 | */ | ||
1927 | smp_mb__after_atomic(); | ||
1928 | } | ||
1929 | return done; | ||
1930 | } | ||
1931 | |||
1932 | /** | 1920 | /** |
1933 | * copy_from_read_buf - copy read data directly | 1921 | * copy_from_read_buf - copy read data directly |
1934 | * @tty: terminal device | 1922 | * @tty: terminal device |
@@ -2124,7 +2112,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2124 | struct n_tty_data *ldata = tty->disc_data; | 2112 | struct n_tty_data *ldata = tty->disc_data; |
2125 | unsigned char __user *b = buf; | 2113 | unsigned char __user *b = buf; |
2126 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | 2114 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
2127 | int c, done; | 2115 | int c; |
2128 | int minimum, time; | 2116 | int minimum, time; |
2129 | ssize_t retval = 0; | 2117 | ssize_t retval = 0; |
2130 | long timeout; | 2118 | long timeout; |
@@ -2183,32 +2171,35 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2183 | break; | 2171 | break; |
2184 | } | 2172 | } |
2185 | 2173 | ||
2186 | done = check_other_done(tty); | ||
2187 | |||
2188 | if (!input_available_p(tty, 0)) { | 2174 | if (!input_available_p(tty, 0)) { |
2189 | if (done) { | ||
2190 | retval = -EIO; | ||
2191 | break; | ||
2192 | } | ||
2193 | if (tty_hung_up_p(file)) | ||
2194 | break; | ||
2195 | if (!timeout) | ||
2196 | break; | ||
2197 | if (file->f_flags & O_NONBLOCK) { | ||
2198 | retval = -EAGAIN; | ||
2199 | break; | ||
2200 | } | ||
2201 | if (signal_pending(current)) { | ||
2202 | retval = -ERESTARTSYS; | ||
2203 | break; | ||
2204 | } | ||
2205 | up_read(&tty->termios_rwsem); | 2175 | up_read(&tty->termios_rwsem); |
2176 | tty_buffer_flush_work(tty->port); | ||
2177 | down_read(&tty->termios_rwsem); | ||
2178 | if (!input_available_p(tty, 0)) { | ||
2179 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { | ||
2180 | retval = -EIO; | ||
2181 | break; | ||
2182 | } | ||
2183 | if (tty_hung_up_p(file)) | ||
2184 | break; | ||
2185 | if (!timeout) | ||
2186 | break; | ||
2187 | if (file->f_flags & O_NONBLOCK) { | ||
2188 | retval = -EAGAIN; | ||
2189 | break; | ||
2190 | } | ||
2191 | if (signal_pending(current)) { | ||
2192 | retval = -ERESTARTSYS; | ||
2193 | break; | ||
2194 | } | ||
2195 | up_read(&tty->termios_rwsem); | ||
2206 | 2196 | ||
2207 | timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, | 2197 | timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, |
2208 | timeout); | 2198 | timeout); |
2209 | 2199 | ||
2210 | down_read(&tty->termios_rwsem); | 2200 | down_read(&tty->termios_rwsem); |
2211 | continue; | 2201 | continue; |
2202 | } | ||
2212 | } | 2203 | } |
2213 | 2204 | ||
2214 | if (ldata->icanon && !L_EXTPROC(tty)) { | 2205 | if (ldata->icanon && !L_EXTPROC(tty)) { |
@@ -2386,12 +2377,17 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, | |||
2386 | 2377 | ||
2387 | poll_wait(file, &tty->read_wait, wait); | 2378 | poll_wait(file, &tty->read_wait, wait); |
2388 | poll_wait(file, &tty->write_wait, wait); | 2379 | poll_wait(file, &tty->write_wait, wait); |
2389 | if (check_other_done(tty)) | ||
2390 | mask |= POLLHUP; | ||
2391 | if (input_available_p(tty, 1)) | 2380 | if (input_available_p(tty, 1)) |
2392 | mask |= POLLIN | POLLRDNORM; | 2381 | mask |= POLLIN | POLLRDNORM; |
2382 | else { | ||
2383 | tty_buffer_flush_work(tty->port); | ||
2384 | if (input_available_p(tty, 1)) | ||
2385 | mask |= POLLIN | POLLRDNORM; | ||
2386 | } | ||
2393 | if (tty->packet && tty->link->ctrl_status) | 2387 | if (tty->packet && tty->link->ctrl_status) |
2394 | mask |= POLLPRI | POLLIN | POLLRDNORM; | 2388 | mask |= POLLPRI | POLLIN | POLLRDNORM; |
2389 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | ||
2390 | mask |= POLLHUP; | ||
2395 | if (tty_hung_up_p(file)) | 2391 | if (tty_hung_up_p(file)) |
2396 | mask |= POLLHUP; | 2392 | mask |= POLLHUP; |
2397 | if (tty->ops->write && !tty_is_writelocked(tty) && | 2393 | if (tty->ops->write && !tty_is_writelocked(tty) && |
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 5cc80b80c82b..d6fd0e802ef5 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -826,7 +826,7 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
826 | size = __le32_to_cpu(readl(addr)); | 826 | size = __le32_to_cpu(readl(addr)); |
827 | /* DBG1( "%d bytes port: %d", size, index); */ | 827 | /* DBG1( "%d bytes port: %d", size, index); */ |
828 | 828 | ||
829 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { | 829 | if (tty && tty_throttled(tty)) { |
830 | DBG1("No room in tty, don't read data, don't ack interrupt, " | 830 | DBG1("No room in tty, don't read data, don't ack interrupt, " |
831 | "disable interrupt"); | 831 | "disable interrupt"); |
832 | 832 | ||
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index cf0dc51a2690..dd4b8417e7f4 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -44,7 +44,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
44 | if (tty->driver->subtype == PTY_TYPE_MASTER) | 44 | if (tty->driver->subtype == PTY_TYPE_MASTER) |
45 | WARN_ON(tty->count > 1); | 45 | WARN_ON(tty->count > 1); |
46 | else { | 46 | else { |
47 | if (test_bit(TTY_IO_ERROR, &tty->flags)) | 47 | if (tty_io_error(tty)) |
48 | return; | 48 | return; |
49 | if (tty->count > 2) | 49 | if (tty->count > 2) |
50 | return; | 50 | return; |
@@ -59,7 +59,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
59 | if (!tty->link) | 59 | if (!tty->link) |
60 | return; | 60 | return; |
61 | set_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 61 | set_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
62 | tty_flip_buffer_push(tty->link->port); | 62 | wake_up_interruptible(&tty->link->read_wait); |
63 | wake_up_interruptible(&tty->link->write_wait); | 63 | wake_up_interruptible(&tty->link->write_wait); |
64 | if (tty->driver->subtype == PTY_TYPE_MASTER) { | 64 | if (tty->driver->subtype == PTY_TYPE_MASTER) { |
65 | set_bit(TTY_OTHER_CLOSED, &tty->flags); | 65 | set_bit(TTY_OTHER_CLOSED, &tty->flags); |
@@ -247,9 +247,7 @@ static int pty_open(struct tty_struct *tty, struct file *filp) | |||
247 | goto out; | 247 | goto out; |
248 | 248 | ||
249 | clear_bit(TTY_IO_ERROR, &tty->flags); | 249 | clear_bit(TTY_IO_ERROR, &tty->flags); |
250 | /* TTY_OTHER_CLOSED must be cleared before TTY_OTHER_DONE */ | ||
251 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 250 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
252 | clear_bit(TTY_OTHER_DONE, &tty->link->flags); | ||
253 | set_bit(TTY_THROTTLED, &tty->flags); | 251 | set_bit(TTY_THROTTLED, &tty->flags); |
254 | return 0; | 252 | return 0; |
255 | 253 | ||
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 0b802cdd70d0..b0cc47c77b40 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -495,7 +495,7 @@ static void rp_handle_port(struct r_port *info) | |||
495 | if (!info) | 495 | if (!info) |
496 | return; | 496 | return; |
497 | 497 | ||
498 | if ((info->port.flags & ASYNC_INITIALIZED) == 0) { | 498 | if (!tty_port_initialized(&info->port)) { |
499 | printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " | 499 | printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " |
500 | "info->flags & NOT_INIT\n"); | 500 | "info->flags & NOT_INIT\n"); |
501 | return; | 501 | return; |
@@ -615,7 +615,8 @@ static void rp_do_poll(unsigned long dummy) | |||
615 | * the board. | 615 | * the board. |
616 | * Inputs: board, aiop, chan numbers | 616 | * Inputs: board, aiop, chan numbers |
617 | */ | 617 | */ |
618 | static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | 618 | static void __init |
619 | init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | ||
619 | { | 620 | { |
620 | unsigned rocketMode; | 621 | unsigned rocketMode; |
621 | struct r_port *info; | 622 | struct r_port *info; |
@@ -920,7 +921,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
920 | /* | 921 | /* |
921 | * Info->count is now 1; so it's safe to sleep now. | 922 | * Info->count is now 1; so it's safe to sleep now. |
922 | */ | 923 | */ |
923 | if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { | 924 | if (!tty_port_initialized(port)) { |
924 | cp = &info->channel; | 925 | cp = &info->channel; |
925 | sSetRxTrigger(cp, TRIG_1); | 926 | sSetRxTrigger(cp, TRIG_1); |
926 | if (sGetChanStatus(cp) & CD_ACT) | 927 | if (sGetChanStatus(cp) & CD_ACT) |
@@ -944,7 +945,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
944 | sEnRxFIFO(cp); | 945 | sEnRxFIFO(cp); |
945 | sEnTransmit(cp); | 946 | sEnTransmit(cp); |
946 | 947 | ||
947 | set_bit(ASYNCB_INITIALIZED, &info->port.flags); | 948 | tty_port_set_initialized(&info->port, 1); |
948 | 949 | ||
949 | /* | 950 | /* |
950 | * Set up the tty->alt_speed kludge | 951 | * Set up the tty->alt_speed kludge |
@@ -1042,9 +1043,10 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1042 | } | 1043 | } |
1043 | } | 1044 | } |
1044 | spin_lock_irq(&port->lock); | 1045 | spin_lock_irq(&port->lock); |
1045 | info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_NORMAL_ACTIVE); | ||
1046 | tty->closing = 0; | 1046 | tty->closing = 0; |
1047 | spin_unlock_irq(&port->lock); | 1047 | spin_unlock_irq(&port->lock); |
1048 | tty_port_set_initialized(port, 0); | ||
1049 | tty_port_set_active(port, 0); | ||
1048 | mutex_unlock(&port->mutex); | 1050 | mutex_unlock(&port->mutex); |
1049 | tty_port_tty_set(port, NULL); | 1051 | tty_port_tty_set(port, NULL); |
1050 | 1052 | ||
@@ -1512,7 +1514,7 @@ static void rp_hangup(struct tty_struct *tty) | |||
1512 | sDisCTSFlowCtl(cp); | 1514 | sDisCTSFlowCtl(cp); |
1513 | sDisTxSoftFlowCtl(cp); | 1515 | sDisTxSoftFlowCtl(cp); |
1514 | sClrTxXOFF(cp); | 1516 | sClrTxXOFF(cp); |
1515 | clear_bit(ASYNCB_INITIALIZED, &info->port.flags); | 1517 | tty_port_set_initialized(&info->port, 0); |
1516 | 1518 | ||
1517 | wake_up_interruptible(&info->port.open_wait); | 1519 | wake_up_interruptible(&info->port.open_wait); |
1518 | } | 1520 | } |
@@ -1624,7 +1626,7 @@ static int rp_write(struct tty_struct *tty, | |||
1624 | /* Write remaining data into the port's xmit_buf */ | 1626 | /* Write remaining data into the port's xmit_buf */ |
1625 | while (1) { | 1627 | while (1) { |
1626 | /* Hung up ? */ | 1628 | /* Hung up ? */ |
1627 | if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags)) | 1629 | if (!tty_port_active(&info->port)) |
1628 | goto end; | 1630 | goto end; |
1629 | c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1); | 1631 | c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1); |
1630 | c = min(c, XMIT_BUF_SIZE - info->xmit_head); | 1632 | c = min(c, XMIT_BUF_SIZE - info->xmit_head); |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 047a7ba6796a..215a99237e95 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | struct uart_8250_dma { | 18 | struct uart_8250_dma { |
19 | int (*tx_dma)(struct uart_8250_port *p); | 19 | int (*tx_dma)(struct uart_8250_port *p); |
20 | int (*rx_dma)(struct uart_8250_port *p, unsigned int iir); | 20 | int (*rx_dma)(struct uart_8250_port *p); |
21 | 21 | ||
22 | /* Filter function */ | 22 | /* Filter function */ |
23 | dma_filter_fn fn; | 23 | dma_filter_fn fn; |
@@ -84,7 +84,6 @@ struct serial8250_config { | |||
84 | #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ | 84 | #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ |
85 | #define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */ | 85 | #define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */ |
86 | 86 | ||
87 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) | ||
88 | 87 | ||
89 | #ifdef CONFIG_SERIAL_8250_SHARE_IRQ | 88 | #ifdef CONFIG_SERIAL_8250_SHARE_IRQ |
90 | #define SERIAL8250_SHARE_IRQS 1 | 89 | #define SERIAL8250_SHARE_IRQS 1 |
@@ -151,6 +150,12 @@ static inline int serial8250_pnp_init(void) { return 0; } | |||
151 | static inline void serial8250_pnp_exit(void) { } | 150 | static inline void serial8250_pnp_exit(void) { } |
152 | #endif | 151 | #endif |
153 | 152 | ||
153 | #ifdef CONFIG_SERIAL_8250_FINTEK | ||
154 | int fintek_8250_probe(struct uart_8250_port *uart); | ||
155 | #else | ||
156 | static inline int fintek_8250_probe(struct uart_8250_port *uart) { return 0; } | ||
157 | #endif | ||
158 | |||
154 | #ifdef CONFIG_ARCH_OMAP1 | 159 | #ifdef CONFIG_ARCH_OMAP1 |
155 | static inline int is_omap1_8250(struct uart_8250_port *pt) | 160 | static inline int is_omap1_8250(struct uart_8250_port *pt) |
156 | { | 161 | { |
@@ -190,7 +195,8 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt) | |||
190 | 195 | ||
191 | #ifdef CONFIG_SERIAL_8250_DMA | 196 | #ifdef CONFIG_SERIAL_8250_DMA |
192 | extern int serial8250_tx_dma(struct uart_8250_port *); | 197 | extern int serial8250_tx_dma(struct uart_8250_port *); |
193 | extern int serial8250_rx_dma(struct uart_8250_port *, unsigned int iir); | 198 | extern int serial8250_rx_dma(struct uart_8250_port *); |
199 | extern void serial8250_rx_dma_flush(struct uart_8250_port *); | ||
194 | extern int serial8250_request_dma(struct uart_8250_port *); | 200 | extern int serial8250_request_dma(struct uart_8250_port *); |
195 | extern void serial8250_release_dma(struct uart_8250_port *); | 201 | extern void serial8250_release_dma(struct uart_8250_port *); |
196 | #else | 202 | #else |
@@ -198,10 +204,11 @@ static inline int serial8250_tx_dma(struct uart_8250_port *p) | |||
198 | { | 204 | { |
199 | return -1; | 205 | return -1; |
200 | } | 206 | } |
201 | static inline int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | 207 | static inline int serial8250_rx_dma(struct uart_8250_port *p) |
202 | { | 208 | { |
203 | return -1; | 209 | return -1; |
204 | } | 210 | } |
211 | static inline void serial8250_rx_dma_flush(struct uart_8250_port *p) { } | ||
205 | static inline int serial8250_request_dma(struct uart_8250_port *p) | 212 | static inline int serial8250_request_dma(struct uart_8250_port *p) |
206 | { | 213 | { |
207 | return -1; | 214 | return -1; |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 2f4f5ee651db..0fbd7c033a25 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -830,6 +830,7 @@ static int serial8250_probe(struct platform_device *dev) | |||
830 | uart.port.handle_irq = p->handle_irq; | 830 | uart.port.handle_irq = p->handle_irq; |
831 | uart.port.handle_break = p->handle_break; | 831 | uart.port.handle_break = p->handle_break; |
832 | uart.port.set_termios = p->set_termios; | 832 | uart.port.set_termios = p->set_termios; |
833 | uart.port.get_mctrl = p->get_mctrl; | ||
833 | uart.port.pm = p->pm; | 834 | uart.port.pm = p->pm; |
834 | uart.port.dev = &dev->dev; | 835 | uart.port.dev = &dev->dev; |
835 | uart.port.irqflags |= irqflag; | 836 | uart.port.irqflags |= irqflag; |
@@ -1022,6 +1023,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
1022 | /* Possibly override set_termios call */ | 1023 | /* Possibly override set_termios call */ |
1023 | if (up->port.set_termios) | 1024 | if (up->port.set_termios) |
1024 | uart->port.set_termios = up->port.set_termios; | 1025 | uart->port.set_termios = up->port.set_termios; |
1026 | if (up->port.get_mctrl) | ||
1027 | uart->port.get_mctrl = up->port.get_mctrl; | ||
1025 | if (up->port.set_mctrl) | 1028 | if (up->port.set_mctrl) |
1026 | uart->port.set_mctrl = up->port.set_mctrl; | 1029 | uart->port.set_mctrl = up->port.set_mctrl; |
1027 | if (up->port.startup) | 1030 | if (up->port.startup) |
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index 78259d3c6a55..7f33d1c8d1a9 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c | |||
@@ -110,30 +110,11 @@ err: | |||
110 | return ret; | 110 | return ret; |
111 | } | 111 | } |
112 | 112 | ||
113 | int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | 113 | int serial8250_rx_dma(struct uart_8250_port *p) |
114 | { | 114 | { |
115 | struct uart_8250_dma *dma = p->dma; | 115 | struct uart_8250_dma *dma = p->dma; |
116 | struct dma_async_tx_descriptor *desc; | 116 | struct dma_async_tx_descriptor *desc; |
117 | 117 | ||
118 | switch (iir & 0x3f) { | ||
119 | case UART_IIR_RLSI: | ||
120 | /* 8250_core handles errors and break interrupts */ | ||
121 | return -EIO; | ||
122 | case UART_IIR_RX_TIMEOUT: | ||
123 | /* | ||
124 | * If RCVR FIFO trigger level was not reached, complete the | ||
125 | * transfer and let 8250_core copy the remaining data. | ||
126 | */ | ||
127 | if (dma->rx_running) { | ||
128 | dmaengine_pause(dma->rxchan); | ||
129 | __dma_rx_complete(p); | ||
130 | dmaengine_terminate_all(dma->rxchan); | ||
131 | } | ||
132 | return -ETIMEDOUT; | ||
133 | default: | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | if (dma->rx_running) | 118 | if (dma->rx_running) |
138 | return 0; | 119 | return 0; |
139 | 120 | ||
@@ -154,10 +135,23 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |||
154 | return 0; | 135 | return 0; |
155 | } | 136 | } |
156 | 137 | ||
138 | void serial8250_rx_dma_flush(struct uart_8250_port *p) | ||
139 | { | ||
140 | struct uart_8250_dma *dma = p->dma; | ||
141 | |||
142 | if (dma->rx_running) { | ||
143 | dmaengine_pause(dma->rxchan); | ||
144 | __dma_rx_complete(p); | ||
145 | dmaengine_terminate_all(dma->rxchan); | ||
146 | } | ||
147 | } | ||
148 | |||
157 | int serial8250_request_dma(struct uart_8250_port *p) | 149 | int serial8250_request_dma(struct uart_8250_port *p) |
158 | { | 150 | { |
159 | struct uart_8250_dma *dma = p->dma; | 151 | struct uart_8250_dma *dma = p->dma; |
160 | dma_cap_mask_t mask; | 152 | dma_cap_mask_t mask; |
153 | struct dma_slave_caps caps; | ||
154 | int ret; | ||
161 | 155 | ||
162 | /* Default slave configuration parameters */ | 156 | /* Default slave configuration parameters */ |
163 | dma->rxconf.direction = DMA_DEV_TO_MEM; | 157 | dma->rxconf.direction = DMA_DEV_TO_MEM; |
@@ -178,6 +172,16 @@ int serial8250_request_dma(struct uart_8250_port *p) | |||
178 | if (!dma->rxchan) | 172 | if (!dma->rxchan) |
179 | return -ENODEV; | 173 | return -ENODEV; |
180 | 174 | ||
175 | /* 8250 rx dma requires dmaengine driver to support pause/terminate */ | ||
176 | ret = dma_get_slave_caps(dma->rxchan, &caps); | ||
177 | if (ret) | ||
178 | goto release_rx; | ||
179 | if (!caps.cmd_pause || !caps.cmd_terminate || | ||
180 | caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR) { | ||
181 | ret = -EINVAL; | ||
182 | goto release_rx; | ||
183 | } | ||
184 | |||
181 | dmaengine_slave_config(dma->rxchan, &dma->rxconf); | 185 | dmaengine_slave_config(dma->rxchan, &dma->rxconf); |
182 | 186 | ||
183 | /* Get a channel for TX */ | 187 | /* Get a channel for TX */ |
@@ -185,8 +189,17 @@ int serial8250_request_dma(struct uart_8250_port *p) | |||
185 | dma->fn, dma->tx_param, | 189 | dma->fn, dma->tx_param, |
186 | p->port.dev, "tx"); | 190 | p->port.dev, "tx"); |
187 | if (!dma->txchan) { | 191 | if (!dma->txchan) { |
188 | dma_release_channel(dma->rxchan); | 192 | ret = -ENODEV; |
189 | return -ENODEV; | 193 | goto release_rx; |
194 | } | ||
195 | |||
196 | /* 8250 tx dma requires dmaengine driver to support terminate */ | ||
197 | ret = dma_get_slave_caps(dma->txchan, &caps); | ||
198 | if (ret) | ||
199 | goto err; | ||
200 | if (!caps.cmd_terminate) { | ||
201 | ret = -EINVAL; | ||
202 | goto err; | ||
190 | } | 203 | } |
191 | 204 | ||
192 | dmaengine_slave_config(dma->txchan, &dma->txconf); | 205 | dmaengine_slave_config(dma->txchan, &dma->txconf); |
@@ -197,8 +210,10 @@ int serial8250_request_dma(struct uart_8250_port *p) | |||
197 | 210 | ||
198 | dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size, | 211 | dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size, |
199 | &dma->rx_addr, GFP_KERNEL); | 212 | &dma->rx_addr, GFP_KERNEL); |
200 | if (!dma->rx_buf) | 213 | if (!dma->rx_buf) { |
214 | ret = -ENOMEM; | ||
201 | goto err; | 215 | goto err; |
216 | } | ||
202 | 217 | ||
203 | /* TX buffer */ | 218 | /* TX buffer */ |
204 | dma->tx_addr = dma_map_single(dma->txchan->device->dev, | 219 | dma->tx_addr = dma_map_single(dma->txchan->device->dev, |
@@ -208,6 +223,7 @@ int serial8250_request_dma(struct uart_8250_port *p) | |||
208 | if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) { | 223 | if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) { |
209 | dma_free_coherent(dma->rxchan->device->dev, dma->rx_size, | 224 | dma_free_coherent(dma->rxchan->device->dev, dma->rx_size, |
210 | dma->rx_buf, dma->rx_addr); | 225 | dma->rx_buf, dma->rx_addr); |
226 | ret = -ENOMEM; | ||
211 | goto err; | 227 | goto err; |
212 | } | 228 | } |
213 | 229 | ||
@@ -215,10 +231,10 @@ int serial8250_request_dma(struct uart_8250_port *p) | |||
215 | 231 | ||
216 | return 0; | 232 | return 0; |
217 | err: | 233 | err: |
218 | dma_release_channel(dma->rxchan); | ||
219 | dma_release_channel(dma->txchan); | 234 | dma_release_channel(dma->txchan); |
220 | 235 | release_rx: | |
221 | return -ENOMEM; | 236 | dma_release_channel(dma->rxchan); |
237 | return ret; | ||
222 | } | 238 | } |
223 | EXPORT_SYMBOL_GPL(serial8250_request_dma); | 239 | EXPORT_SYMBOL_GPL(serial8250_request_dma); |
224 | 240 | ||
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index a3fb95d85d7c..e19969614203 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -104,15 +104,16 @@ static void dw8250_check_lcr(struct uart_port *p, int value) | |||
104 | dw8250_force_idle(p); | 104 | dw8250_force_idle(p); |
105 | 105 | ||
106 | #ifdef CONFIG_64BIT | 106 | #ifdef CONFIG_64BIT |
107 | __raw_writeq(value & 0xff, offset); | 107 | if (p->type == PORT_OCTEON) |
108 | #else | 108 | __raw_writeq(value & 0xff, offset); |
109 | else | ||
110 | #endif | ||
109 | if (p->iotype == UPIO_MEM32) | 111 | if (p->iotype == UPIO_MEM32) |
110 | writel(value, offset); | 112 | writel(value, offset); |
111 | else if (p->iotype == UPIO_MEM32BE) | 113 | else if (p->iotype == UPIO_MEM32BE) |
112 | iowrite32be(value, offset); | 114 | iowrite32be(value, offset); |
113 | else | 115 | else |
114 | writeb(value, offset); | 116 | writeb(value, offset); |
115 | #endif | ||
116 | } | 117 | } |
117 | /* | 118 | /* |
118 | * FIXME: this deadlocks if port->lock is already held | 119 | * FIXME: this deadlocks if port->lock is already held |
@@ -617,6 +618,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = { | |||
617 | { "8086228A", 0 }, | 618 | { "8086228A", 0 }, |
618 | { "APMC0D08", 0}, | 619 | { "APMC0D08", 0}, |
619 | { "AMD0020", 0 }, | 620 | { "AMD0020", 0 }, |
621 | { "AMDI0020", 0 }, | ||
620 | { }, | 622 | { }, |
621 | }; | 623 | }; |
622 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | 624 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); |
diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c index 89474399ab89..870981dd9e39 100644 --- a/drivers/tty/serial/8250/8250_fintek.c +++ b/drivers/tty/serial/8250/8250_fintek.c | |||
@@ -1,9 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Probe for F81216A LPC to 4 UART | 2 | * Probe for F81216A LPC to 4 UART |
3 | * | 3 | * |
4 | * Based on drivers/tty/serial/8250_pnp.c, by Russell King, et al | 4 | * Copyright (C) 2014-2016 Ricardo Ribalda, Qtechnology A/S |
5 | * | ||
6 | * Copyright (C) 2014 Ricardo Ribalda, Qtechnology A/S | ||
7 | * | 5 | * |
8 | * | 6 | * |
9 | * 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 |
@@ -38,19 +36,15 @@ | |||
38 | #define RXW4C_IRA BIT(3) | 36 | #define RXW4C_IRA BIT(3) |
39 | #define TXW4C_IRA BIT(2) | 37 | #define TXW4C_IRA BIT(2) |
40 | 38 | ||
41 | #define DRIVER_NAME "8250_fintek" | ||
42 | |||
43 | struct fintek_8250 { | 39 | struct fintek_8250 { |
44 | u16 base_port; | 40 | u16 base_port; |
45 | u8 index; | 41 | u8 index; |
46 | u8 key; | 42 | u8 key; |
47 | long line; | ||
48 | }; | 43 | }; |
49 | 44 | ||
50 | static int fintek_8250_enter_key(u16 base_port, u8 key) | 45 | static int fintek_8250_enter_key(u16 base_port, u8 key) |
51 | { | 46 | { |
52 | 47 | if (!request_muxed_region(base_port, 2, "8250_fintek")) | |
53 | if (!request_muxed_region(base_port, 2, DRIVER_NAME)) | ||
54 | return -EBUSY; | 48 | return -EBUSY; |
55 | 49 | ||
56 | outb(key, base_port + ADDR_PORT); | 50 | outb(key, base_port + ADDR_PORT); |
@@ -138,7 +132,7 @@ static int fintek_8250_rs485_config(struct uart_port *port, | |||
138 | return 0; | 132 | return 0; |
139 | } | 133 | } |
140 | 134 | ||
141 | static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index) | 135 | static int find_base_port(struct fintek_8250 *pdata, u16 io_address) |
142 | { | 136 | { |
143 | static const u16 addr[] = {0x4e, 0x2e}; | 137 | static const u16 addr[] = {0x4e, 0x2e}; |
144 | static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67}; | 138 | static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67}; |
@@ -168,10 +162,13 @@ static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index) | |||
168 | continue; | 162 | continue; |
169 | 163 | ||
170 | fintek_8250_exit_key(addr[i]); | 164 | fintek_8250_exit_key(addr[i]); |
171 | *key = keys[j]; | 165 | pdata->key = keys[j]; |
172 | *index = k; | 166 | pdata->base_port = addr[i]; |
173 | return addr[i]; | 167 | pdata->index = k; |
168 | |||
169 | return 0; | ||
174 | } | 170 | } |
171 | |||
175 | fintek_8250_exit_key(addr[i]); | 172 | fintek_8250_exit_key(addr[i]); |
176 | } | 173 | } |
177 | } | 174 | } |
@@ -179,104 +176,21 @@ static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index) | |||
179 | return -ENODEV; | 176 | return -ENODEV; |
180 | } | 177 | } |
181 | 178 | ||
182 | static int | 179 | int fintek_8250_probe(struct uart_8250_port *uart) |
183 | fintek_8250_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | ||
184 | { | 180 | { |
185 | struct uart_8250_port uart; | ||
186 | struct fintek_8250 *pdata; | 181 | struct fintek_8250 *pdata; |
187 | int base_port; | 182 | struct fintek_8250 probe_data; |
188 | u8 key; | ||
189 | u8 index; | ||
190 | |||
191 | if (!pnp_port_valid(dev, 0)) | ||
192 | return -ENODEV; | ||
193 | 183 | ||
194 | base_port = fintek_8250_base_port(pnp_port_start(dev, 0), &key, &index); | 184 | if (find_base_port(&probe_data, uart->port.iobase)) |
195 | if (base_port < 0) | ||
196 | return -ENODEV; | 185 | return -ENODEV; |
197 | 186 | ||
198 | memset(&uart, 0, sizeof(uart)); | 187 | pdata = devm_kzalloc(uart->port.dev, sizeof(*pdata), GFP_KERNEL); |
199 | |||
200 | pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); | ||
201 | if (!pdata) | 188 | if (!pdata) |
202 | return -ENOMEM; | 189 | return -ENOMEM; |
203 | uart.port.private_data = pdata; | ||
204 | 190 | ||
205 | if (!pnp_irq_valid(dev, 0)) | 191 | memcpy(pdata, &probe_data, sizeof(probe_data)); |
206 | return -ENODEV; | 192 | uart->port.rs485_config = fintek_8250_rs485_config; |
207 | uart.port.irq = pnp_irq(dev, 0); | 193 | uart->port.private_data = pdata; |
208 | uart.port.iobase = pnp_port_start(dev, 0); | ||
209 | uart.port.iotype = UPIO_PORT; | ||
210 | uart.port.rs485_config = fintek_8250_rs485_config; | ||
211 | |||
212 | uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | ||
213 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) | ||
214 | uart.port.flags |= UPF_SHARE_IRQ; | ||
215 | uart.port.uartclk = 1843200; | ||
216 | uart.port.dev = &dev->dev; | ||
217 | |||
218 | pdata->key = key; | ||
219 | pdata->base_port = base_port; | ||
220 | pdata->index = index; | ||
221 | pdata->line = serial8250_register_8250_port(&uart); | ||
222 | if (pdata->line < 0) | ||
223 | return -ENODEV; | ||
224 | 194 | ||
225 | pnp_set_drvdata(dev, pdata); | ||
226 | return 0; | 195 | return 0; |
227 | } | 196 | } |
228 | |||
229 | static void fintek_8250_remove(struct pnp_dev *dev) | ||
230 | { | ||
231 | struct fintek_8250 *pdata = pnp_get_drvdata(dev); | ||
232 | |||
233 | if (pdata) | ||
234 | serial8250_unregister_port(pdata->line); | ||
235 | } | ||
236 | |||
237 | #ifdef CONFIG_PM | ||
238 | static int fintek_8250_suspend(struct pnp_dev *dev, pm_message_t state) | ||
239 | { | ||
240 | struct fintek_8250 *pdata = pnp_get_drvdata(dev); | ||
241 | |||
242 | if (!pdata) | ||
243 | return -ENODEV; | ||
244 | serial8250_suspend_port(pdata->line); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int fintek_8250_resume(struct pnp_dev *dev) | ||
249 | { | ||
250 | struct fintek_8250 *pdata = pnp_get_drvdata(dev); | ||
251 | |||
252 | if (!pdata) | ||
253 | return -ENODEV; | ||
254 | serial8250_resume_port(pdata->line); | ||
255 | return 0; | ||
256 | } | ||
257 | #else | ||
258 | #define fintek_8250_suspend NULL | ||
259 | #define fintek_8250_resume NULL | ||
260 | #endif /* CONFIG_PM */ | ||
261 | |||
262 | static const struct pnp_device_id fintek_dev_table[] = { | ||
263 | /* Qtechnology Panel PC / IO1000 */ | ||
264 | { "PNP0501"}, | ||
265 | {} | ||
266 | }; | ||
267 | |||
268 | MODULE_DEVICE_TABLE(pnp, fintek_dev_table); | ||
269 | |||
270 | static struct pnp_driver fintek_8250_driver = { | ||
271 | .name = DRIVER_NAME, | ||
272 | .probe = fintek_8250_probe, | ||
273 | .remove = fintek_8250_remove, | ||
274 | .suspend = fintek_8250_suspend, | ||
275 | .resume = fintek_8250_resume, | ||
276 | .id_table = fintek_dev_table, | ||
277 | }; | ||
278 | |||
279 | module_pnp_driver(fintek_8250_driver); | ||
280 | MODULE_DESCRIPTION("Fintek F812164 module"); | ||
281 | MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>"); | ||
282 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index 88531a36b69c..86379a79a6a3 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c | |||
@@ -9,11 +9,13 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/rational.h> | 12 | #include <linux/bitops.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/rational.h> | ||
15 | 16 | ||
16 | #include <linux/dma/hsu.h> | 17 | #include <linux/dma/hsu.h> |
18 | #include <linux/8250_pci.h> | ||
17 | 19 | ||
18 | #include "8250.h" | 20 | #include "8250.h" |
19 | 21 | ||
@@ -24,6 +26,7 @@ | |||
24 | #define PCI_DEVICE_ID_INTEL_DNV_UART 0x19d8 | 26 | #define PCI_DEVICE_ID_INTEL_DNV_UART 0x19d8 |
25 | 27 | ||
26 | /* Intel MID Specific registers */ | 28 | /* Intel MID Specific registers */ |
29 | #define INTEL_MID_UART_DNV_FISR 0x08 | ||
27 | #define INTEL_MID_UART_PS 0x30 | 30 | #define INTEL_MID_UART_PS 0x30 |
28 | #define INTEL_MID_UART_MUL 0x34 | 31 | #define INTEL_MID_UART_MUL 0x34 |
29 | #define INTEL_MID_UART_DIV 0x38 | 32 | #define INTEL_MID_UART_DIV 0x38 |
@@ -31,6 +34,7 @@ | |||
31 | struct mid8250; | 34 | struct mid8250; |
32 | 35 | ||
33 | struct mid8250_board { | 36 | struct mid8250_board { |
37 | unsigned int flags; | ||
34 | unsigned long freq; | 38 | unsigned long freq; |
35 | unsigned int base_baud; | 39 | unsigned int base_baud; |
36 | int (*setup)(struct mid8250 *, struct uart_port *p); | 40 | int (*setup)(struct mid8250 *, struct uart_port *p); |
@@ -76,7 +80,11 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p) | |||
76 | struct pci_dev *pdev = to_pci_dev(p->dev); | 80 | struct pci_dev *pdev = to_pci_dev(p->dev); |
77 | int index = PCI_FUNC(pdev->devfn); | 81 | int index = PCI_FUNC(pdev->devfn); |
78 | 82 | ||
79 | /* Currently no support for HSU port0 */ | 83 | /* |
84 | * Device 0000:00:04.0 is not a real HSU port. It provides a global | ||
85 | * register set for all HSU ports, although it has the same PCI ID. | ||
86 | * Skip it here. | ||
87 | */ | ||
80 | if (index-- == 0) | 88 | if (index-- == 0) |
81 | return -ENODEV; | 89 | return -ENODEV; |
82 | 90 | ||
@@ -88,16 +96,16 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p) | |||
88 | static int dnv_handle_irq(struct uart_port *p) | 96 | static int dnv_handle_irq(struct uart_port *p) |
89 | { | 97 | { |
90 | struct mid8250 *mid = p->private_data; | 98 | struct mid8250 *mid = p->private_data; |
91 | int ret; | 99 | unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR); |
92 | 100 | int ret = IRQ_NONE; | |
93 | ret = hsu_dma_irq(&mid->dma_chip, 0); | 101 | |
94 | ret |= hsu_dma_irq(&mid->dma_chip, 1); | 102 | if (fisr & BIT(2)) |
95 | 103 | ret |= hsu_dma_irq(&mid->dma_chip, 1); | |
96 | /* For now, letting the HW generate separate interrupt for the UART */ | 104 | if (fisr & BIT(1)) |
97 | if (ret) | 105 | ret |= hsu_dma_irq(&mid->dma_chip, 0); |
98 | return ret; | 106 | if (fisr & BIT(0)) |
99 | 107 | ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); | |
100 | return serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); | 108 | return ret; |
101 | } | 109 | } |
102 | 110 | ||
103 | #define DNV_DMA_CHAN_OFFSET 0x80 | 111 | #define DNV_DMA_CHAN_OFFSET 0x80 |
@@ -106,12 +114,13 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p) | |||
106 | { | 114 | { |
107 | struct hsu_dma_chip *chip = &mid->dma_chip; | 115 | struct hsu_dma_chip *chip = &mid->dma_chip; |
108 | struct pci_dev *pdev = to_pci_dev(p->dev); | 116 | struct pci_dev *pdev = to_pci_dev(p->dev); |
117 | unsigned int bar = FL_GET_BASE(mid->board->flags); | ||
109 | int ret; | 118 | int ret; |
110 | 119 | ||
111 | chip->dev = &pdev->dev; | 120 | chip->dev = &pdev->dev; |
112 | chip->irq = pdev->irq; | 121 | chip->irq = pdev->irq; |
113 | chip->regs = p->membase; | 122 | chip->regs = p->membase; |
114 | chip->length = pci_resource_len(pdev, 0); | 123 | chip->length = pci_resource_len(pdev, bar); |
115 | chip->offset = DNV_DMA_CHAN_OFFSET; | 124 | chip->offset = DNV_DMA_CHAN_OFFSET; |
116 | 125 | ||
117 | /* Falling back to PIO mode if DMA probing fails */ | 126 | /* Falling back to PIO mode if DMA probing fails */ |
@@ -217,6 +226,7 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
217 | { | 226 | { |
218 | struct uart_8250_port uart; | 227 | struct uart_8250_port uart; |
219 | struct mid8250 *mid; | 228 | struct mid8250 *mid; |
229 | unsigned int bar; | ||
220 | int ret; | 230 | int ret; |
221 | 231 | ||
222 | ret = pcim_enable_device(pdev); | 232 | ret = pcim_enable_device(pdev); |
@@ -230,6 +240,7 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
230 | return -ENOMEM; | 240 | return -ENOMEM; |
231 | 241 | ||
232 | mid->board = (struct mid8250_board *)id->driver_data; | 242 | mid->board = (struct mid8250_board *)id->driver_data; |
243 | bar = FL_GET_BASE(mid->board->flags); | ||
233 | 244 | ||
234 | memset(&uart, 0, sizeof(struct uart_8250_port)); | 245 | memset(&uart, 0, sizeof(struct uart_8250_port)); |
235 | 246 | ||
@@ -242,8 +253,8 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
242 | uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE; | 253 | uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE; |
243 | uart.port.set_termios = mid8250_set_termios; | 254 | uart.port.set_termios = mid8250_set_termios; |
244 | 255 | ||
245 | uart.port.mapbase = pci_resource_start(pdev, 0); | 256 | uart.port.mapbase = pci_resource_start(pdev, bar); |
246 | uart.port.membase = pcim_iomap(pdev, 0, 0); | 257 | uart.port.membase = pcim_iomap(pdev, bar, 0); |
247 | if (!uart.port.membase) | 258 | if (!uart.port.membase) |
248 | return -ENOMEM; | 259 | return -ENOMEM; |
249 | 260 | ||
@@ -282,18 +293,21 @@ static void mid8250_remove(struct pci_dev *pdev) | |||
282 | } | 293 | } |
283 | 294 | ||
284 | static const struct mid8250_board pnw_board = { | 295 | static const struct mid8250_board pnw_board = { |
296 | .flags = FL_BASE0, | ||
285 | .freq = 50000000, | 297 | .freq = 50000000, |
286 | .base_baud = 115200, | 298 | .base_baud = 115200, |
287 | .setup = pnw_setup, | 299 | .setup = pnw_setup, |
288 | }; | 300 | }; |
289 | 301 | ||
290 | static const struct mid8250_board tng_board = { | 302 | static const struct mid8250_board tng_board = { |
303 | .flags = FL_BASE0, | ||
291 | .freq = 38400000, | 304 | .freq = 38400000, |
292 | .base_baud = 1843200, | 305 | .base_baud = 1843200, |
293 | .setup = tng_setup, | 306 | .setup = tng_setup, |
294 | }; | 307 | }; |
295 | 308 | ||
296 | static const struct mid8250_board dnv_board = { | 309 | static const struct mid8250_board dnv_board = { |
310 | .flags = FL_BASE1, | ||
297 | .freq = 133333333, | 311 | .freq = 133333333, |
298 | .base_baud = 115200, | 312 | .base_baud = 115200, |
299 | .setup = dnv_setup, | 313 | .setup = dnv_setup, |
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index c7ed3d2bc8b2..38963d7bcf84 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c | |||
@@ -29,7 +29,7 @@ struct of_serial_info { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | #ifdef CONFIG_ARCH_TEGRA | 31 | #ifdef CONFIG_ARCH_TEGRA |
32 | void tegra_serial_handle_break(struct uart_port *p) | 32 | static void tegra_serial_handle_break(struct uart_port *p) |
33 | { | 33 | { |
34 | unsigned int status, tmout = 10000; | 34 | unsigned int status, tmout = 10000; |
35 | 35 | ||
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 6f760510e46d..2c44c792d586 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c | |||
@@ -115,6 +115,12 @@ struct omap8250_priv { | |||
115 | bool rx_dma_broken; | 115 | bool rx_dma_broken; |
116 | }; | 116 | }; |
117 | 117 | ||
118 | #ifdef CONFIG_SERIAL_8250_DMA | ||
119 | static void omap_8250_rx_dma_flush(struct uart_8250_port *p); | ||
120 | #else | ||
121 | static inline void omap_8250_rx_dma_flush(struct uart_8250_port *p) { } | ||
122 | #endif | ||
123 | |||
118 | static u32 uart_read(struct uart_8250_port *up, u32 reg) | 124 | static u32 uart_read(struct uart_8250_port *up, u32 reg) |
119 | { | 125 | { |
120 | return readl(up->port.membase + (reg << up->port.regshift)); | 126 | return readl(up->port.membase + (reg << up->port.regshift)); |
@@ -635,7 +641,7 @@ static int omap_8250_startup(struct uart_port *port) | |||
635 | serial_out(up, UART_OMAP_WER, priv->wer); | 641 | serial_out(up, UART_OMAP_WER, priv->wer); |
636 | 642 | ||
637 | if (up->dma) | 643 | if (up->dma) |
638 | up->dma->rx_dma(up, 0); | 644 | up->dma->rx_dma(up); |
639 | 645 | ||
640 | pm_runtime_mark_last_busy(port->dev); | 646 | pm_runtime_mark_last_busy(port->dev); |
641 | pm_runtime_put_autosuspend(port->dev); | 647 | pm_runtime_put_autosuspend(port->dev); |
@@ -654,7 +660,7 @@ static void omap_8250_shutdown(struct uart_port *port) | |||
654 | 660 | ||
655 | flush_work(&priv->qos_work); | 661 | flush_work(&priv->qos_work); |
656 | if (up->dma) | 662 | if (up->dma) |
657 | up->dma->rx_dma(up, UART_IIR_RX_TIMEOUT); | 663 | omap_8250_rx_dma_flush(up); |
658 | 664 | ||
659 | pm_runtime_get_sync(port->dev); | 665 | pm_runtime_get_sync(port->dev); |
660 | 666 | ||
@@ -742,9 +748,9 @@ static void omap_8250_unthrottle(struct uart_port *port) | |||
742 | } | 748 | } |
743 | 749 | ||
744 | #ifdef CONFIG_SERIAL_8250_DMA | 750 | #ifdef CONFIG_SERIAL_8250_DMA |
745 | static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir); | 751 | static int omap_8250_rx_dma(struct uart_8250_port *p); |
746 | 752 | ||
747 | static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) | 753 | static void __dma_rx_do_complete(struct uart_8250_port *p) |
748 | { | 754 | { |
749 | struct omap8250_priv *priv = p->port.private_data; | 755 | struct omap8250_priv *priv = p->port.private_data; |
750 | struct uart_8250_dma *dma = p->dma; | 756 | struct uart_8250_dma *dma = p->dma; |
@@ -754,9 +760,6 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) | |||
754 | unsigned long flags; | 760 | unsigned long flags; |
755 | int ret; | 761 | int ret; |
756 | 762 | ||
757 | dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, | ||
758 | dma->rx_size, DMA_FROM_DEVICE); | ||
759 | |||
760 | spin_lock_irqsave(&priv->rx_dma_lock, flags); | 763 | spin_lock_irqsave(&priv->rx_dma_lock, flags); |
761 | 764 | ||
762 | if (!dma->rx_running) | 765 | if (!dma->rx_running) |
@@ -764,7 +767,6 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) | |||
764 | 767 | ||
765 | dma->rx_running = 0; | 768 | dma->rx_running = 0; |
766 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | 769 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
767 | dmaengine_terminate_all(dma->rxchan); | ||
768 | 770 | ||
769 | count = dma->rx_size - state.residue; | 771 | count = dma->rx_size - state.residue; |
770 | 772 | ||
@@ -775,15 +777,13 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) | |||
775 | unlock: | 777 | unlock: |
776 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); | 778 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); |
777 | 779 | ||
778 | if (!error) | ||
779 | omap_8250_rx_dma(p, 0); | ||
780 | |||
781 | tty_flip_buffer_push(tty_port); | 780 | tty_flip_buffer_push(tty_port); |
782 | } | 781 | } |
783 | 782 | ||
784 | static void __dma_rx_complete(void *param) | 783 | static void __dma_rx_complete(void *param) |
785 | { | 784 | { |
786 | __dma_rx_do_complete(param, false); | 785 | __dma_rx_do_complete(param); |
786 | omap_8250_rx_dma(param); | ||
787 | } | 787 | } |
788 | 788 | ||
789 | static void omap_8250_rx_dma_flush(struct uart_8250_port *p) | 789 | static void omap_8250_rx_dma_flush(struct uart_8250_port *p) |
@@ -806,10 +806,11 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p) | |||
806 | 806 | ||
807 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); | 807 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); |
808 | 808 | ||
809 | __dma_rx_do_complete(p, true); | 809 | __dma_rx_do_complete(p); |
810 | dmaengine_terminate_all(dma->rxchan); | ||
810 | } | 811 | } |
811 | 812 | ||
812 | static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | 813 | static int omap_8250_rx_dma(struct uart_8250_port *p) |
813 | { | 814 | { |
814 | struct omap8250_priv *priv = p->port.private_data; | 815 | struct omap8250_priv *priv = p->port.private_data; |
815 | struct uart_8250_dma *dma = p->dma; | 816 | struct uart_8250_dma *dma = p->dma; |
@@ -817,35 +818,6 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |||
817 | struct dma_async_tx_descriptor *desc; | 818 | struct dma_async_tx_descriptor *desc; |
818 | unsigned long flags; | 819 | unsigned long flags; |
819 | 820 | ||
820 | switch (iir & 0x3f) { | ||
821 | case UART_IIR_RLSI: | ||
822 | /* 8250_core handles errors and break interrupts */ | ||
823 | omap_8250_rx_dma_flush(p); | ||
824 | return -EIO; | ||
825 | case UART_IIR_RX_TIMEOUT: | ||
826 | /* | ||
827 | * If RCVR FIFO trigger level was not reached, complete the | ||
828 | * transfer and let 8250_core copy the remaining data. | ||
829 | */ | ||
830 | omap_8250_rx_dma_flush(p); | ||
831 | return -ETIMEDOUT; | ||
832 | case UART_IIR_RDI: | ||
833 | /* | ||
834 | * The OMAP UART is a special BEAST. If we receive RDI we _have_ | ||
835 | * a DMA transfer programmed but it didn't work. One reason is | ||
836 | * that we were too slow and there were too many bytes in the | ||
837 | * FIFO, the UART counted wrong and never kicked the DMA engine | ||
838 | * to do anything. That means once we receive RDI on OMAP then | ||
839 | * the DMA won't do anything soon so we have to cancel the DMA | ||
840 | * transfer and purge the FIFO manually. | ||
841 | */ | ||
842 | omap_8250_rx_dma_flush(p); | ||
843 | return -ETIMEDOUT; | ||
844 | |||
845 | default: | ||
846 | break; | ||
847 | } | ||
848 | |||
849 | if (priv->rx_dma_broken) | 821 | if (priv->rx_dma_broken) |
850 | return -EINVAL; | 822 | return -EINVAL; |
851 | 823 | ||
@@ -868,9 +840,6 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |||
868 | 840 | ||
869 | dma->rx_cookie = dmaengine_submit(desc); | 841 | dma->rx_cookie = dmaengine_submit(desc); |
870 | 842 | ||
871 | dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr, | ||
872 | dma->rx_size, DMA_FROM_DEVICE); | ||
873 | |||
874 | dma_async_issue_pending(dma->rxchan); | 843 | dma_async_issue_pending(dma->rxchan); |
875 | out: | 844 | out: |
876 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); | 845 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); |
@@ -1022,6 +991,18 @@ err: | |||
1022 | return ret; | 991 | return ret; |
1023 | } | 992 | } |
1024 | 993 | ||
994 | static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir) | ||
995 | { | ||
996 | switch (iir & 0x3f) { | ||
997 | case UART_IIR_RLSI: | ||
998 | case UART_IIR_RX_TIMEOUT: | ||
999 | case UART_IIR_RDI: | ||
1000 | omap_8250_rx_dma_flush(up); | ||
1001 | return true; | ||
1002 | } | ||
1003 | return omap_8250_rx_dma(up); | ||
1004 | } | ||
1005 | |||
1025 | /* | 1006 | /* |
1026 | * This is mostly serial8250_handle_irq(). We have a slightly different DMA | 1007 | * This is mostly serial8250_handle_irq(). We have a slightly different DMA |
1027 | * hoook for RX/TX and need different logic for them in the ISR. Therefore we | 1008 | * hoook for RX/TX and need different logic for them in the ISR. Therefore we |
@@ -1033,7 +1014,6 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) | |||
1033 | unsigned char status; | 1014 | unsigned char status; |
1034 | unsigned long flags; | 1015 | unsigned long flags; |
1035 | u8 iir; | 1016 | u8 iir; |
1036 | int dma_err = 0; | ||
1037 | 1017 | ||
1038 | serial8250_rpm_get(up); | 1018 | serial8250_rpm_get(up); |
1039 | 1019 | ||
@@ -1048,11 +1028,9 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) | |||
1048 | status = serial_port_in(port, UART_LSR); | 1028 | status = serial_port_in(port, UART_LSR); |
1049 | 1029 | ||
1050 | if (status & (UART_LSR_DR | UART_LSR_BI)) { | 1030 | if (status & (UART_LSR_DR | UART_LSR_BI)) { |
1051 | 1031 | if (handle_rx_dma(up, iir)) { | |
1052 | dma_err = omap_8250_rx_dma(up, iir); | ||
1053 | if (dma_err) { | ||
1054 | status = serial8250_rx_chars(up, status); | 1032 | status = serial8250_rx_chars(up, status); |
1055 | omap_8250_rx_dma(up, 0); | 1033 | omap_8250_rx_dma(up); |
1056 | } | 1034 | } |
1057 | } | 1035 | } |
1058 | serial8250_modem_status(up); | 1036 | serial8250_modem_status(up); |
@@ -1066,8 +1044,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) | |||
1066 | * try again due to an earlier failer which | 1044 | * try again due to an earlier failer which |
1067 | * might have been resolved by now. | 1045 | * might have been resolved by now. |
1068 | */ | 1046 | */ |
1069 | dma_err = omap_8250_tx_dma(up); | 1047 | if (omap_8250_tx_dma(up)) |
1070 | if (dma_err) | ||
1071 | serial8250_tx_chars(up); | 1048 | serial8250_tx_chars(up); |
1072 | } | 1049 | } |
1073 | } | 1050 | } |
@@ -1084,7 +1061,7 @@ static bool the_no_dma_filter_fn(struct dma_chan *chan, void *param) | |||
1084 | 1061 | ||
1085 | #else | 1062 | #else |
1086 | 1063 | ||
1087 | static inline int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | 1064 | static inline int omap_8250_rx_dma(struct uart_8250_port *p) |
1088 | { | 1065 | { |
1089 | return -EINVAL; | 1066 | return -EINVAL; |
1090 | } | 1067 | } |
@@ -1395,7 +1372,7 @@ static int omap8250_runtime_suspend(struct device *dev) | |||
1395 | } | 1372 | } |
1396 | 1373 | ||
1397 | if (up->dma && up->dma->rxchan) | 1374 | if (up->dma && up->dma->rxchan) |
1398 | omap_8250_rx_dma(up, UART_IIR_RX_TIMEOUT); | 1375 | omap_8250_rx_dma_flush(up); |
1399 | 1376 | ||
1400 | priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | 1377 | priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; |
1401 | schedule_work(&priv->qos_work); | 1378 | schedule_work(&priv->qos_work); |
@@ -1407,20 +1384,18 @@ static int omap8250_runtime_resume(struct device *dev) | |||
1407 | { | 1384 | { |
1408 | struct omap8250_priv *priv = dev_get_drvdata(dev); | 1385 | struct omap8250_priv *priv = dev_get_drvdata(dev); |
1409 | struct uart_8250_port *up; | 1386 | struct uart_8250_port *up; |
1410 | int loss_cntx; | ||
1411 | 1387 | ||
1412 | /* In case runtime-pm tries this before we are setup */ | 1388 | /* In case runtime-pm tries this before we are setup */ |
1413 | if (!priv) | 1389 | if (!priv) |
1414 | return 0; | 1390 | return 0; |
1415 | 1391 | ||
1416 | up = serial8250_get_port(priv->line); | 1392 | up = serial8250_get_port(priv->line); |
1417 | loss_cntx = omap8250_lost_context(up); | ||
1418 | 1393 | ||
1419 | if (loss_cntx) | 1394 | if (omap8250_lost_context(up)) |
1420 | omap8250_restore_regs(up); | 1395 | omap8250_restore_regs(up); |
1421 | 1396 | ||
1422 | if (up->dma && up->dma->rxchan) | 1397 | if (up->dma && up->dma->rxchan) |
1423 | omap_8250_rx_dma(up, 0); | 1398 | omap_8250_rx_dma(up); |
1424 | 1399 | ||
1425 | priv->latency = priv->calc_latency; | 1400 | priv->latency = priv->calc_latency; |
1426 | schedule_work(&priv->qos_work); | 1401 | schedule_work(&priv->qos_work); |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 5eea74d7f9f4..8dd250fbd367 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1377,6 +1377,9 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios, | |||
1377 | unsigned long m, n; | 1377 | unsigned long m, n; |
1378 | u32 reg; | 1378 | u32 reg; |
1379 | 1379 | ||
1380 | /* Gracefully handle the B0 case: fall back to B9600 */ | ||
1381 | fuart = fuart ? fuart : 9600 * 16; | ||
1382 | |||
1380 | /* Get Fuart closer to Fref */ | 1383 | /* Get Fuart closer to Fref */ |
1381 | fuart *= rounddown_pow_of_two(fref / fuart); | 1384 | fuart *= rounddown_pow_of_two(fref / fuart); |
1382 | 1385 | ||
@@ -1413,6 +1416,17 @@ static bool byt_dma_filter(struct dma_chan *chan, void *param) | |||
1413 | return true; | 1416 | return true; |
1414 | } | 1417 | } |
1415 | 1418 | ||
1419 | static unsigned int | ||
1420 | byt_get_mctrl(struct uart_port *port) | ||
1421 | { | ||
1422 | unsigned int ret = serial8250_do_get_mctrl(port); | ||
1423 | |||
1424 | /* Force DCD and DSR signals to permanently be reported as active. */ | ||
1425 | ret |= TIOCM_CAR | TIOCM_DSR; | ||
1426 | |||
1427 | return ret; | ||
1428 | } | ||
1429 | |||
1416 | static int | 1430 | static int |
1417 | byt_serial_setup(struct serial_private *priv, | 1431 | byt_serial_setup(struct serial_private *priv, |
1418 | const struct pciserial_board *board, | 1432 | const struct pciserial_board *board, |
@@ -1477,6 +1491,7 @@ byt_serial_setup(struct serial_private *priv, | |||
1477 | port->port.type = PORT_16550A; | 1491 | port->port.type = PORT_16550A; |
1478 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | 1492 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); |
1479 | port->port.set_termios = byt_set_termios; | 1493 | port->port.set_termios = byt_set_termios; |
1494 | port->port.get_mctrl = byt_get_mctrl; | ||
1480 | port->port.fifosize = 64; | 1495 | port->port.fifosize = 64; |
1481 | port->tx_loadsz = 64; | 1496 | port->tx_loadsz = 64; |
1482 | port->dma = dma; | 1497 | port->dma = dma; |
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 00ad2637b08c..d4036038a4dd 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c | |||
@@ -1315,6 +1315,13 @@ static void autoconfig(struct uart_8250_port *up) | |||
1315 | 1315 | ||
1316 | out_lock: | 1316 | out_lock: |
1317 | spin_unlock_irqrestore(&port->lock, flags); | 1317 | spin_unlock_irqrestore(&port->lock, flags); |
1318 | |||
1319 | /* | ||
1320 | * Check if the device is a Fintek F81216A | ||
1321 | */ | ||
1322 | if (port->type == PORT_16550A) | ||
1323 | fintek_8250_probe(up); | ||
1324 | |||
1318 | if (up->capabilities != old_capabilities) { | 1325 | if (up->capabilities != old_capabilities) { |
1319 | pr_warn("ttyS%d: detected caps %08x should be %08x\n", | 1326 | pr_warn("ttyS%d: detected caps %08x should be %08x\n", |
1320 | serial_index(port), old_capabilities, | 1327 | serial_index(port), old_capabilities, |
@@ -1788,6 +1795,18 @@ unsigned int serial8250_modem_status(struct uart_8250_port *up) | |||
1788 | } | 1795 | } |
1789 | EXPORT_SYMBOL_GPL(serial8250_modem_status); | 1796 | EXPORT_SYMBOL_GPL(serial8250_modem_status); |
1790 | 1797 | ||
1798 | static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir) | ||
1799 | { | ||
1800 | switch (iir & 0x3f) { | ||
1801 | case UART_IIR_RX_TIMEOUT: | ||
1802 | serial8250_rx_dma_flush(up); | ||
1803 | /* fall-through */ | ||
1804 | case UART_IIR_RLSI: | ||
1805 | return true; | ||
1806 | } | ||
1807 | return up->dma->rx_dma(up); | ||
1808 | } | ||
1809 | |||
1791 | /* | 1810 | /* |
1792 | * This handles the interrupt from one port. | 1811 | * This handles the interrupt from one port. |
1793 | */ | 1812 | */ |
@@ -1796,7 +1815,6 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1796 | unsigned char status; | 1815 | unsigned char status; |
1797 | unsigned long flags; | 1816 | unsigned long flags; |
1798 | struct uart_8250_port *up = up_to_u8250p(port); | 1817 | struct uart_8250_port *up = up_to_u8250p(port); |
1799 | int dma_err = 0; | ||
1800 | 1818 | ||
1801 | if (iir & UART_IIR_NO_INT) | 1819 | if (iir & UART_IIR_NO_INT) |
1802 | return 0; | 1820 | return 0; |
@@ -1808,15 +1826,11 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1808 | DEBUG_INTR("status = %x...", status); | 1826 | DEBUG_INTR("status = %x...", status); |
1809 | 1827 | ||
1810 | if (status & (UART_LSR_DR | UART_LSR_BI)) { | 1828 | if (status & (UART_LSR_DR | UART_LSR_BI)) { |
1811 | if (up->dma) | 1829 | if (!up->dma || handle_rx_dma(up, iir)) |
1812 | dma_err = up->dma->rx_dma(up, iir); | ||
1813 | |||
1814 | if (!up->dma || dma_err) | ||
1815 | status = serial8250_rx_chars(up, status); | 1830 | status = serial8250_rx_chars(up, status); |
1816 | } | 1831 | } |
1817 | serial8250_modem_status(up); | 1832 | serial8250_modem_status(up); |
1818 | if ((!up->dma || (up->dma && up->dma->tx_err)) && | 1833 | if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE)) |
1819 | (status & UART_LSR_THRE)) | ||
1820 | serial8250_tx_chars(up); | 1834 | serial8250_tx_chars(up); |
1821 | 1835 | ||
1822 | spin_unlock_irqrestore(&port->lock, flags); | 1836 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -1882,7 +1896,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
1882 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; | 1896 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; |
1883 | } | 1897 | } |
1884 | 1898 | ||
1885 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1899 | unsigned int serial8250_do_get_mctrl(struct uart_port *port) |
1886 | { | 1900 | { |
1887 | struct uart_8250_port *up = up_to_u8250p(port); | 1901 | struct uart_8250_port *up = up_to_u8250p(port); |
1888 | unsigned int status; | 1902 | unsigned int status; |
@@ -1903,6 +1917,14 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) | |||
1903 | ret |= TIOCM_CTS; | 1917 | ret |= TIOCM_CTS; |
1904 | return ret; | 1918 | return ret; |
1905 | } | 1919 | } |
1920 | EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); | ||
1921 | |||
1922 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | ||
1923 | { | ||
1924 | if (port->get_mctrl) | ||
1925 | return port->get_mctrl(port); | ||
1926 | return serial8250_do_get_mctrl(port); | ||
1927 | } | ||
1906 | 1928 | ||
1907 | void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) | 1929 | void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) |
1908 | { | 1930 | { |
diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index 1b7bd26555b7..efd1f9c047b1 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c | |||
@@ -209,7 +209,7 @@ static int uniphier_uart_probe(struct platform_device *pdev) | |||
209 | 209 | ||
210 | irq = platform_get_irq(pdev, 0); | 210 | irq = platform_get_irq(pdev, 0); |
211 | if (irq < 0) { | 211 | if (irq < 0) { |
212 | dev_err(dev, "failed to get IRQ number"); | 212 | dev_err(dev, "failed to get IRQ number\n"); |
213 | return irq; | 213 | return irq; |
214 | } | 214 | } |
215 | 215 | ||
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 4d7cb9c04fce..e46761d20f7b 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -57,6 +57,18 @@ config SERIAL_8250_PNP | |||
57 | This builds standard PNP serial support. You may be able to | 57 | This builds standard PNP serial support. You may be able to |
58 | disable this feature if you only need legacy serial support. | 58 | disable this feature if you only need legacy serial support. |
59 | 59 | ||
60 | config SERIAL_8250_FINTEK | ||
61 | bool "Support for Fintek F81216A LPC to 4 UART RS485 API" | ||
62 | depends on SERIAL_8250 | ||
63 | ---help--- | ||
64 | Selecting this option will add support for the RS485 capabilities | ||
65 | of the Fintek F81216A LPC to 4 UART. | ||
66 | |||
67 | If this option is not selected the device will be configured as a | ||
68 | standard 16550A serial port. | ||
69 | |||
70 | If unsure, say N. | ||
71 | |||
60 | config SERIAL_8250_CONSOLE | 72 | config SERIAL_8250_CONSOLE |
61 | bool "Console on 8250/16550 and compatible serial port" | 73 | bool "Console on 8250/16550 and compatible serial port" |
62 | depends on SERIAL_8250=y | 74 | depends on SERIAL_8250=y |
@@ -358,14 +370,6 @@ config SERIAL_8250_OMAP_TTYO_FIXUP | |||
358 | not booting kernel because the serial console remains silent in case | 370 | not booting kernel because the serial console remains silent in case |
359 | they forgot to update the command line. | 371 | they forgot to update the command line. |
360 | 372 | ||
361 | config SERIAL_8250_FINTEK | ||
362 | tristate "Support for Fintek F81216A LPC to 4 UART" | ||
363 | depends on SERIAL_8250 && PNP | ||
364 | help | ||
365 | Selecting this option will add support for the Fintek F81216A | ||
366 | LPC to 4 UART. This device has some RS485 functionality not available | ||
367 | through the PNP driver. If unsure, say N. | ||
368 | |||
369 | config SERIAL_8250_LPC18XX | 373 | config SERIAL_8250_LPC18XX |
370 | tristate "NXP LPC18xx/43xx serial port support" | 374 | tristate "NXP LPC18xx/43xx serial port support" |
371 | depends on SERIAL_8250 && OF && (ARCH_LPC18XX || COMPILE_TEST) | 375 | depends on SERIAL_8250 && OF && (ARCH_LPC18XX || COMPILE_TEST) |
@@ -398,8 +402,10 @@ config SERIAL_8250_INGENIC | |||
398 | its UARTs, say Y to this option. If unsure, say N. | 402 | its UARTs, say Y to this option. If unsure, say N. |
399 | 403 | ||
400 | config SERIAL_8250_MID | 404 | config SERIAL_8250_MID |
401 | tristate "Support for serial ports on Intel MID platforms" | 405 | tristate "Support for serial ports on Intel MID platforms" if EXPERT |
406 | default SERIAL_8250 | ||
402 | depends on SERIAL_8250 && PCI | 407 | depends on SERIAL_8250 && PCI |
408 | depends on X86 || COMPILE_TEST | ||
403 | select HSU_DMA if SERIAL_8250_DMA | 409 | select HSU_DMA if SERIAL_8250_DMA |
404 | select HSU_DMA_PCI if (HSU_DMA && X86_INTEL_MID) | 410 | select HSU_DMA_PCI if (HSU_DMA && X86_INTEL_MID) |
405 | select RATIONAL | 411 | select RATIONAL |
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index c9a2d6ed87e9..367d403d28d5 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o | |||
7 | 8250-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o | 7 | 8250-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o |
8 | 8250_base-y := 8250_port.o | 8 | 8250_base-y := 8250_port.o |
9 | 8250_base-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o | 9 | 8250_base-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o |
10 | 8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o | ||
10 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o | 11 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o |
11 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o | 12 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o |
12 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o | 13 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o |
@@ -23,7 +24,6 @@ obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o | |||
23 | obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o | 24 | obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o |
24 | obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o | 25 | obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o |
25 | obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o | 26 | obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o |
26 | obj-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o | ||
27 | obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o | 27 | obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o |
28 | obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o | 28 | obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o |
29 | obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o | 29 | obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 7711b260dacf..7e3a58c8bb67 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -213,6 +213,7 @@ config SERIAL_MESON_CONSOLE | |||
213 | bool "Support for console on meson" | 213 | bool "Support for console on meson" |
214 | depends on SERIAL_MESON=y | 214 | depends on SERIAL_MESON=y |
215 | select SERIAL_CORE_CONSOLE | 215 | select SERIAL_CORE_CONSOLE |
216 | select SERIAL_EARLYCON | ||
216 | help | 217 | help |
217 | Say Y here if you wish to use a Amlogic MesonX UART as the | 218 | Say Y here if you wish to use a Amlogic MesonX UART as the |
218 | system console (the system console is the device which | 219 | system console (the system console is the device which |
@@ -1404,11 +1405,12 @@ config SERIAL_PCH_UART_CONSOLE | |||
1404 | config SERIAL_MXS_AUART | 1405 | config SERIAL_MXS_AUART |
1405 | tristate "MXS AUART support" | 1406 | tristate "MXS AUART support" |
1406 | depends on HAS_DMA | 1407 | depends on HAS_DMA |
1407 | depends on ARCH_MXS || COMPILE_TEST | 1408 | depends on ARCH_MXS || MACH_ASM9260 || COMPILE_TEST |
1408 | select SERIAL_CORE | 1409 | select SERIAL_CORE |
1409 | select SERIAL_MCTRL_GPIO if GPIOLIB | 1410 | select SERIAL_MCTRL_GPIO if GPIOLIB |
1410 | help | 1411 | help |
1411 | This driver supports the MXS Application UART (AUART) port. | 1412 | This driver supports the MXS and Alphascale ASM9260 Application |
1413 | UART (AUART) port. | ||
1412 | 1414 | ||
1413 | config SERIAL_MXS_AUART_CONSOLE | 1415 | config SERIAL_MXS_AUART_CONSOLE |
1414 | bool "MXS AUART console support" | 1416 | bool "MXS AUART console support" |
@@ -1467,6 +1469,19 @@ config SERIAL_EFM32_UART | |||
1467 | This driver support the USART and UART ports on | 1469 | This driver support the USART and UART ports on |
1468 | Energy Micro's efm32 SoCs. | 1470 | Energy Micro's efm32 SoCs. |
1469 | 1471 | ||
1472 | config SERIAL_MPS2_UART_CONSOLE | ||
1473 | bool "MPS2 UART console support" | ||
1474 | depends on SERIAL_MPS2_UART | ||
1475 | select SERIAL_CORE_CONSOLE | ||
1476 | select SERIAL_EARLYCON | ||
1477 | |||
1478 | config SERIAL_MPS2_UART | ||
1479 | bool "MPS2 UART port" | ||
1480 | depends on ARM || COMPILE_TEST | ||
1481 | select SERIAL_CORE | ||
1482 | help | ||
1483 | This driver support the UART ports on ARM MPS2. | ||
1484 | |||
1470 | config SERIAL_EFM32_UART_CONSOLE | 1485 | config SERIAL_EFM32_UART_CONSOLE |
1471 | bool "EFM32 UART/USART console support" | 1486 | bool "EFM32 UART/USART console support" |
1472 | depends on SERIAL_EFM32_UART=y | 1487 | depends on SERIAL_EFM32_UART=y |
@@ -1625,6 +1640,7 @@ config SERIAL_STM32_CONSOLE | |||
1625 | 1640 | ||
1626 | config SERIAL_MVEBU_UART | 1641 | config SERIAL_MVEBU_UART |
1627 | bool "Marvell EBU serial port support" | 1642 | bool "Marvell EBU serial port support" |
1643 | depends on ARCH_MVEBU || COMPILE_TEST | ||
1628 | select SERIAL_CORE | 1644 | select SERIAL_CORE |
1629 | help | 1645 | help |
1630 | This driver is for Marvell EBU SoC's UART. If you have a machine | 1646 | This driver is for Marvell EBU SoC's UART. If you have a machine |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 74914aafac61..1278d376da50 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -92,6 +92,7 @@ obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o | |||
92 | obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o | 92 | obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o |
93 | obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o | 93 | obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o |
94 | obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o | 94 | obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o |
95 | obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o | ||
95 | 96 | ||
96 | # GPIOLIB helpers for modem control lines | 97 | # GPIOLIB helpers for modem control lines |
97 | obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o | 98 | obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 7c198e0a3178..a2aa655f56c4 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -121,6 +121,7 @@ static struct vendor_data vendor_arm = { | |||
121 | 121 | ||
122 | static struct vendor_data vendor_sbsa = { | 122 | static struct vendor_data vendor_sbsa = { |
123 | .reg_offset = pl011_std_offsets, | 123 | .reg_offset = pl011_std_offsets, |
124 | .access_32b = true, | ||
124 | .oversampling = false, | 125 | .oversampling = false, |
125 | .dma_threshold = false, | 126 | .dma_threshold = false, |
126 | .cts_event_workaround = false, | 127 | .cts_event_workaround = false, |
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index d9439e6ab719..954941dd8124 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -274,6 +274,13 @@ static bool atmel_use_dma_rx(struct uart_port *port) | |||
274 | return atmel_port->use_dma_rx; | 274 | return atmel_port->use_dma_rx; |
275 | } | 275 | } |
276 | 276 | ||
277 | static bool atmel_use_fifo(struct uart_port *port) | ||
278 | { | ||
279 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
280 | |||
281 | return atmel_port->fifo_size; | ||
282 | } | ||
283 | |||
277 | static unsigned int atmel_get_lines_status(struct uart_port *port) | 284 | static unsigned int atmel_get_lines_status(struct uart_port *port) |
278 | { | 285 | { |
279 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 286 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
@@ -2090,7 +2097,12 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2090 | mode |= ATMEL_US_USMODE_RS485; | 2097 | mode |= ATMEL_US_USMODE_RS485; |
2091 | } else if (termios->c_cflag & CRTSCTS) { | 2098 | } else if (termios->c_cflag & CRTSCTS) { |
2092 | /* RS232 with hardware handshake (RTS/CTS) */ | 2099 | /* RS232 with hardware handshake (RTS/CTS) */ |
2093 | mode |= ATMEL_US_USMODE_HWHS; | 2100 | if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) { |
2101 | dev_info(port->dev, "not enabling hardware flow control because DMA is used"); | ||
2102 | termios->c_cflag &= ~CRTSCTS; | ||
2103 | } else { | ||
2104 | mode |= ATMEL_US_USMODE_HWHS; | ||
2105 | } | ||
2094 | } else { | 2106 | } else { |
2095 | /* RS232 without hadware handshake */ | 2107 | /* RS232 without hadware handshake */ |
2096 | mode |= ATMEL_US_USMODE_NORMAL; | 2108 | mode |= ATMEL_US_USMODE_NORMAL; |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index c0172bf54a9b..315c84979b18 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -2599,7 +2599,7 @@ startup(struct e100_serial * info) | |||
2599 | 2599 | ||
2600 | /* if it was already initialized, skip this */ | 2600 | /* if it was already initialized, skip this */ |
2601 | 2601 | ||
2602 | if (info->port.flags & ASYNC_INITIALIZED) { | 2602 | if (tty_port_initialized(&info->port)) { |
2603 | local_irq_restore(flags); | 2603 | local_irq_restore(flags); |
2604 | free_page(xmit_page); | 2604 | free_page(xmit_page); |
2605 | return 0; | 2605 | return 0; |
@@ -2703,7 +2703,7 @@ startup(struct e100_serial * info) | |||
2703 | e100_rts(info, 1); | 2703 | e100_rts(info, 1); |
2704 | e100_dtr(info, 1); | 2704 | e100_dtr(info, 1); |
2705 | 2705 | ||
2706 | info->port.flags |= ASYNC_INITIALIZED; | 2706 | tty_port_set_initialized(&info->port, 1); |
2707 | 2707 | ||
2708 | local_irq_restore(flags); | 2708 | local_irq_restore(flags); |
2709 | return 0; | 2709 | return 0; |
@@ -2745,7 +2745,7 @@ shutdown(struct e100_serial * info) | |||
2745 | info->tr_running = 0; | 2745 | info->tr_running = 0; |
2746 | } | 2746 | } |
2747 | 2747 | ||
2748 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 2748 | if (!tty_port_initialized(&info->port)) |
2749 | return; | 2749 | return; |
2750 | 2750 | ||
2751 | #ifdef SERIAL_DEBUG_OPEN | 2751 | #ifdef SERIAL_DEBUG_OPEN |
@@ -2776,7 +2776,7 @@ shutdown(struct e100_serial * info) | |||
2776 | if (info->port.tty) | 2776 | if (info->port.tty) |
2777 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 2777 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
2778 | 2778 | ||
2779 | info->port.flags &= ~ASYNC_INITIALIZED; | 2779 | tty_port_set_initialized(&info->port, 0); |
2780 | local_irq_restore(flags); | 2780 | local_irq_restore(flags); |
2781 | } | 2781 | } |
2782 | 2782 | ||
@@ -3273,9 +3273,9 @@ set_serial_info(struct e100_serial *info, | |||
3273 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 3273 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
3274 | 3274 | ||
3275 | check_and_exit: | 3275 | check_and_exit: |
3276 | if (info->port.flags & ASYNC_INITIALIZED) { | 3276 | if (tty_port_initialized(&info->port)) |
3277 | change_speed(info); | 3277 | change_speed(info); |
3278 | } else | 3278 | else |
3279 | retval = startup(info); | 3279 | retval = startup(info); |
3280 | return retval; | 3280 | return retval; |
3281 | } | 3281 | } |
@@ -3445,7 +3445,7 @@ rs_ioctl(struct tty_struct *tty, | |||
3445 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 3445 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
3446 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && | 3446 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && |
3447 | (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { | 3447 | (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { |
3448 | if (tty->flags & (1 << TTY_IO_ERROR)) | 3448 | if (tty_io_error(tty)) |
3449 | return -EIO; | 3449 | return -EIO; |
3450 | } | 3450 | } |
3451 | 3451 | ||
@@ -3628,7 +3628,7 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3628 | e100_disable_rx(info); | 3628 | e100_disable_rx(info); |
3629 | e100_disable_rx_irq(info); | 3629 | e100_disable_rx_irq(info); |
3630 | 3630 | ||
3631 | if (info->port.flags & ASYNC_INITIALIZED) { | 3631 | if (tty_port_initialized(&info->port)) { |
3632 | /* | 3632 | /* |
3633 | * Before we drop DTR, make sure the UART transmitter | 3633 | * Before we drop DTR, make sure the UART transmitter |
3634 | * has completely drained; this is especially | 3634 | * has completely drained; this is especially |
@@ -3648,8 +3648,8 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3648 | schedule_timeout_interruptible(info->port.close_delay); | 3648 | schedule_timeout_interruptible(info->port.close_delay); |
3649 | wake_up_interruptible(&info->port.open_wait); | 3649 | wake_up_interruptible(&info->port.open_wait); |
3650 | } | 3650 | } |
3651 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | ||
3652 | local_irq_restore(flags); | 3651 | local_irq_restore(flags); |
3652 | tty_port_set_active(&info->port, 0); | ||
3653 | 3653 | ||
3654 | /* port closed */ | 3654 | /* port closed */ |
3655 | 3655 | ||
@@ -3732,7 +3732,7 @@ rs_hangup(struct tty_struct *tty) | |||
3732 | shutdown(info); | 3732 | shutdown(info); |
3733 | info->event = 0; | 3733 | info->event = 0; |
3734 | info->port.count = 0; | 3734 | info->port.count = 0; |
3735 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 3735 | tty_port_set_active(&info->port, 0); |
3736 | info->port.tty = NULL; | 3736 | info->port.tty = NULL; |
3737 | wake_up_interruptible(&info->port.open_wait); | 3737 | wake_up_interruptible(&info->port.open_wait); |
3738 | } | 3738 | } |
@@ -3755,9 +3755,8 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3755 | * If non-blocking mode is set, or the port is not enabled, | 3755 | * If non-blocking mode is set, or the port is not enabled, |
3756 | * then make the check up front and then exit. | 3756 | * then make the check up front and then exit. |
3757 | */ | 3757 | */ |
3758 | if ((filp->f_flags & O_NONBLOCK) || | 3758 | if ((filp->f_flags & O_NONBLOCK) || tty_io_error(tty)) { |
3759 | (tty->flags & (1 << TTY_IO_ERROR))) { | 3759 | tty_port_set_active(&info->port, 1); |
3760 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | ||
3761 | return 0; | 3760 | return 0; |
3762 | } | 3761 | } |
3763 | 3762 | ||
@@ -3788,8 +3787,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3788 | e100_dtr(info, 1); | 3787 | e100_dtr(info, 1); |
3789 | local_irq_restore(flags); | 3788 | local_irq_restore(flags); |
3790 | set_current_state(TASK_INTERRUPTIBLE); | 3789 | set_current_state(TASK_INTERRUPTIBLE); |
3791 | if (tty_hung_up_p(filp) || | 3790 | if (tty_hung_up_p(filp) || !tty_port_initialized(&info->port)) { |
3792 | !(info->port.flags & ASYNC_INITIALIZED)) { | ||
3793 | #ifdef SERIAL_DO_RESTART | 3791 | #ifdef SERIAL_DO_RESTART |
3794 | if (info->port.flags & ASYNC_HUP_NOTIFY) | 3792 | if (info->port.flags & ASYNC_HUP_NOTIFY) |
3795 | retval = -EAGAIN; | 3793 | retval = -EAGAIN; |
@@ -3826,7 +3824,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3826 | #endif | 3824 | #endif |
3827 | if (retval) | 3825 | if (retval) |
3828 | return retval; | 3826 | return retval; |
3829 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 3827 | tty_port_set_active(&info->port, 1); |
3830 | return 0; | 3828 | return 0; |
3831 | } | 3829 | } |
3832 | 3830 | ||
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 2085a6cfa44b..d386346248de 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -651,7 +651,7 @@ static void ifx_spi_complete(void *ctx) | |||
651 | struct ifx_spi_device *ifx_dev = ctx; | 651 | struct ifx_spi_device *ifx_dev = ctx; |
652 | int length; | 652 | int length; |
653 | int actual_length; | 653 | int actual_length; |
654 | unsigned char more; | 654 | unsigned char more = 0; |
655 | unsigned char cts; | 655 | unsigned char cts; |
656 | int local_write_pending = 0; | 656 | int local_write_pending = 0; |
657 | int queue_length; | 657 | int queue_length; |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 231e7d5caf6c..0df2b1c091ae 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -114,6 +114,7 @@ | |||
114 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ | 114 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ |
115 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ | 115 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ |
116 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ | 116 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ |
117 | #define UCR3_DTRDEN (1<<3) /* Data Terminal Ready Delta Enable. */ | ||
117 | #define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */ | 118 | #define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */ |
118 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ | 119 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ |
119 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ | 120 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ |
@@ -142,7 +143,7 @@ | |||
142 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ | 143 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ |
143 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ | 144 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ |
144 | #define USR1_AGTIM (1<<8) /* Ageing timer interrupt flag */ | 145 | #define USR1_AGTIM (1<<8) /* Ageing timer interrupt flag */ |
145 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ | 146 | #define USR1_DTRD (1<<7) /* DTR Delta */ |
146 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ | 147 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ |
147 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ | 148 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ |
148 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ | 149 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ |
@@ -361,6 +362,7 @@ static void imx_stop_tx(struct uart_port *port) | |||
361 | imx_port_rts_inactive(sport, &temp); | 362 | imx_port_rts_inactive(sport, &temp); |
362 | else | 363 | else |
363 | imx_port_rts_active(sport, &temp); | 364 | imx_port_rts_active(sport, &temp); |
365 | temp |= UCR2_RXEN; | ||
364 | writel(temp, port->membase + UCR2); | 366 | writel(temp, port->membase + UCR2); |
365 | 367 | ||
366 | temp = readl(port->membase + UCR4); | 368 | temp = readl(port->membase + UCR4); |
@@ -568,6 +570,8 @@ static void imx_start_tx(struct uart_port *port) | |||
568 | imx_port_rts_inactive(sport, &temp); | 570 | imx_port_rts_inactive(sport, &temp); |
569 | else | 571 | else |
570 | imx_port_rts_active(sport, &temp); | 572 | imx_port_rts_active(sport, &temp); |
573 | if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) | ||
574 | temp &= ~UCR2_RXEN; | ||
571 | writel(temp, port->membase + UCR2); | 575 | writel(temp, port->membase + UCR2); |
572 | 576 | ||
573 | /* enable transmitter and shifter empty irq */ | 577 | /* enable transmitter and shifter empty irq */ |
@@ -729,11 +733,61 @@ static void imx_dma_rxint(struct imx_port *sport) | |||
729 | spin_unlock_irqrestore(&sport->port.lock, flags); | 733 | spin_unlock_irqrestore(&sport->port.lock, flags); |
730 | } | 734 | } |
731 | 735 | ||
736 | /* | ||
737 | * We have a modem side uart, so the meanings of RTS and CTS are inverted. | ||
738 | */ | ||
739 | static unsigned int imx_get_hwmctrl(struct imx_port *sport) | ||
740 | { | ||
741 | unsigned int tmp = TIOCM_DSR; | ||
742 | unsigned usr1 = readl(sport->port.membase + USR1); | ||
743 | |||
744 | if (usr1 & USR1_RTSS) | ||
745 | tmp |= TIOCM_CTS; | ||
746 | |||
747 | /* in DCE mode DCDIN is always 0 */ | ||
748 | if (!(usr1 & USR2_DCDIN)) | ||
749 | tmp |= TIOCM_CAR; | ||
750 | |||
751 | if (sport->dte_mode) | ||
752 | if (!(readl(sport->port.membase + USR2) & USR2_RIIN)) | ||
753 | tmp |= TIOCM_RI; | ||
754 | |||
755 | return tmp; | ||
756 | } | ||
757 | |||
758 | /* | ||
759 | * Handle any change of modem status signal since we were last called. | ||
760 | */ | ||
761 | static void imx_mctrl_check(struct imx_port *sport) | ||
762 | { | ||
763 | unsigned int status, changed; | ||
764 | |||
765 | status = imx_get_hwmctrl(sport); | ||
766 | changed = status ^ sport->old_status; | ||
767 | |||
768 | if (changed == 0) | ||
769 | return; | ||
770 | |||
771 | sport->old_status = status; | ||
772 | |||
773 | if (changed & TIOCM_RI && status & TIOCM_RI) | ||
774 | sport->port.icount.rng++; | ||
775 | if (changed & TIOCM_DSR) | ||
776 | sport->port.icount.dsr++; | ||
777 | if (changed & TIOCM_CAR) | ||
778 | uart_handle_dcd_change(&sport->port, status & TIOCM_CAR); | ||
779 | if (changed & TIOCM_CTS) | ||
780 | uart_handle_cts_change(&sport->port, status & TIOCM_CTS); | ||
781 | |||
782 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); | ||
783 | } | ||
784 | |||
732 | static irqreturn_t imx_int(int irq, void *dev_id) | 785 | static irqreturn_t imx_int(int irq, void *dev_id) |
733 | { | 786 | { |
734 | struct imx_port *sport = dev_id; | 787 | struct imx_port *sport = dev_id; |
735 | unsigned int sts; | 788 | unsigned int sts; |
736 | unsigned int sts2; | 789 | unsigned int sts2; |
790 | irqreturn_t ret = IRQ_NONE; | ||
737 | 791 | ||
738 | sts = readl(sport->port.membase + USR1); | 792 | sts = readl(sport->port.membase + USR1); |
739 | sts2 = readl(sport->port.membase + USR2); | 793 | sts2 = readl(sport->port.membase + USR2); |
@@ -743,26 +797,47 @@ static irqreturn_t imx_int(int irq, void *dev_id) | |||
743 | imx_dma_rxint(sport); | 797 | imx_dma_rxint(sport); |
744 | else | 798 | else |
745 | imx_rxint(irq, dev_id); | 799 | imx_rxint(irq, dev_id); |
800 | ret = IRQ_HANDLED; | ||
746 | } | 801 | } |
747 | 802 | ||
748 | if ((sts & USR1_TRDY && | 803 | if ((sts & USR1_TRDY && |
749 | readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) || | 804 | readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) || |
750 | (sts2 & USR2_TXDC && | 805 | (sts2 & USR2_TXDC && |
751 | readl(sport->port.membase + UCR4) & UCR4_TCEN)) | 806 | readl(sport->port.membase + UCR4) & UCR4_TCEN)) { |
752 | imx_txint(irq, dev_id); | 807 | imx_txint(irq, dev_id); |
808 | ret = IRQ_HANDLED; | ||
809 | } | ||
810 | |||
811 | if (sts & USR1_DTRD) { | ||
812 | unsigned long flags; | ||
813 | |||
814 | if (sts & USR1_DTRD) | ||
815 | writel(USR1_DTRD, sport->port.membase + USR1); | ||
816 | |||
817 | spin_lock_irqsave(&sport->port.lock, flags); | ||
818 | imx_mctrl_check(sport); | ||
819 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
753 | 820 | ||
754 | if (sts & USR1_RTSD) | 821 | ret = IRQ_HANDLED; |
822 | } | ||
823 | |||
824 | if (sts & USR1_RTSD) { | ||
755 | imx_rtsint(irq, dev_id); | 825 | imx_rtsint(irq, dev_id); |
826 | ret = IRQ_HANDLED; | ||
827 | } | ||
756 | 828 | ||
757 | if (sts & USR1_AWAKE) | 829 | if (sts & USR1_AWAKE) { |
758 | writel(USR1_AWAKE, sport->port.membase + USR1); | 830 | writel(USR1_AWAKE, sport->port.membase + USR1); |
831 | ret = IRQ_HANDLED; | ||
832 | } | ||
759 | 833 | ||
760 | if (sts2 & USR2_ORE) { | 834 | if (sts2 & USR2_ORE) { |
761 | sport->port.icount.overrun++; | 835 | sport->port.icount.overrun++; |
762 | writel(USR2_ORE, sport->port.membase + USR2); | 836 | writel(USR2_ORE, sport->port.membase + USR2); |
837 | ret = IRQ_HANDLED; | ||
763 | } | 838 | } |
764 | 839 | ||
765 | return IRQ_HANDLED; | 840 | return ret; |
766 | } | 841 | } |
767 | 842 | ||
768 | /* | 843 | /* |
@@ -782,28 +857,6 @@ static unsigned int imx_tx_empty(struct uart_port *port) | |||
782 | return ret; | 857 | return ret; |
783 | } | 858 | } |
784 | 859 | ||
785 | /* | ||
786 | * We have a modem side uart, so the meanings of RTS and CTS are inverted. | ||
787 | */ | ||
788 | static unsigned int imx_get_hwmctrl(struct imx_port *sport) | ||
789 | { | ||
790 | unsigned int tmp = TIOCM_DSR; | ||
791 | unsigned usr1 = readl(sport->port.membase + USR1); | ||
792 | |||
793 | if (usr1 & USR1_RTSS) | ||
794 | tmp |= TIOCM_CTS; | ||
795 | |||
796 | /* in DCE mode DCDIN is always 0 */ | ||
797 | if (!(usr1 & USR2_DCDIN)) | ||
798 | tmp |= TIOCM_CAR; | ||
799 | |||
800 | /* in DCE mode RIIN is always 0 */ | ||
801 | if (readl(sport->port.membase + USR2) & USR2_RIIN) | ||
802 | tmp |= TIOCM_RI; | ||
803 | |||
804 | return tmp; | ||
805 | } | ||
806 | |||
807 | static unsigned int imx_get_mctrl(struct uart_port *port) | 860 | static unsigned int imx_get_mctrl(struct uart_port *port) |
808 | { | 861 | { |
809 | struct imx_port *sport = (struct imx_port *)port; | 862 | struct imx_port *sport = (struct imx_port *)port; |
@@ -861,33 +914,6 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
861 | } | 914 | } |
862 | 915 | ||
863 | /* | 916 | /* |
864 | * Handle any change of modem status signal since we were last called. | ||
865 | */ | ||
866 | static void imx_mctrl_check(struct imx_port *sport) | ||
867 | { | ||
868 | unsigned int status, changed; | ||
869 | |||
870 | status = imx_get_hwmctrl(sport); | ||
871 | changed = status ^ sport->old_status; | ||
872 | |||
873 | if (changed == 0) | ||
874 | return; | ||
875 | |||
876 | sport->old_status = status; | ||
877 | |||
878 | if (changed & TIOCM_RI) | ||
879 | sport->port.icount.rng++; | ||
880 | if (changed & TIOCM_DSR) | ||
881 | sport->port.icount.dsr++; | ||
882 | if (changed & TIOCM_CAR) | ||
883 | uart_handle_dcd_change(&sport->port, status & TIOCM_CAR); | ||
884 | if (changed & TIOCM_CTS) | ||
885 | uart_handle_cts_change(&sport->port, status & TIOCM_CTS); | ||
886 | |||
887 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); | ||
888 | } | ||
889 | |||
890 | /* | ||
891 | * This is our per-port timeout handler, for checking the | 917 | * This is our per-port timeout handler, for checking the |
892 | * modem status signals. | 918 | * modem status signals. |
893 | */ | 919 | */ |
@@ -1193,7 +1219,7 @@ static int imx_startup(struct uart_port *port) | |||
1193 | /* | 1219 | /* |
1194 | * Finally, clear and enable interrupts | 1220 | * Finally, clear and enable interrupts |
1195 | */ | 1221 | */ |
1196 | writel(USR1_RTSD, sport->port.membase + USR1); | 1222 | writel(USR1_RTSD | USR1_DTRD, sport->port.membase + USR1); |
1197 | writel(USR2_ORE, sport->port.membase + USR2); | 1223 | writel(USR2_ORE, sport->port.membase + USR2); |
1198 | 1224 | ||
1199 | if (sport->dma_is_inited && !sport->dma_is_enabled) | 1225 | if (sport->dma_is_inited && !sport->dma_is_enabled) |
@@ -1212,11 +1238,32 @@ static int imx_startup(struct uart_port *port) | |||
1212 | temp |= (UCR2_RXEN | UCR2_TXEN); | 1238 | temp |= (UCR2_RXEN | UCR2_TXEN); |
1213 | if (!sport->have_rtscts) | 1239 | if (!sport->have_rtscts) |
1214 | temp |= UCR2_IRTS; | 1240 | temp |= UCR2_IRTS; |
1241 | /* | ||
1242 | * make sure the edge sensitive RTS-irq is disabled, | ||
1243 | * we're using RTSD instead. | ||
1244 | */ | ||
1245 | if (!is_imx1_uart(sport)) | ||
1246 | temp &= ~UCR2_RTSEN; | ||
1215 | writel(temp, sport->port.membase + UCR2); | 1247 | writel(temp, sport->port.membase + UCR2); |
1216 | 1248 | ||
1217 | if (!is_imx1_uart(sport)) { | 1249 | if (!is_imx1_uart(sport)) { |
1218 | temp = readl(sport->port.membase + UCR3); | 1250 | temp = readl(sport->port.membase + UCR3); |
1219 | temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP; | 1251 | |
1252 | /* | ||
1253 | * The effect of RI and DCD differs depending on the UFCR_DCEDTE | ||
1254 | * bit. In DCE mode they control the outputs, in DTE mode they | ||
1255 | * enable the respective irqs. At least the DCD irq cannot be | ||
1256 | * cleared on i.MX25 at least, so it's not usable and must be | ||
1257 | * disabled. I don't have test hardware to check if RI has the | ||
1258 | * same problem but I consider this likely so it's disabled for | ||
1259 | * now, too. | ||
1260 | */ | ||
1261 | temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP | | ||
1262 | UCR3_DTRDEN | UCR3_RI | UCR3_DCD; | ||
1263 | |||
1264 | if (sport->dte_mode) | ||
1265 | temp &= ~(UCR3_RI | UCR3_DCD); | ||
1266 | |||
1220 | writel(temp, sport->port.membase + UCR3); | 1267 | writel(temp, sport->port.membase + UCR3); |
1221 | } | 1268 | } |
1222 | 1269 | ||
@@ -1610,19 +1657,17 @@ static int imx_rs485_config(struct uart_port *port, | |||
1610 | struct serial_rs485 *rs485conf) | 1657 | struct serial_rs485 *rs485conf) |
1611 | { | 1658 | { |
1612 | struct imx_port *sport = (struct imx_port *)port; | 1659 | struct imx_port *sport = (struct imx_port *)port; |
1660 | unsigned long temp; | ||
1613 | 1661 | ||
1614 | /* unimplemented */ | 1662 | /* unimplemented */ |
1615 | rs485conf->delay_rts_before_send = 0; | 1663 | rs485conf->delay_rts_before_send = 0; |
1616 | rs485conf->delay_rts_after_send = 0; | 1664 | rs485conf->delay_rts_after_send = 0; |
1617 | rs485conf->flags |= SER_RS485_RX_DURING_TX; | ||
1618 | 1665 | ||
1619 | /* RTS is required to control the transmitter */ | 1666 | /* RTS is required to control the transmitter */ |
1620 | if (!sport->have_rtscts) | 1667 | if (!sport->have_rtscts) |
1621 | rs485conf->flags &= ~SER_RS485_ENABLED; | 1668 | rs485conf->flags &= ~SER_RS485_ENABLED; |
1622 | 1669 | ||
1623 | if (rs485conf->flags & SER_RS485_ENABLED) { | 1670 | if (rs485conf->flags & SER_RS485_ENABLED) { |
1624 | unsigned long temp; | ||
1625 | |||
1626 | /* disable transmitter */ | 1671 | /* disable transmitter */ |
1627 | temp = readl(sport->port.membase + UCR2); | 1672 | temp = readl(sport->port.membase + UCR2); |
1628 | if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) | 1673 | if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) |
@@ -1632,6 +1677,14 @@ static int imx_rs485_config(struct uart_port *port, | |||
1632 | writel(temp, sport->port.membase + UCR2); | 1677 | writel(temp, sport->port.membase + UCR2); |
1633 | } | 1678 | } |
1634 | 1679 | ||
1680 | /* Make sure Rx is enabled in case Tx is active with Rx disabled */ | ||
1681 | if (!(rs485conf->flags & SER_RS485_ENABLED) || | ||
1682 | rs485conf->flags & SER_RS485_RX_DURING_TX) { | ||
1683 | temp = readl(sport->port.membase + UCR2); | ||
1684 | temp |= UCR2_RXEN; | ||
1685 | writel(temp, sport->port.membase + UCR2); | ||
1686 | } | ||
1687 | |||
1635 | port->rs485 = *rs485conf; | 1688 | port->rs485 = *rs485conf; |
1636 | 1689 | ||
1637 | return 0; | 1690 | return 0; |
@@ -1927,7 +1980,8 @@ static int serial_imx_probe_dt(struct imx_port *sport, | |||
1927 | } | 1980 | } |
1928 | sport->port.line = ret; | 1981 | sport->port.line = ret; |
1929 | 1982 | ||
1930 | if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) | 1983 | if (of_get_property(np, "uart-has-rtscts", NULL) || |
1984 | of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */) | ||
1931 | sport->have_rtscts = 1; | 1985 | sport->have_rtscts = 1; |
1932 | 1986 | ||
1933 | if (of_get_property(np, "fsl,dte-mode", NULL)) | 1987 | if (of_get_property(np, "fsl,dte-mode", NULL)) |
diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 024445aa0521..6aea0f4a9165 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c | |||
@@ -481,18 +481,13 @@ static void meson_console_putchar(struct uart_port *port, int ch) | |||
481 | writel(ch, port->membase + AML_UART_WFIFO); | 481 | writel(ch, port->membase + AML_UART_WFIFO); |
482 | } | 482 | } |
483 | 483 | ||
484 | static void meson_serial_console_write(struct console *co, const char *s, | 484 | static void meson_serial_port_write(struct uart_port *port, const char *s, |
485 | u_int count) | 485 | u_int count) |
486 | { | 486 | { |
487 | struct uart_port *port; | ||
488 | unsigned long flags; | 487 | unsigned long flags; |
489 | int locked; | 488 | int locked; |
490 | u32 val, tmp; | 489 | u32 val, tmp; |
491 | 490 | ||
492 | port = meson_ports[co->index]; | ||
493 | if (!port) | ||
494 | return; | ||
495 | |||
496 | local_irq_save(flags); | 491 | local_irq_save(flags); |
497 | if (port->sysrq) { | 492 | if (port->sysrq) { |
498 | locked = 0; | 493 | locked = 0; |
@@ -516,6 +511,18 @@ static void meson_serial_console_write(struct console *co, const char *s, | |||
516 | local_irq_restore(flags); | 511 | local_irq_restore(flags); |
517 | } | 512 | } |
518 | 513 | ||
514 | static void meson_serial_console_write(struct console *co, const char *s, | ||
515 | u_int count) | ||
516 | { | ||
517 | struct uart_port *port; | ||
518 | |||
519 | port = meson_ports[co->index]; | ||
520 | if (!port) | ||
521 | return; | ||
522 | |||
523 | meson_serial_port_write(port, s, count); | ||
524 | } | ||
525 | |||
519 | static int meson_serial_console_setup(struct console *co, char *options) | 526 | static int meson_serial_console_setup(struct console *co, char *options) |
520 | { | 527 | { |
521 | struct uart_port *port; | 528 | struct uart_port *port; |
@@ -554,6 +561,27 @@ static int __init meson_serial_console_init(void) | |||
554 | } | 561 | } |
555 | console_initcall(meson_serial_console_init); | 562 | console_initcall(meson_serial_console_init); |
556 | 563 | ||
564 | static void meson_serial_early_console_write(struct console *co, | ||
565 | const char *s, | ||
566 | u_int count) | ||
567 | { | ||
568 | struct earlycon_device *dev = co->data; | ||
569 | |||
570 | meson_serial_port_write(&dev->port, s, count); | ||
571 | } | ||
572 | |||
573 | static int __init | ||
574 | meson_serial_early_console_setup(struct earlycon_device *device, const char *opt) | ||
575 | { | ||
576 | if (!device->port.membase) | ||
577 | return -ENODEV; | ||
578 | |||
579 | device->con->write = meson_serial_early_console_write; | ||
580 | return 0; | ||
581 | } | ||
582 | OF_EARLYCON_DECLARE(meson, "amlogic,meson-uart", | ||
583 | meson_serial_early_console_setup); | ||
584 | |||
557 | #define MESON_SERIAL_CONSOLE (&meson_serial_console) | 585 | #define MESON_SERIAL_CONSOLE (&meson_serial_console) |
558 | #else | 586 | #else |
559 | #define MESON_SERIAL_CONSOLE NULL | 587 | #define MESON_SERIAL_CONSOLE NULL |
diff --git a/drivers/tty/serial/mps2-uart.c b/drivers/tty/serial/mps2-uart.c new file mode 100644 index 000000000000..da9e27d3c263 --- /dev/null +++ b/drivers/tty/serial/mps2-uart.c | |||
@@ -0,0 +1,625 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 ARM Limited | ||
3 | * | ||
4 | * Author: Vladimir Murzin <vladimir.murzin@arm.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * TODO: support for SysRq | ||
11 | */ | ||
12 | |||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
14 | |||
15 | #include <linux/bitops.h> | ||
16 | #include <linux/clk.h> | ||
17 | #include <linux/console.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/of_device.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/serial_core.h> | ||
25 | #include <linux/tty_flip.h> | ||
26 | #include <linux/types.h> | ||
27 | |||
28 | #define SERIAL_NAME "ttyMPS" | ||
29 | #define DRIVER_NAME "mps2-uart" | ||
30 | #define MAKE_NAME(x) (DRIVER_NAME # x) | ||
31 | |||
32 | #define UARTn_DATA 0x00 | ||
33 | |||
34 | #define UARTn_STATE 0x04 | ||
35 | #define UARTn_STATE_TX_FULL BIT(0) | ||
36 | #define UARTn_STATE_RX_FULL BIT(1) | ||
37 | #define UARTn_STATE_TX_OVERRUN BIT(2) | ||
38 | #define UARTn_STATE_RX_OVERRUN BIT(3) | ||
39 | |||
40 | #define UARTn_CTRL 0x08 | ||
41 | #define UARTn_CTRL_TX_ENABLE BIT(0) | ||
42 | #define UARTn_CTRL_RX_ENABLE BIT(1) | ||
43 | #define UARTn_CTRL_TX_INT_ENABLE BIT(2) | ||
44 | #define UARTn_CTRL_RX_INT_ENABLE BIT(3) | ||
45 | #define UARTn_CTRL_TX_OVERRUN_INT_ENABLE BIT(4) | ||
46 | #define UARTn_CTRL_RX_OVERRUN_INT_ENABLE BIT(5) | ||
47 | |||
48 | #define UARTn_INT 0x0c | ||
49 | #define UARTn_INT_TX BIT(0) | ||
50 | #define UARTn_INT_RX BIT(1) | ||
51 | #define UARTn_INT_TX_OVERRUN BIT(2) | ||
52 | #define UARTn_INT_RX_OVERRUN BIT(3) | ||
53 | |||
54 | #define UARTn_BAUDDIV 0x10 | ||
55 | #define UARTn_BAUDDIV_MASK GENMASK(20, 0) | ||
56 | |||
57 | /* | ||
58 | * Helpers to make typical enable/disable operations more readable. | ||
59 | */ | ||
60 | #define UARTn_CTRL_TX_GRP (UARTn_CTRL_TX_ENABLE |\ | ||
61 | UARTn_CTRL_TX_INT_ENABLE |\ | ||
62 | UARTn_CTRL_TX_OVERRUN_INT_ENABLE) | ||
63 | |||
64 | #define UARTn_CTRL_RX_GRP (UARTn_CTRL_RX_ENABLE |\ | ||
65 | UARTn_CTRL_RX_INT_ENABLE |\ | ||
66 | UARTn_CTRL_RX_OVERRUN_INT_ENABLE) | ||
67 | |||
68 | #define MPS2_MAX_PORTS 3 | ||
69 | |||
70 | struct mps2_uart_port { | ||
71 | struct uart_port port; | ||
72 | struct clk *clk; | ||
73 | unsigned int tx_irq; | ||
74 | unsigned int rx_irq; | ||
75 | }; | ||
76 | |||
77 | static inline struct mps2_uart_port *to_mps2_port(struct uart_port *port) | ||
78 | { | ||
79 | return container_of(port, struct mps2_uart_port, port); | ||
80 | } | ||
81 | |||
82 | static void mps2_uart_write8(struct uart_port *port, u8 val, unsigned int off) | ||
83 | { | ||
84 | struct mps2_uart_port *mps_port = to_mps2_port(port); | ||
85 | |||
86 | writeb(val, mps_port->port.membase + off); | ||
87 | } | ||
88 | |||
89 | static u8 mps2_uart_read8(struct uart_port *port, unsigned int off) | ||
90 | { | ||
91 | struct mps2_uart_port *mps_port = to_mps2_port(port); | ||
92 | |||
93 | return readb(mps_port->port.membase + off); | ||
94 | } | ||
95 | |||
96 | static void mps2_uart_write32(struct uart_port *port, u32 val, unsigned int off) | ||
97 | { | ||
98 | struct mps2_uart_port *mps_port = to_mps2_port(port); | ||
99 | |||
100 | writel_relaxed(val, mps_port->port.membase + off); | ||
101 | } | ||
102 | |||
103 | static unsigned int mps2_uart_tx_empty(struct uart_port *port) | ||
104 | { | ||
105 | u8 status = mps2_uart_read8(port, UARTn_STATE); | ||
106 | |||
107 | return (status & UARTn_STATE_TX_FULL) ? 0 : TIOCSER_TEMT; | ||
108 | } | ||
109 | |||
110 | static void mps2_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
111 | { | ||
112 | } | ||
113 | |||
114 | static unsigned int mps2_uart_get_mctrl(struct uart_port *port) | ||
115 | { | ||
116 | return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; | ||
117 | } | ||
118 | |||
119 | static void mps2_uart_stop_tx(struct uart_port *port) | ||
120 | { | ||
121 | u8 control = mps2_uart_read8(port, UARTn_CTRL); | ||
122 | |||
123 | control &= ~UARTn_CTRL_TX_INT_ENABLE; | ||
124 | |||
125 | mps2_uart_write8(port, control, UARTn_CTRL); | ||
126 | } | ||
127 | |||
128 | static void mps2_uart_tx_chars(struct uart_port *port) | ||
129 | { | ||
130 | struct circ_buf *xmit = &port->state->xmit; | ||
131 | |||
132 | while (!(mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL)) { | ||
133 | if (port->x_char) { | ||
134 | mps2_uart_write8(port, port->x_char, UARTn_DATA); | ||
135 | port->x_char = 0; | ||
136 | port->icount.tx++; | ||
137 | continue; | ||
138 | } | ||
139 | |||
140 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | ||
141 | break; | ||
142 | |||
143 | mps2_uart_write8(port, xmit->buf[xmit->tail], UARTn_DATA); | ||
144 | xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE; | ||
145 | port->icount.tx++; | ||
146 | } | ||
147 | |||
148 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
149 | uart_write_wakeup(port); | ||
150 | |||
151 | if (uart_circ_empty(xmit)) | ||
152 | mps2_uart_stop_tx(port); | ||
153 | } | ||
154 | |||
155 | static void mps2_uart_start_tx(struct uart_port *port) | ||
156 | { | ||
157 | u8 control = mps2_uart_read8(port, UARTn_CTRL); | ||
158 | |||
159 | control |= UARTn_CTRL_TX_INT_ENABLE; | ||
160 | |||
161 | mps2_uart_write8(port, control, UARTn_CTRL); | ||
162 | |||
163 | /* | ||
164 | * We've just unmasked the TX IRQ and now slow-starting via | ||
165 | * polling; if there is enough data to fill up the internal | ||
166 | * write buffer in one go, the TX IRQ should assert, at which | ||
167 | * point we switch to fully interrupt-driven TX. | ||
168 | */ | ||
169 | |||
170 | mps2_uart_tx_chars(port); | ||
171 | } | ||
172 | |||
173 | static void mps2_uart_stop_rx(struct uart_port *port) | ||
174 | { | ||
175 | u8 control = mps2_uart_read8(port, UARTn_CTRL); | ||
176 | |||
177 | control &= ~UARTn_CTRL_RX_GRP; | ||
178 | |||
179 | mps2_uart_write8(port, control, UARTn_CTRL); | ||
180 | } | ||
181 | |||
182 | static void mps2_uart_break_ctl(struct uart_port *port, int ctl) | ||
183 | { | ||
184 | } | ||
185 | |||
186 | static void mps2_uart_rx_chars(struct uart_port *port) | ||
187 | { | ||
188 | struct tty_port *tport = &port->state->port; | ||
189 | |||
190 | while (mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_RX_FULL) { | ||
191 | u8 rxdata = mps2_uart_read8(port, UARTn_DATA); | ||
192 | |||
193 | port->icount.rx++; | ||
194 | tty_insert_flip_char(&port->state->port, rxdata, TTY_NORMAL); | ||
195 | } | ||
196 | |||
197 | tty_flip_buffer_push(tport); | ||
198 | } | ||
199 | |||
200 | static irqreturn_t mps2_uart_rxirq(int irq, void *data) | ||
201 | { | ||
202 | struct uart_port *port = data; | ||
203 | u8 irqflag = mps2_uart_read8(port, UARTn_INT); | ||
204 | |||
205 | if (unlikely(!(irqflag & UARTn_INT_RX))) | ||
206 | return IRQ_NONE; | ||
207 | |||
208 | spin_lock(&port->lock); | ||
209 | |||
210 | mps2_uart_write8(port, UARTn_INT_RX, UARTn_INT); | ||
211 | mps2_uart_rx_chars(port); | ||
212 | |||
213 | spin_unlock(&port->lock); | ||
214 | |||
215 | return IRQ_HANDLED; | ||
216 | } | ||
217 | |||
218 | static irqreturn_t mps2_uart_txirq(int irq, void *data) | ||
219 | { | ||
220 | struct uart_port *port = data; | ||
221 | u8 irqflag = mps2_uart_read8(port, UARTn_INT); | ||
222 | |||
223 | if (unlikely(!(irqflag & UARTn_INT_TX))) | ||
224 | return IRQ_NONE; | ||
225 | |||
226 | spin_lock(&port->lock); | ||
227 | |||
228 | mps2_uart_write8(port, UARTn_INT_TX, UARTn_INT); | ||
229 | mps2_uart_tx_chars(port); | ||
230 | |||
231 | spin_unlock(&port->lock); | ||
232 | |||
233 | return IRQ_HANDLED; | ||
234 | } | ||
235 | |||
236 | static irqreturn_t mps2_uart_oerrirq(int irq, void *data) | ||
237 | { | ||
238 | irqreturn_t handled = IRQ_NONE; | ||
239 | struct uart_port *port = data; | ||
240 | u8 irqflag = mps2_uart_read8(port, UARTn_INT); | ||
241 | |||
242 | spin_lock(&port->lock); | ||
243 | |||
244 | if (irqflag & UARTn_INT_RX_OVERRUN) { | ||
245 | struct tty_port *tport = &port->state->port; | ||
246 | |||
247 | mps2_uart_write8(port, UARTn_INT_RX_OVERRUN, UARTn_INT); | ||
248 | port->icount.overrun++; | ||
249 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); | ||
250 | tty_flip_buffer_push(tport); | ||
251 | handled = IRQ_HANDLED; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * It's never been seen in practice and it never *should* happen since | ||
256 | * we check if there is enough room in TX buffer before sending data. | ||
257 | * So we keep this check in case something suspicious has happened. | ||
258 | */ | ||
259 | if (irqflag & UARTn_INT_TX_OVERRUN) { | ||
260 | mps2_uart_write8(port, UARTn_INT_TX_OVERRUN, UARTn_INT); | ||
261 | handled = IRQ_HANDLED; | ||
262 | } | ||
263 | |||
264 | spin_unlock(&port->lock); | ||
265 | |||
266 | return handled; | ||
267 | } | ||
268 | |||
269 | static int mps2_uart_startup(struct uart_port *port) | ||
270 | { | ||
271 | struct mps2_uart_port *mps_port = to_mps2_port(port); | ||
272 | u8 control = mps2_uart_read8(port, UARTn_CTRL); | ||
273 | int ret; | ||
274 | |||
275 | control &= ~(UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP); | ||
276 | |||
277 | mps2_uart_write8(port, control, UARTn_CTRL); | ||
278 | |||
279 | ret = request_irq(mps_port->rx_irq, mps2_uart_rxirq, 0, | ||
280 | MAKE_NAME(-rx), mps_port); | ||
281 | if (ret) { | ||
282 | dev_err(port->dev, "failed to register rxirq (%d)\n", ret); | ||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | ret = request_irq(mps_port->tx_irq, mps2_uart_txirq, 0, | ||
287 | MAKE_NAME(-tx), mps_port); | ||
288 | if (ret) { | ||
289 | dev_err(port->dev, "failed to register txirq (%d)\n", ret); | ||
290 | goto err_free_rxirq; | ||
291 | } | ||
292 | |||
293 | ret = request_irq(port->irq, mps2_uart_oerrirq, IRQF_SHARED, | ||
294 | MAKE_NAME(-overrun), mps_port); | ||
295 | |||
296 | if (ret) { | ||
297 | dev_err(port->dev, "failed to register oerrirq (%d)\n", ret); | ||
298 | goto err_free_txirq; | ||
299 | } | ||
300 | |||
301 | control |= UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP; | ||
302 | |||
303 | mps2_uart_write8(port, control, UARTn_CTRL); | ||
304 | |||
305 | return 0; | ||
306 | |||
307 | err_free_txirq: | ||
308 | free_irq(mps_port->tx_irq, mps_port); | ||
309 | err_free_rxirq: | ||
310 | free_irq(mps_port->rx_irq, mps_port); | ||
311 | |||
312 | return ret; | ||
313 | } | ||
314 | |||
315 | static void mps2_uart_shutdown(struct uart_port *port) | ||
316 | { | ||
317 | struct mps2_uart_port *mps_port = to_mps2_port(port); | ||
318 | u8 control = mps2_uart_read8(port, UARTn_CTRL); | ||
319 | |||
320 | control &= ~(UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP); | ||
321 | |||
322 | mps2_uart_write8(port, control, UARTn_CTRL); | ||
323 | |||
324 | free_irq(mps_port->rx_irq, mps_port); | ||
325 | free_irq(mps_port->tx_irq, mps_port); | ||
326 | free_irq(port->irq, mps_port); | ||
327 | } | ||
328 | |||
329 | static void | ||
330 | mps2_uart_set_termios(struct uart_port *port, struct ktermios *termios, | ||
331 | struct ktermios *old) | ||
332 | { | ||
333 | unsigned long flags; | ||
334 | unsigned int baud, bauddiv; | ||
335 | |||
336 | termios->c_cflag &= ~(CRTSCTS | CMSPAR); | ||
337 | termios->c_cflag &= ~CSIZE; | ||
338 | termios->c_cflag |= CS8; | ||
339 | termios->c_cflag &= ~PARENB; | ||
340 | termios->c_cflag &= ~CSTOPB; | ||
341 | |||
342 | baud = uart_get_baud_rate(port, termios, old, | ||
343 | DIV_ROUND_CLOSEST(port->uartclk, UARTn_BAUDDIV_MASK), | ||
344 | DIV_ROUND_CLOSEST(port->uartclk, 16)); | ||
345 | |||
346 | bauddiv = DIV_ROUND_CLOSEST(port->uartclk, baud); | ||
347 | |||
348 | spin_lock_irqsave(&port->lock, flags); | ||
349 | |||
350 | uart_update_timeout(port, termios->c_cflag, baud); | ||
351 | mps2_uart_write32(port, bauddiv, UARTn_BAUDDIV); | ||
352 | |||
353 | spin_unlock_irqrestore(&port->lock, flags); | ||
354 | |||
355 | if (tty_termios_baud_rate(termios)) | ||
356 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
357 | } | ||
358 | |||
359 | static const char *mps2_uart_type(struct uart_port *port) | ||
360 | { | ||
361 | return (port->type == PORT_MPS2UART) ? DRIVER_NAME : NULL; | ||
362 | } | ||
363 | |||
364 | static void mps2_uart_release_port(struct uart_port *port) | ||
365 | { | ||
366 | } | ||
367 | |||
368 | static int mps2_uart_request_port(struct uart_port *port) | ||
369 | { | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static void mps2_uart_config_port(struct uart_port *port, int type) | ||
374 | { | ||
375 | if (type & UART_CONFIG_TYPE && !mps2_uart_request_port(port)) | ||
376 | port->type = PORT_MPS2UART; | ||
377 | } | ||
378 | |||
379 | static int mps2_uart_verify_port(struct uart_port *port, struct serial_struct *serinfo) | ||
380 | { | ||
381 | return -EINVAL; | ||
382 | } | ||
383 | |||
384 | static const struct uart_ops mps2_uart_pops = { | ||
385 | .tx_empty = mps2_uart_tx_empty, | ||
386 | .set_mctrl = mps2_uart_set_mctrl, | ||
387 | .get_mctrl = mps2_uart_get_mctrl, | ||
388 | .stop_tx = mps2_uart_stop_tx, | ||
389 | .start_tx = mps2_uart_start_tx, | ||
390 | .stop_rx = mps2_uart_stop_rx, | ||
391 | .break_ctl = mps2_uart_break_ctl, | ||
392 | .startup = mps2_uart_startup, | ||
393 | .shutdown = mps2_uart_shutdown, | ||
394 | .set_termios = mps2_uart_set_termios, | ||
395 | .type = mps2_uart_type, | ||
396 | .release_port = mps2_uart_release_port, | ||
397 | .request_port = mps2_uart_request_port, | ||
398 | .config_port = mps2_uart_config_port, | ||
399 | .verify_port = mps2_uart_verify_port, | ||
400 | }; | ||
401 | |||
402 | static struct mps2_uart_port mps2_uart_ports[MPS2_MAX_PORTS]; | ||
403 | |||
404 | #ifdef CONFIG_SERIAL_MPS2_UART_CONSOLE | ||
405 | static void mps2_uart_console_putchar(struct uart_port *port, int ch) | ||
406 | { | ||
407 | while (mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL) | ||
408 | cpu_relax(); | ||
409 | |||
410 | mps2_uart_write8(port, ch, UARTn_DATA); | ||
411 | } | ||
412 | |||
413 | static void mps2_uart_console_write(struct console *co, const char *s, unsigned int cnt) | ||
414 | { | ||
415 | struct uart_port *port = &mps2_uart_ports[co->index].port; | ||
416 | |||
417 | uart_console_write(port, s, cnt, mps2_uart_console_putchar); | ||
418 | } | ||
419 | |||
420 | static int mps2_uart_console_setup(struct console *co, char *options) | ||
421 | { | ||
422 | struct mps2_uart_port *mps_port; | ||
423 | int baud = 9600; | ||
424 | int bits = 8; | ||
425 | int parity = 'n'; | ||
426 | int flow = 'n'; | ||
427 | |||
428 | if (co->index < 0 || co->index >= MPS2_MAX_PORTS) | ||
429 | return -ENODEV; | ||
430 | |||
431 | mps_port = &mps2_uart_ports[co->index]; | ||
432 | |||
433 | if (options) | ||
434 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
435 | |||
436 | return uart_set_options(&mps_port->port, co, baud, parity, bits, flow); | ||
437 | } | ||
438 | |||
439 | static struct uart_driver mps2_uart_driver; | ||
440 | |||
441 | static struct console mps2_uart_console = { | ||
442 | .name = SERIAL_NAME, | ||
443 | .device = uart_console_device, | ||
444 | .write = mps2_uart_console_write, | ||
445 | .setup = mps2_uart_console_setup, | ||
446 | .flags = CON_PRINTBUFFER, | ||
447 | .index = -1, | ||
448 | .data = &mps2_uart_driver, | ||
449 | }; | ||
450 | |||
451 | #define MPS2_SERIAL_CONSOLE (&mps2_uart_console) | ||
452 | |||
453 | static void mps2_early_putchar(struct uart_port *port, int ch) | ||
454 | { | ||
455 | while (readb(port->membase + UARTn_STATE) & UARTn_STATE_TX_FULL) | ||
456 | cpu_relax(); | ||
457 | |||
458 | writeb((unsigned char)ch, port->membase + UARTn_DATA); | ||
459 | } | ||
460 | |||
461 | static void mps2_early_write(struct console *con, const char *s, unsigned int n) | ||
462 | { | ||
463 | struct earlycon_device *dev = con->data; | ||
464 | |||
465 | uart_console_write(&dev->port, s, n, mps2_early_putchar); | ||
466 | } | ||
467 | |||
468 | static int __init mps2_early_console_setup(struct earlycon_device *device, | ||
469 | const char *opt) | ||
470 | { | ||
471 | if (!device->port.membase) | ||
472 | return -ENODEV; | ||
473 | |||
474 | device->con->write = mps2_early_write; | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | OF_EARLYCON_DECLARE(mps2, "arm,mps2-uart", mps2_early_console_setup); | ||
480 | |||
481 | #else | ||
482 | #define MPS2_SERIAL_CONSOLE NULL | ||
483 | #endif | ||
484 | |||
485 | static struct uart_driver mps2_uart_driver = { | ||
486 | .driver_name = DRIVER_NAME, | ||
487 | .dev_name = SERIAL_NAME, | ||
488 | .nr = MPS2_MAX_PORTS, | ||
489 | .cons = MPS2_SERIAL_CONSOLE, | ||
490 | }; | ||
491 | |||
492 | static struct mps2_uart_port *mps2_of_get_port(struct platform_device *pdev) | ||
493 | { | ||
494 | struct device_node *np = pdev->dev.of_node; | ||
495 | int id; | ||
496 | |||
497 | if (!np) | ||
498 | return NULL; | ||
499 | |||
500 | id = of_alias_get_id(np, "serial"); | ||
501 | if (id < 0) | ||
502 | id = 0; | ||
503 | |||
504 | if (WARN_ON(id >= MPS2_MAX_PORTS)) | ||
505 | return NULL; | ||
506 | |||
507 | mps2_uart_ports[id].port.line = id; | ||
508 | return &mps2_uart_ports[id]; | ||
509 | } | ||
510 | |||
511 | static int mps2_init_port(struct mps2_uart_port *mps_port, | ||
512 | struct platform_device *pdev) | ||
513 | { | ||
514 | struct resource *res; | ||
515 | int ret; | ||
516 | |||
517 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
518 | mps_port->port.membase = devm_ioremap_resource(&pdev->dev, res); | ||
519 | if (IS_ERR(mps_port->port.membase)) | ||
520 | return PTR_ERR(mps_port->port.membase); | ||
521 | |||
522 | mps_port->port.mapbase = res->start; | ||
523 | mps_port->port.mapsize = resource_size(res); | ||
524 | |||
525 | mps_port->rx_irq = platform_get_irq(pdev, 0); | ||
526 | mps_port->tx_irq = platform_get_irq(pdev, 1); | ||
527 | mps_port->port.irq = platform_get_irq(pdev, 2); | ||
528 | |||
529 | mps_port->port.iotype = UPIO_MEM; | ||
530 | mps_port->port.flags = UPF_BOOT_AUTOCONF; | ||
531 | mps_port->port.fifosize = 1; | ||
532 | mps_port->port.ops = &mps2_uart_pops; | ||
533 | mps_port->port.dev = &pdev->dev; | ||
534 | |||
535 | mps_port->clk = devm_clk_get(&pdev->dev, NULL); | ||
536 | if (IS_ERR(mps_port->clk)) | ||
537 | return PTR_ERR(mps_port->clk); | ||
538 | |||
539 | ret = clk_prepare_enable(mps_port->clk); | ||
540 | if (ret) | ||
541 | return ret; | ||
542 | |||
543 | mps_port->port.uartclk = clk_get_rate(mps_port->clk); | ||
544 | |||
545 | clk_disable_unprepare(mps_port->clk); | ||
546 | |||
547 | return ret; | ||
548 | } | ||
549 | |||
550 | static int mps2_serial_probe(struct platform_device *pdev) | ||
551 | { | ||
552 | struct mps2_uart_port *mps_port; | ||
553 | int ret; | ||
554 | |||
555 | mps_port = mps2_of_get_port(pdev); | ||
556 | if (!mps_port) | ||
557 | return -ENODEV; | ||
558 | |||
559 | ret = mps2_init_port(mps_port, pdev); | ||
560 | if (ret) | ||
561 | return ret; | ||
562 | |||
563 | ret = uart_add_one_port(&mps2_uart_driver, &mps_port->port); | ||
564 | if (ret) | ||
565 | return ret; | ||
566 | |||
567 | platform_set_drvdata(pdev, mps_port); | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | static int mps2_serial_remove(struct platform_device *pdev) | ||
573 | { | ||
574 | struct mps2_uart_port *mps_port = platform_get_drvdata(pdev); | ||
575 | |||
576 | uart_remove_one_port(&mps2_uart_driver, &mps_port->port); | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | #ifdef CONFIG_OF | ||
582 | static const struct of_device_id mps2_match[] = { | ||
583 | { .compatible = "arm,mps2-uart", }, | ||
584 | {}, | ||
585 | }; | ||
586 | MODULE_DEVICE_TABLE(of, mps2_match); | ||
587 | #endif | ||
588 | |||
589 | static struct platform_driver mps2_serial_driver = { | ||
590 | .probe = mps2_serial_probe, | ||
591 | .remove = mps2_serial_remove, | ||
592 | |||
593 | .driver = { | ||
594 | .name = DRIVER_NAME, | ||
595 | .of_match_table = of_match_ptr(mps2_match), | ||
596 | }, | ||
597 | }; | ||
598 | |||
599 | static int __init mps2_uart_init(void) | ||
600 | { | ||
601 | int ret; | ||
602 | |||
603 | ret = uart_register_driver(&mps2_uart_driver); | ||
604 | if (ret) | ||
605 | return ret; | ||
606 | |||
607 | ret = platform_driver_register(&mps2_serial_driver); | ||
608 | if (ret) | ||
609 | uart_unregister_driver(&mps2_uart_driver); | ||
610 | |||
611 | return ret; | ||
612 | } | ||
613 | module_init(mps2_uart_init); | ||
614 | |||
615 | static void __exit mps2_uart_exit(void) | ||
616 | { | ||
617 | platform_driver_unregister(&mps2_serial_driver); | ||
618 | uart_unregister_driver(&mps2_uart_driver); | ||
619 | } | ||
620 | module_exit(mps2_uart_exit); | ||
621 | |||
622 | MODULE_AUTHOR("Vladimir Murzin <vladimir.murzin@arm.com>"); | ||
623 | MODULE_DESCRIPTION("MPS2 UART driver"); | ||
624 | MODULE_LICENSE("GPL v2"); | ||
625 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 96d3ce8dc2dc..b7d80bd57db9 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -861,37 +861,72 @@ struct msm_baud_map { | |||
861 | }; | 861 | }; |
862 | 862 | ||
863 | static const struct msm_baud_map * | 863 | static const struct msm_baud_map * |
864 | msm_find_best_baud(struct uart_port *port, unsigned int baud) | 864 | msm_find_best_baud(struct uart_port *port, unsigned int baud, |
865 | unsigned long *rate) | ||
865 | { | 866 | { |
866 | unsigned int i, divisor; | 867 | struct msm_port *msm_port = UART_TO_MSM(port); |
867 | const struct msm_baud_map *entry; | 868 | unsigned int divisor, result; |
869 | unsigned long target, old, best_rate = 0, diff, best_diff = ULONG_MAX; | ||
870 | const struct msm_baud_map *entry, *end, *best; | ||
868 | static const struct msm_baud_map table[] = { | 871 | static const struct msm_baud_map table[] = { |
869 | { 1536, 0x00, 1 }, | ||
870 | { 768, 0x11, 1 }, | ||
871 | { 384, 0x22, 1 }, | ||
872 | { 192, 0x33, 1 }, | ||
873 | { 96, 0x44, 1 }, | ||
874 | { 48, 0x55, 1 }, | ||
875 | { 32, 0x66, 1 }, | ||
876 | { 24, 0x77, 1 }, | ||
877 | { 16, 0x88, 1 }, | ||
878 | { 12, 0x99, 6 }, | ||
879 | { 8, 0xaa, 6 }, | ||
880 | { 6, 0xbb, 6 }, | ||
881 | { 4, 0xcc, 6 }, | ||
882 | { 3, 0xdd, 8 }, | ||
883 | { 2, 0xee, 16 }, | ||
884 | { 1, 0xff, 31 }, | 872 | { 1, 0xff, 31 }, |
885 | { 0, 0xff, 31 }, | 873 | { 2, 0xee, 16 }, |
874 | { 3, 0xdd, 8 }, | ||
875 | { 4, 0xcc, 6 }, | ||
876 | { 6, 0xbb, 6 }, | ||
877 | { 8, 0xaa, 6 }, | ||
878 | { 12, 0x99, 6 }, | ||
879 | { 16, 0x88, 1 }, | ||
880 | { 24, 0x77, 1 }, | ||
881 | { 32, 0x66, 1 }, | ||
882 | { 48, 0x55, 1 }, | ||
883 | { 96, 0x44, 1 }, | ||
884 | { 192, 0x33, 1 }, | ||
885 | { 384, 0x22, 1 }, | ||
886 | { 768, 0x11, 1 }, | ||
887 | { 1536, 0x00, 1 }, | ||
886 | }; | 888 | }; |
887 | 889 | ||
888 | divisor = uart_get_divisor(port, baud); | 890 | best = table; /* Default to smallest divider */ |
891 | target = clk_round_rate(msm_port->clk, 16 * baud); | ||
892 | divisor = DIV_ROUND_CLOSEST(target, 16 * baud); | ||
893 | |||
894 | end = table + ARRAY_SIZE(table); | ||
895 | entry = table; | ||
896 | while (entry < end) { | ||
897 | if (entry->divisor <= divisor) { | ||
898 | result = target / entry->divisor / 16; | ||
899 | diff = abs(result - baud); | ||
900 | |||
901 | /* Keep track of best entry */ | ||
902 | if (diff < best_diff) { | ||
903 | best_diff = diff; | ||
904 | best = entry; | ||
905 | best_rate = target; | ||
906 | } | ||
889 | 907 | ||
890 | for (i = 0, entry = table; i < ARRAY_SIZE(table); i++, entry++) | 908 | if (result == baud) |
891 | if (entry->divisor <= divisor) | 909 | break; |
892 | break; | 910 | } else if (entry->divisor > divisor) { |
911 | old = target; | ||
912 | target = clk_round_rate(msm_port->clk, old + 1); | ||
913 | /* | ||
914 | * The rate didn't get any faster so we can't do | ||
915 | * better at dividing it down | ||
916 | */ | ||
917 | if (target == old) | ||
918 | break; | ||
893 | 919 | ||
894 | return entry; /* Default to smallest divider */ | 920 | /* Start the divisor search over at this new rate */ |
921 | entry = table; | ||
922 | divisor = DIV_ROUND_CLOSEST(target, 16 * baud); | ||
923 | continue; | ||
924 | } | ||
925 | entry++; | ||
926 | } | ||
927 | |||
928 | *rate = best_rate; | ||
929 | return best; | ||
895 | } | 930 | } |
896 | 931 | ||
897 | static int msm_set_baud_rate(struct uart_port *port, unsigned int baud, | 932 | static int msm_set_baud_rate(struct uart_port *port, unsigned int baud, |
@@ -900,22 +935,20 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud, | |||
900 | unsigned int rxstale, watermark, mask; | 935 | unsigned int rxstale, watermark, mask; |
901 | struct msm_port *msm_port = UART_TO_MSM(port); | 936 | struct msm_port *msm_port = UART_TO_MSM(port); |
902 | const struct msm_baud_map *entry; | 937 | const struct msm_baud_map *entry; |
903 | unsigned long flags; | 938 | unsigned long flags, rate; |
904 | |||
905 | entry = msm_find_best_baud(port, baud); | ||
906 | |||
907 | msm_write(port, entry->code, UART_CSR); | ||
908 | |||
909 | if (baud > 460800) | ||
910 | port->uartclk = baud * 16; | ||
911 | 939 | ||
912 | flags = *saved_flags; | 940 | flags = *saved_flags; |
913 | spin_unlock_irqrestore(&port->lock, flags); | 941 | spin_unlock_irqrestore(&port->lock, flags); |
914 | 942 | ||
915 | clk_set_rate(msm_port->clk, port->uartclk); | 943 | entry = msm_find_best_baud(port, baud, &rate); |
944 | clk_set_rate(msm_port->clk, rate); | ||
945 | baud = rate / 16 / entry->divisor; | ||
916 | 946 | ||
917 | spin_lock_irqsave(&port->lock, flags); | 947 | spin_lock_irqsave(&port->lock, flags); |
918 | *saved_flags = flags; | 948 | *saved_flags = flags; |
949 | port->uartclk = rate; | ||
950 | |||
951 | msm_write(port, entry->code, UART_CSR); | ||
919 | 952 | ||
920 | /* RX stale watermark */ | 953 | /* RX stale watermark */ |
921 | rxstale = entry->rxstale; | 954 | rxstale = entry->rxstale; |
@@ -1577,8 +1610,6 @@ static int msm_serial_probe(struct platform_device *pdev) | |||
1577 | msm_port->pclk = devm_clk_get(&pdev->dev, "iface"); | 1610 | msm_port->pclk = devm_clk_get(&pdev->dev, "iface"); |
1578 | if (IS_ERR(msm_port->pclk)) | 1611 | if (IS_ERR(msm_port->pclk)) |
1579 | return PTR_ERR(msm_port->pclk); | 1612 | return PTR_ERR(msm_port->pclk); |
1580 | |||
1581 | clk_set_rate(msm_port->clk, 1843200); | ||
1582 | } | 1613 | } |
1583 | 1614 | ||
1584 | port->uartclk = clk_get_rate(msm_port->clk); | 1615 | port->uartclk = clk_get_rate(msm_port->clk); |
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 0ff27818bb87..ce362bd51de7 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * *************************************************************************** | 2 | * *************************************************************************** |
3 | * Marvell Armada-3700 Serial Driver | ||
4 | * Author: Wilson Ding <dingwei@marvell.com> | ||
3 | * Copyright (C) 2015 Marvell International Ltd. | 5 | * Copyright (C) 2015 Marvell International Ltd. |
4 | * *************************************************************************** | 6 | * *************************************************************************** |
5 | * This program is free software: you can redistribute it and/or modify it | 7 | * This program is free software: you can redistribute it and/or modify it |
@@ -23,7 +25,6 @@ | |||
23 | #include <linux/init.h> | 25 | #include <linux/init.h> |
24 | #include <linux/io.h> | 26 | #include <linux/io.h> |
25 | #include <linux/iopoll.h> | 27 | #include <linux/iopoll.h> |
26 | #include <linux/module.h> | ||
27 | #include <linux/of.h> | 28 | #include <linux/of.h> |
28 | #include <linux/of_address.h> | 29 | #include <linux/of_address.h> |
29 | #include <linux/of_device.h> | 30 | #include <linux/of_device.h> |
@@ -594,30 +595,18 @@ static int mvebu_uart_probe(struct platform_device *pdev) | |||
594 | return 0; | 595 | return 0; |
595 | } | 596 | } |
596 | 597 | ||
597 | static int mvebu_uart_remove(struct platform_device *pdev) | ||
598 | { | ||
599 | struct mvebu_uart_data *data = platform_get_drvdata(pdev); | ||
600 | |||
601 | uart_remove_one_port(&mvebu_uart_driver, data->port); | ||
602 | data->port->private_data = NULL; | ||
603 | data->port->mapbase = 0; | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | /* Match table for of_platform binding */ | 598 | /* Match table for of_platform binding */ |
608 | static const struct of_device_id mvebu_uart_of_match[] = { | 599 | static const struct of_device_id mvebu_uart_of_match[] = { |
609 | { .compatible = "marvell,armada-3700-uart", }, | 600 | { .compatible = "marvell,armada-3700-uart", }, |
610 | {} | 601 | {} |
611 | }; | 602 | }; |
612 | MODULE_DEVICE_TABLE(of, mvebu_uart_of_match); | ||
613 | 603 | ||
614 | static struct platform_driver mvebu_uart_platform_driver = { | 604 | static struct platform_driver mvebu_uart_platform_driver = { |
615 | .probe = mvebu_uart_probe, | 605 | .probe = mvebu_uart_probe, |
616 | .remove = mvebu_uart_remove, | ||
617 | .driver = { | 606 | .driver = { |
618 | .owner = THIS_MODULE, | ||
619 | .name = "mvebu-uart", | 607 | .name = "mvebu-uart", |
620 | .of_match_table = of_match_ptr(mvebu_uart_of_match), | 608 | .of_match_table = of_match_ptr(mvebu_uart_of_match), |
609 | .suppress_bind_attrs = true, | ||
621 | }, | 610 | }, |
622 | }; | 611 | }; |
623 | 612 | ||
@@ -635,16 +624,4 @@ static int __init mvebu_uart_init(void) | |||
635 | 624 | ||
636 | return ret; | 625 | return ret; |
637 | } | 626 | } |
638 | |||
639 | static void __exit mvebu_uart_exit(void) | ||
640 | { | ||
641 | platform_driver_unregister(&mvebu_uart_platform_driver); | ||
642 | uart_unregister_driver(&mvebu_uart_driver); | ||
643 | } | ||
644 | |||
645 | arch_initcall(mvebu_uart_init); | 627 | arch_initcall(mvebu_uart_init); |
646 | module_exit(mvebu_uart_exit); | ||
647 | |||
648 | MODULE_AUTHOR("Wilson Ding <dingwei@marvell.com>"); | ||
649 | MODULE_DESCRIPTION("Marvell Armada-3700 Serial Driver"); | ||
650 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index cd0414bbe094..eb54e5c77ead 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -1,17 +1,18 @@ | |||
1 | /* | 1 | /* |
2 | * Freescale STMP37XX/STMP378X Application UART driver | 2 | * Application UART driver for: |
3 | * Freescale STMP37XX/STMP378X | ||
4 | * Alphascale ASM9260 | ||
3 | * | 5 | * |
4 | * Author: dmitry pervushin <dimka@embeddedalley.com> | 6 | * Author: dmitry pervushin <dimka@embeddedalley.com> |
5 | * | 7 | * |
8 | * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de> | ||
9 | * Provide Alphascale ASM9260 support. | ||
6 | * Copyright 2008-2010 Freescale Semiconductor, Inc. | 10 | * Copyright 2008-2010 Freescale Semiconductor, Inc. |
7 | * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. | 11 | * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. |
8 | * | 12 | * |
9 | * The code contained herein is licensed under the GNU General Public | 13 | * The code contained herein is licensed under the GNU General Public |
10 | * License. You may obtain a copy of the GNU General Public License | 14 | * License. You may obtain a copy of the GNU General Public License |
11 | * Version 2 or later at the following locations: | 15 | * Version 2 or later at the following locations: |
12 | * | ||
13 | * http://www.opensource.org/licenses/gpl-license.html | ||
14 | * http://www.gnu.org/copyleft/gpl.html | ||
15 | */ | 16 | */ |
16 | 17 | ||
17 | #if defined(CONFIG_SERIAL_MXS_AUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 18 | #if defined(CONFIG_SERIAL_MXS_AUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
@@ -51,30 +52,16 @@ | |||
51 | #define MXS_AUART_PORTS 5 | 52 | #define MXS_AUART_PORTS 5 |
52 | #define MXS_AUART_FIFO_SIZE 16 | 53 | #define MXS_AUART_FIFO_SIZE 16 |
53 | 54 | ||
55 | #define SET_REG 0x4 | ||
56 | #define CLR_REG 0x8 | ||
57 | #define TOG_REG 0xc | ||
58 | |||
54 | #define AUART_CTRL0 0x00000000 | 59 | #define AUART_CTRL0 0x00000000 |
55 | #define AUART_CTRL0_SET 0x00000004 | ||
56 | #define AUART_CTRL0_CLR 0x00000008 | ||
57 | #define AUART_CTRL0_TOG 0x0000000c | ||
58 | #define AUART_CTRL1 0x00000010 | 60 | #define AUART_CTRL1 0x00000010 |
59 | #define AUART_CTRL1_SET 0x00000014 | ||
60 | #define AUART_CTRL1_CLR 0x00000018 | ||
61 | #define AUART_CTRL1_TOG 0x0000001c | ||
62 | #define AUART_CTRL2 0x00000020 | 61 | #define AUART_CTRL2 0x00000020 |
63 | #define AUART_CTRL2_SET 0x00000024 | ||
64 | #define AUART_CTRL2_CLR 0x00000028 | ||
65 | #define AUART_CTRL2_TOG 0x0000002c | ||
66 | #define AUART_LINECTRL 0x00000030 | 62 | #define AUART_LINECTRL 0x00000030 |
67 | #define AUART_LINECTRL_SET 0x00000034 | ||
68 | #define AUART_LINECTRL_CLR 0x00000038 | ||
69 | #define AUART_LINECTRL_TOG 0x0000003c | ||
70 | #define AUART_LINECTRL2 0x00000040 | 63 | #define AUART_LINECTRL2 0x00000040 |
71 | #define AUART_LINECTRL2_SET 0x00000044 | ||
72 | #define AUART_LINECTRL2_CLR 0x00000048 | ||
73 | #define AUART_LINECTRL2_TOG 0x0000004c | ||
74 | #define AUART_INTR 0x00000050 | 64 | #define AUART_INTR 0x00000050 |
75 | #define AUART_INTR_SET 0x00000054 | ||
76 | #define AUART_INTR_CLR 0x00000058 | ||
77 | #define AUART_INTR_TOG 0x0000005c | ||
78 | #define AUART_DATA 0x00000060 | 65 | #define AUART_DATA 0x00000060 |
79 | #define AUART_STAT 0x00000070 | 66 | #define AUART_STAT 0x00000070 |
80 | #define AUART_DEBUG 0x00000080 | 67 | #define AUART_DEBUG 0x00000080 |
@@ -136,11 +123,301 @@ | |||
136 | #define AUART_STAT_FERR (1 << 16) | 123 | #define AUART_STAT_FERR (1 << 16) |
137 | #define AUART_STAT_RXCOUNT_MASK 0xffff | 124 | #define AUART_STAT_RXCOUNT_MASK 0xffff |
138 | 125 | ||
126 | /* | ||
127 | * Start of Alphascale asm9260 defines | ||
128 | * This list contains only differences of existing bits | ||
129 | * between imx2x and asm9260 | ||
130 | */ | ||
131 | #define ASM9260_HW_CTRL0 0x0000 | ||
132 | /* | ||
133 | * RW. Tell the UART to execute the RX DMA Command. The | ||
134 | * UART will clear this bit at the end of receive execution. | ||
135 | */ | ||
136 | #define ASM9260_BM_CTRL0_RXDMA_RUN BIT(28) | ||
137 | /* RW. 0 use FIFO for status register; 1 use DMA */ | ||
138 | #define ASM9260_BM_CTRL0_RXTO_SOURCE_STATUS BIT(25) | ||
139 | /* | ||
140 | * RW. RX TIMEOUT Enable. Valid for FIFO and DMA. | ||
141 | * Warning: If this bit is set to 0, the RX timeout will not affect receive DMA | ||
142 | * operation. If this bit is set to 1, a receive timeout will cause the receive | ||
143 | * DMA logic to terminate by filling the remaining DMA bytes with garbage data. | ||
144 | */ | ||
145 | #define ASM9260_BM_CTRL0_RXTO_ENABLE BIT(24) | ||
146 | /* | ||
147 | * RW. Receive Timeout Counter Value: number of 8-bit-time to wait before | ||
148 | * asserting timeout on the RX input. If the RXFIFO is not empty and the RX | ||
149 | * input is idle, then the watchdog counter will decrement each bit-time. Note | ||
150 | * 7-bit-time is added to the programmed value, so a value of zero will set | ||
151 | * the counter to 7-bit-time, a value of 0x1 gives 15-bit-time and so on. Also | ||
152 | * note that the counter is reloaded at the end of each frame, so if the frame | ||
153 | * is 10 bits long and the timeout counter value is zero, then timeout will | ||
154 | * occur (when FIFO is not empty) even if the RX input is not idle. The default | ||
155 | * value is 0x3 (31 bit-time). | ||
156 | */ | ||
157 | #define ASM9260_BM_CTRL0_RXTO_MASK (0xff << 16) | ||
158 | /* TIMEOUT = (100*7+1)*(1/BAUD) */ | ||
159 | #define ASM9260_BM_CTRL0_DEFAULT_RXTIMEOUT (20 << 16) | ||
160 | |||
161 | /* TX ctrl register */ | ||
162 | #define ASM9260_HW_CTRL1 0x0010 | ||
163 | /* | ||
164 | * RW. Tell the UART to execute the TX DMA Command. The | ||
165 | * UART will clear this bit at the end of transmit execution. | ||
166 | */ | ||
167 | #define ASM9260_BM_CTRL1_TXDMA_RUN BIT(28) | ||
168 | |||
169 | #define ASM9260_HW_CTRL2 0x0020 | ||
170 | /* | ||
171 | * RW. Receive Interrupt FIFO Level Select. | ||
172 | * The trigger points for the receive interrupt are as follows: | ||
173 | * ONE_EIGHTHS = 0x0 Trigger on FIFO full to at least 2 of 16 entries. | ||
174 | * ONE_QUARTER = 0x1 Trigger on FIFO full to at least 4 of 16 entries. | ||
175 | * ONE_HALF = 0x2 Trigger on FIFO full to at least 8 of 16 entries. | ||
176 | * THREE_QUARTERS = 0x3 Trigger on FIFO full to at least 12 of 16 entries. | ||
177 | * SEVEN_EIGHTHS = 0x4 Trigger on FIFO full to at least 14 of 16 entries. | ||
178 | */ | ||
179 | #define ASM9260_BM_CTRL2_RXIFLSEL (7 << 20) | ||
180 | #define ASM9260_BM_CTRL2_DEFAULT_RXIFLSEL (3 << 20) | ||
181 | /* RW. Same as RXIFLSEL */ | ||
182 | #define ASM9260_BM_CTRL2_TXIFLSEL (7 << 16) | ||
183 | #define ASM9260_BM_CTRL2_DEFAULT_TXIFLSEL (2 << 16) | ||
184 | /* RW. Set DTR. When this bit is 1, the output is 0. */ | ||
185 | #define ASM9260_BM_CTRL2_DTR BIT(10) | ||
186 | /* RW. Loop Back Enable */ | ||
187 | #define ASM9260_BM_CTRL2_LBE BIT(7) | ||
188 | #define ASM9260_BM_CTRL2_PORT_ENABLE BIT(0) | ||
189 | |||
190 | #define ASM9260_HW_LINECTRL 0x0030 | ||
191 | /* | ||
192 | * RW. Stick Parity Select. When bits 1, 2, and 7 of this register are set, the | ||
193 | * parity bit is transmitted and checked as a 0. When bits 1 and 7 are set, | ||
194 | * and bit 2 is 0, the parity bit is transmitted and checked as a 1. When this | ||
195 | * bit is cleared stick parity is disabled. | ||
196 | */ | ||
197 | #define ASM9260_BM_LCTRL_SPS BIT(7) | ||
198 | /* RW. Word length */ | ||
199 | #define ASM9260_BM_LCTRL_WLEN (3 << 5) | ||
200 | #define ASM9260_BM_LCTRL_CHRL_5 (0 << 5) | ||
201 | #define ASM9260_BM_LCTRL_CHRL_6 (1 << 5) | ||
202 | #define ASM9260_BM_LCTRL_CHRL_7 (2 << 5) | ||
203 | #define ASM9260_BM_LCTRL_CHRL_8 (3 << 5) | ||
204 | |||
205 | /* | ||
206 | * Interrupt register. | ||
207 | * contains the interrupt enables and the interrupt status bits | ||
208 | */ | ||
209 | #define ASM9260_HW_INTR 0x0040 | ||
210 | /* Tx FIFO EMPTY Raw Interrupt enable */ | ||
211 | #define ASM9260_BM_INTR_TFEIEN BIT(27) | ||
212 | /* Overrun Error Interrupt Enable. */ | ||
213 | #define ASM9260_BM_INTR_OEIEN BIT(26) | ||
214 | /* Break Error Interrupt Enable. */ | ||
215 | #define ASM9260_BM_INTR_BEIEN BIT(25) | ||
216 | /* Parity Error Interrupt Enable. */ | ||
217 | #define ASM9260_BM_INTR_PEIEN BIT(24) | ||
218 | /* Framing Error Interrupt Enable. */ | ||
219 | #define ASM9260_BM_INTR_FEIEN BIT(23) | ||
220 | |||
221 | /* nUARTDSR Modem Interrupt Enable. */ | ||
222 | #define ASM9260_BM_INTR_DSRMIEN BIT(19) | ||
223 | /* nUARTDCD Modem Interrupt Enable. */ | ||
224 | #define ASM9260_BM_INTR_DCDMIEN BIT(18) | ||
225 | /* nUARTRI Modem Interrupt Enable. */ | ||
226 | #define ASM9260_BM_INTR_RIMIEN BIT(16) | ||
227 | /* Auto-Boud Timeout */ | ||
228 | #define ASM9260_BM_INTR_ABTO BIT(13) | ||
229 | #define ASM9260_BM_INTR_ABEO BIT(12) | ||
230 | /* Tx FIFO EMPTY Raw Interrupt state */ | ||
231 | #define ASM9260_BM_INTR_TFEIS BIT(11) | ||
232 | /* Overrun Error */ | ||
233 | #define ASM9260_BM_INTR_OEIS BIT(10) | ||
234 | /* Break Error */ | ||
235 | #define ASM9260_BM_INTR_BEIS BIT(9) | ||
236 | /* Parity Error */ | ||
237 | #define ASM9260_BM_INTR_PEIS BIT(8) | ||
238 | /* Framing Error */ | ||
239 | #define ASM9260_BM_INTR_FEIS BIT(7) | ||
240 | #define ASM9260_BM_INTR_DSRMIS BIT(3) | ||
241 | #define ASM9260_BM_INTR_DCDMIS BIT(2) | ||
242 | #define ASM9260_BM_INTR_RIMIS BIT(0) | ||
243 | |||
244 | /* | ||
245 | * RW. In DMA mode, up to 4 Received/Transmit characters can be accessed at a | ||
246 | * time. In PIO mode, only one character can be accessed at a time. The status | ||
247 | * register contains the receive data flags and valid bits. | ||
248 | */ | ||
249 | #define ASM9260_HW_DATA 0x0050 | ||
250 | |||
251 | #define ASM9260_HW_STAT 0x0060 | ||
252 | /* RO. If 1, UARTAPP is present in this product. */ | ||
253 | #define ASM9260_BM_STAT_PRESENT BIT(31) | ||
254 | /* RO. If 1, HISPEED is present in this product. */ | ||
255 | #define ASM9260_BM_STAT_HISPEED BIT(30) | ||
256 | /* RO. Receive FIFO Full. */ | ||
257 | #define ASM9260_BM_STAT_RXFULL BIT(26) | ||
258 | |||
259 | /* RO. The UART Debug Register contains the state of the DMA signals. */ | ||
260 | #define ASM9260_HW_DEBUG 0x0070 | ||
261 | /* DMA Command Run Status */ | ||
262 | #define ASM9260_BM_DEBUG_TXDMARUN BIT(5) | ||
263 | #define ASM9260_BM_DEBUG_RXDMARUN BIT(4) | ||
264 | /* DMA Command End Status */ | ||
265 | #define ASM9260_BM_DEBUG_TXCMDEND BIT(3) | ||
266 | #define ASM9260_BM_DEBUG_RXCMDEND BIT(2) | ||
267 | /* DMA Request Status */ | ||
268 | #define ASM9260_BM_DEBUG_TXDMARQ BIT(1) | ||
269 | #define ASM9260_BM_DEBUG_RXDMARQ BIT(0) | ||
270 | |||
271 | #define ASM9260_HW_ILPR 0x0080 | ||
272 | |||
273 | #define ASM9260_HW_RS485CTRL 0x0090 | ||
274 | /* | ||
275 | * RW. This bit reverses the polarity of the direction control signal on the RTS | ||
276 | * (or DTR) pin. | ||
277 | * If 0, The direction control pin will be driven to logic ‘0’ when the | ||
278 | * transmitter has data to be sent. It will be driven to logic ‘1’ after the | ||
279 | * last bit of data has been transmitted. | ||
280 | */ | ||
281 | #define ASM9260_BM_RS485CTRL_ONIV BIT(5) | ||
282 | /* RW. Enable Auto Direction Control. */ | ||
283 | #define ASM9260_BM_RS485CTRL_DIR_CTRL BIT(4) | ||
284 | /* | ||
285 | * RW. If 0 and DIR_CTRL = 1, pin RTS is used for direction control. | ||
286 | * If 1 and DIR_CTRL = 1, pin DTR is used for direction control. | ||
287 | */ | ||
288 | #define ASM9260_BM_RS485CTRL_PINSEL BIT(3) | ||
289 | /* RW. Enable Auto Address Detect (AAD). */ | ||
290 | #define ASM9260_BM_RS485CTRL_AADEN BIT(2) | ||
291 | /* RW. Disable receiver. */ | ||
292 | #define ASM9260_BM_RS485CTRL_RXDIS BIT(1) | ||
293 | /* RW. Enable RS-485/EIA-485 Normal Multidrop Mode (NMM) */ | ||
294 | #define ASM9260_BM_RS485CTRL_RS485EN BIT(0) | ||
295 | |||
296 | #define ASM9260_HW_RS485ADRMATCH 0x00a0 | ||
297 | /* Contains the address match value. */ | ||
298 | #define ASM9260_BM_RS485ADRMATCH_MASK (0xff << 0) | ||
299 | |||
300 | #define ASM9260_HW_RS485DLY 0x00b0 | ||
301 | /* | ||
302 | * RW. Contains the direction control (RTS or DTR) delay value. This delay time | ||
303 | * is in periods of the baud clock. | ||
304 | */ | ||
305 | #define ASM9260_BM_RS485DLY_MASK (0xff << 0) | ||
306 | |||
307 | #define ASM9260_HW_AUTOBAUD 0x00c0 | ||
308 | /* WO. Auto-baud time-out interrupt clear bit. */ | ||
309 | #define ASM9260_BM_AUTOBAUD_TO_INT_CLR BIT(9) | ||
310 | /* WO. End of auto-baud interrupt clear bit. */ | ||
311 | #define ASM9260_BM_AUTOBAUD_EO_INT_CLR BIT(8) | ||
312 | /* Restart in case of timeout (counter restarts at next UART Rx falling edge) */ | ||
313 | #define ASM9260_BM_AUTOBAUD_AUTORESTART BIT(2) | ||
314 | /* Auto-baud mode select bit. 0 - Mode 0, 1 - Mode 1. */ | ||
315 | #define ASM9260_BM_AUTOBAUD_MODE BIT(1) | ||
316 | /* | ||
317 | * Auto-baud start (auto-baud is running). Auto-baud run bit. This bit is | ||
318 | * automatically cleared after auto-baud completion. | ||
319 | */ | ||
320 | #define ASM9260_BM_AUTOBAUD_START BIT(0) | ||
321 | |||
322 | #define ASM9260_HW_CTRL3 0x00d0 | ||
323 | #define ASM9260_BM_CTRL3_OUTCLK_DIV_MASK (0xffff << 16) | ||
324 | /* | ||
325 | * RW. Provide clk over OUTCLK pin. In case of asm9260 it can be configured on | ||
326 | * pins 137 and 144. | ||
327 | */ | ||
328 | #define ASM9260_BM_CTRL3_MASTERMODE BIT(6) | ||
329 | /* RW. Baud Rate Mode: 1 - Enable sync mode. 0 - async mode. */ | ||
330 | #define ASM9260_BM_CTRL3_SYNCMODE BIT(4) | ||
331 | /* RW. 1 - MSB bit send frist; 0 - LSB bit frist. */ | ||
332 | #define ASM9260_BM_CTRL3_MSBF BIT(2) | ||
333 | /* RW. 1 - sample rate = 8 x Baudrate; 0 - sample rate = 16 x Baudrate. */ | ||
334 | #define ASM9260_BM_CTRL3_BAUD8 BIT(1) | ||
335 | /* RW. 1 - Set word length to 9bit. 0 - use ASM9260_BM_LCTRL_WLEN */ | ||
336 | #define ASM9260_BM_CTRL3_9BIT BIT(0) | ||
337 | |||
338 | #define ASM9260_HW_ISO7816_CTRL 0x00e0 | ||
339 | /* RW. Enable High Speed mode. */ | ||
340 | #define ASM9260_BM_ISO7816CTRL_HS BIT(12) | ||
341 | /* Disable Successive Receive NACK */ | ||
342 | #define ASM9260_BM_ISO7816CTRL_DS_NACK BIT(8) | ||
343 | #define ASM9260_BM_ISO7816CTRL_MAX_ITER_MASK (0xff << 4) | ||
344 | /* Receive NACK Inhibit */ | ||
345 | #define ASM9260_BM_ISO7816CTRL_INACK BIT(3) | ||
346 | #define ASM9260_BM_ISO7816CTRL_NEG_DATA BIT(2) | ||
347 | /* RW. 1 - ISO7816 mode; 0 - USART mode */ | ||
348 | #define ASM9260_BM_ISO7816CTRL_ENABLE BIT(0) | ||
349 | |||
350 | #define ASM9260_HW_ISO7816_ERRCNT 0x00f0 | ||
351 | /* Parity error counter. Will be cleared after reading */ | ||
352 | #define ASM9260_BM_ISO7816_NB_ERRORS_MASK (0xff << 0) | ||
353 | |||
354 | #define ASM9260_HW_ISO7816_STATUS 0x0100 | ||
355 | /* Max number of Repetitions Reached */ | ||
356 | #define ASM9260_BM_ISO7816_STAT_ITERATION BIT(0) | ||
357 | |||
358 | /* End of Alphascale asm9260 defines */ | ||
359 | |||
139 | static struct uart_driver auart_driver; | 360 | static struct uart_driver auart_driver; |
140 | 361 | ||
141 | enum mxs_auart_type { | 362 | enum mxs_auart_type { |
142 | IMX23_AUART, | 363 | IMX23_AUART, |
143 | IMX28_AUART, | 364 | IMX28_AUART, |
365 | ASM9260_AUART, | ||
366 | }; | ||
367 | |||
368 | struct vendor_data { | ||
369 | const u16 *reg_offset; | ||
370 | }; | ||
371 | |||
372 | enum { | ||
373 | REG_CTRL0, | ||
374 | REG_CTRL1, | ||
375 | REG_CTRL2, | ||
376 | REG_LINECTRL, | ||
377 | REG_LINECTRL2, | ||
378 | REG_INTR, | ||
379 | REG_DATA, | ||
380 | REG_STAT, | ||
381 | REG_DEBUG, | ||
382 | REG_VERSION, | ||
383 | REG_AUTOBAUD, | ||
384 | |||
385 | /* The size of the array - must be last */ | ||
386 | REG_ARRAY_SIZE, | ||
387 | }; | ||
388 | |||
389 | static const u16 mxs_asm9260_offsets[REG_ARRAY_SIZE] = { | ||
390 | [REG_CTRL0] = ASM9260_HW_CTRL0, | ||
391 | [REG_CTRL1] = ASM9260_HW_CTRL1, | ||
392 | [REG_CTRL2] = ASM9260_HW_CTRL2, | ||
393 | [REG_LINECTRL] = ASM9260_HW_LINECTRL, | ||
394 | [REG_INTR] = ASM9260_HW_INTR, | ||
395 | [REG_DATA] = ASM9260_HW_DATA, | ||
396 | [REG_STAT] = ASM9260_HW_STAT, | ||
397 | [REG_DEBUG] = ASM9260_HW_DEBUG, | ||
398 | [REG_AUTOBAUD] = ASM9260_HW_AUTOBAUD, | ||
399 | }; | ||
400 | |||
401 | static const u16 mxs_stmp37xx_offsets[REG_ARRAY_SIZE] = { | ||
402 | [REG_CTRL0] = AUART_CTRL0, | ||
403 | [REG_CTRL1] = AUART_CTRL1, | ||
404 | [REG_CTRL2] = AUART_CTRL2, | ||
405 | [REG_LINECTRL] = AUART_LINECTRL, | ||
406 | [REG_LINECTRL2] = AUART_LINECTRL2, | ||
407 | [REG_INTR] = AUART_INTR, | ||
408 | [REG_DATA] = AUART_DATA, | ||
409 | [REG_STAT] = AUART_STAT, | ||
410 | [REG_DEBUG] = AUART_DEBUG, | ||
411 | [REG_VERSION] = AUART_VERSION, | ||
412 | [REG_AUTOBAUD] = AUART_AUTOBAUD, | ||
413 | }; | ||
414 | |||
415 | static const struct vendor_data vendor_alphascale_asm9260 = { | ||
416 | .reg_offset = mxs_asm9260_offsets, | ||
417 | }; | ||
418 | |||
419 | static const struct vendor_data vendor_freescale_stmp37xx = { | ||
420 | .reg_offset = mxs_stmp37xx_offsets, | ||
144 | }; | 421 | }; |
145 | 422 | ||
146 | struct mxs_auart_port { | 423 | struct mxs_auart_port { |
@@ -153,8 +430,10 @@ struct mxs_auart_port { | |||
153 | unsigned long flags; | 430 | unsigned long flags; |
154 | unsigned int mctrl_prev; | 431 | unsigned int mctrl_prev; |
155 | enum mxs_auart_type devtype; | 432 | enum mxs_auart_type devtype; |
433 | const struct vendor_data *vendor; | ||
156 | 434 | ||
157 | struct clk *clk; | 435 | struct clk *clk; |
436 | struct clk *clk_ahb; | ||
158 | struct device *dev; | 437 | struct device *dev; |
159 | 438 | ||
160 | /* for DMA */ | 439 | /* for DMA */ |
@@ -174,6 +453,7 @@ struct mxs_auart_port { | |||
174 | static const struct platform_device_id mxs_auart_devtype[] = { | 453 | static const struct platform_device_id mxs_auart_devtype[] = { |
175 | { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART }, | 454 | { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART }, |
176 | { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART }, | 455 | { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART }, |
456 | { .name = "as-auart-asm9260", .driver_data = ASM9260_AUART }, | ||
177 | { /* sentinel */ } | 457 | { /* sentinel */ } |
178 | }; | 458 | }; |
179 | MODULE_DEVICE_TABLE(platform, mxs_auart_devtype); | 459 | MODULE_DEVICE_TABLE(platform, mxs_auart_devtype); |
@@ -185,6 +465,9 @@ static const struct of_device_id mxs_auart_dt_ids[] = { | |||
185 | }, { | 465 | }, { |
186 | .compatible = "fsl,imx23-auart", | 466 | .compatible = "fsl,imx23-auart", |
187 | .data = &mxs_auart_devtype[IMX23_AUART] | 467 | .data = &mxs_auart_devtype[IMX23_AUART] |
468 | }, { | ||
469 | .compatible = "alphascale,asm9260-auart", | ||
470 | .data = &mxs_auart_devtype[ASM9260_AUART] | ||
188 | }, { /* sentinel */ } | 471 | }, { /* sentinel */ } |
189 | }; | 472 | }; |
190 | MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids); | 473 | MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids); |
@@ -194,11 +477,54 @@ static inline int is_imx28_auart(struct mxs_auart_port *s) | |||
194 | return s->devtype == IMX28_AUART; | 477 | return s->devtype == IMX28_AUART; |
195 | } | 478 | } |
196 | 479 | ||
480 | static inline int is_asm9260_auart(struct mxs_auart_port *s) | ||
481 | { | ||
482 | return s->devtype == ASM9260_AUART; | ||
483 | } | ||
484 | |||
197 | static inline bool auart_dma_enabled(struct mxs_auart_port *s) | 485 | static inline bool auart_dma_enabled(struct mxs_auart_port *s) |
198 | { | 486 | { |
199 | return s->flags & MXS_AUART_DMA_ENABLED; | 487 | return s->flags & MXS_AUART_DMA_ENABLED; |
200 | } | 488 | } |
201 | 489 | ||
490 | static unsigned int mxs_reg_to_offset(const struct mxs_auart_port *uap, | ||
491 | unsigned int reg) | ||
492 | { | ||
493 | return uap->vendor->reg_offset[reg]; | ||
494 | } | ||
495 | |||
496 | static unsigned int mxs_read(const struct mxs_auart_port *uap, | ||
497 | unsigned int reg) | ||
498 | { | ||
499 | void __iomem *addr = uap->port.membase + mxs_reg_to_offset(uap, reg); | ||
500 | |||
501 | return readl_relaxed(addr); | ||
502 | } | ||
503 | |||
504 | static void mxs_write(unsigned int val, struct mxs_auart_port *uap, | ||
505 | unsigned int reg) | ||
506 | { | ||
507 | void __iomem *addr = uap->port.membase + mxs_reg_to_offset(uap, reg); | ||
508 | |||
509 | writel_relaxed(val, addr); | ||
510 | } | ||
511 | |||
512 | static void mxs_set(unsigned int val, struct mxs_auart_port *uap, | ||
513 | unsigned int reg) | ||
514 | { | ||
515 | void __iomem *addr = uap->port.membase + mxs_reg_to_offset(uap, reg); | ||
516 | |||
517 | writel_relaxed(val, addr + SET_REG); | ||
518 | } | ||
519 | |||
520 | static void mxs_clr(unsigned int val, struct mxs_auart_port *uap, | ||
521 | unsigned int reg) | ||
522 | { | ||
523 | void __iomem *addr = uap->port.membase + mxs_reg_to_offset(uap, reg); | ||
524 | |||
525 | writel_relaxed(val, addr + CLR_REG); | ||
526 | } | ||
527 | |||
202 | static void mxs_auart_stop_tx(struct uart_port *u); | 528 | static void mxs_auart_stop_tx(struct uart_port *u); |
203 | 529 | ||
204 | #define to_auart_port(u) container_of(u, struct mxs_auart_port, port) | 530 | #define to_auart_port(u) container_of(u, struct mxs_auart_port, port) |
@@ -295,19 +621,16 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s) | |||
295 | } | 621 | } |
296 | 622 | ||
297 | 623 | ||
298 | while (!(readl(s->port.membase + AUART_STAT) & | 624 | while (!(mxs_read(s, REG_STAT) & AUART_STAT_TXFF)) { |
299 | AUART_STAT_TXFF)) { | ||
300 | if (s->port.x_char) { | 625 | if (s->port.x_char) { |
301 | s->port.icount.tx++; | 626 | s->port.icount.tx++; |
302 | writel(s->port.x_char, | 627 | mxs_write(s->port.x_char, s, REG_DATA); |
303 | s->port.membase + AUART_DATA); | ||
304 | s->port.x_char = 0; | 628 | s->port.x_char = 0; |
305 | continue; | 629 | continue; |
306 | } | 630 | } |
307 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { | 631 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { |
308 | s->port.icount.tx++; | 632 | s->port.icount.tx++; |
309 | writel(xmit->buf[xmit->tail], | 633 | mxs_write(xmit->buf[xmit->tail], s, REG_DATA); |
310 | s->port.membase + AUART_DATA); | ||
311 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 634 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
312 | } else | 635 | } else |
313 | break; | 636 | break; |
@@ -316,11 +639,9 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s) | |||
316 | uart_write_wakeup(&s->port); | 639 | uart_write_wakeup(&s->port); |
317 | 640 | ||
318 | if (uart_circ_empty(&(s->port.state->xmit))) | 641 | if (uart_circ_empty(&(s->port.state->xmit))) |
319 | writel(AUART_INTR_TXIEN, | 642 | mxs_clr(AUART_INTR_TXIEN, s, REG_INTR); |
320 | s->port.membase + AUART_INTR_CLR); | ||
321 | else | 643 | else |
322 | writel(AUART_INTR_TXIEN, | 644 | mxs_set(AUART_INTR_TXIEN, s, REG_INTR); |
323 | s->port.membase + AUART_INTR_SET); | ||
324 | 645 | ||
325 | if (uart_tx_stopped(&s->port)) | 646 | if (uart_tx_stopped(&s->port)) |
326 | mxs_auart_stop_tx(&s->port); | 647 | mxs_auart_stop_tx(&s->port); |
@@ -332,8 +653,8 @@ static void mxs_auart_rx_char(struct mxs_auart_port *s) | |||
332 | u32 stat; | 653 | u32 stat; |
333 | u8 c; | 654 | u8 c; |
334 | 655 | ||
335 | c = readl(s->port.membase + AUART_DATA); | 656 | c = mxs_read(s, REG_DATA); |
336 | stat = readl(s->port.membase + AUART_STAT); | 657 | stat = mxs_read(s, REG_STAT); |
337 | 658 | ||
338 | flag = TTY_NORMAL; | 659 | flag = TTY_NORMAL; |
339 | s->port.icount.rx++; | 660 | s->port.icount.rx++; |
@@ -368,7 +689,7 @@ static void mxs_auart_rx_char(struct mxs_auart_port *s) | |||
368 | 689 | ||
369 | uart_insert_char(&s->port, stat, AUART_STAT_OERR, c, flag); | 690 | uart_insert_char(&s->port, stat, AUART_STAT_OERR, c, flag); |
370 | out: | 691 | out: |
371 | writel(stat, s->port.membase + AUART_STAT); | 692 | mxs_write(stat, s, REG_STAT); |
372 | } | 693 | } |
373 | 694 | ||
374 | static void mxs_auart_rx_chars(struct mxs_auart_port *s) | 695 | static void mxs_auart_rx_chars(struct mxs_auart_port *s) |
@@ -376,13 +697,13 @@ static void mxs_auart_rx_chars(struct mxs_auart_port *s) | |||
376 | u32 stat = 0; | 697 | u32 stat = 0; |
377 | 698 | ||
378 | for (;;) { | 699 | for (;;) { |
379 | stat = readl(s->port.membase + AUART_STAT); | 700 | stat = mxs_read(s, REG_STAT); |
380 | if (stat & AUART_STAT_RXFE) | 701 | if (stat & AUART_STAT_RXFE) |
381 | break; | 702 | break; |
382 | mxs_auart_rx_char(s); | 703 | mxs_auart_rx_char(s); |
383 | } | 704 | } |
384 | 705 | ||
385 | writel(stat, s->port.membase + AUART_STAT); | 706 | mxs_write(stat, s, REG_STAT); |
386 | tty_flip_buffer_push(&s->port.state->port); | 707 | tty_flip_buffer_push(&s->port.state->port); |
387 | } | 708 | } |
388 | 709 | ||
@@ -418,7 +739,7 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
418 | { | 739 | { |
419 | struct mxs_auart_port *s = to_auart_port(u); | 740 | struct mxs_auart_port *s = to_auart_port(u); |
420 | 741 | ||
421 | u32 ctrl = readl(u->membase + AUART_CTRL2); | 742 | u32 ctrl = mxs_read(s, REG_CTRL2); |
422 | 743 | ||
423 | ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS); | 744 | ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS); |
424 | if (mctrl & TIOCM_RTS) { | 745 | if (mctrl & TIOCM_RTS) { |
@@ -428,7 +749,7 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
428 | ctrl |= AUART_CTRL2_RTS; | 749 | ctrl |= AUART_CTRL2_RTS; |
429 | } | 750 | } |
430 | 751 | ||
431 | writel(ctrl, u->membase + AUART_CTRL2); | 752 | mxs_write(ctrl, s, REG_CTRL2); |
432 | 753 | ||
433 | mctrl_gpio_set(s->gpios, mctrl); | 754 | mctrl_gpio_set(s->gpios, mctrl); |
434 | } | 755 | } |
@@ -459,7 +780,7 @@ static u32 mxs_auart_modem_status(struct mxs_auart_port *s, u32 mctrl) | |||
459 | static u32 mxs_auart_get_mctrl(struct uart_port *u) | 780 | static u32 mxs_auart_get_mctrl(struct uart_port *u) |
460 | { | 781 | { |
461 | struct mxs_auart_port *s = to_auart_port(u); | 782 | struct mxs_auart_port *s = to_auart_port(u); |
462 | u32 stat = readl(u->membase + AUART_STAT); | 783 | u32 stat = mxs_read(s, REG_STAT); |
463 | u32 mctrl = 0; | 784 | u32 mctrl = 0; |
464 | 785 | ||
465 | if (stat & AUART_STAT_CTS) | 786 | if (stat & AUART_STAT_CTS) |
@@ -536,14 +857,14 @@ static void dma_rx_callback(void *arg) | |||
536 | 857 | ||
537 | dma_unmap_sg(s->dev, &s->rx_sgl, 1, DMA_FROM_DEVICE); | 858 | dma_unmap_sg(s->dev, &s->rx_sgl, 1, DMA_FROM_DEVICE); |
538 | 859 | ||
539 | stat = readl(s->port.membase + AUART_STAT); | 860 | stat = mxs_read(s, REG_STAT); |
540 | stat &= ~(AUART_STAT_OERR | AUART_STAT_BERR | | 861 | stat &= ~(AUART_STAT_OERR | AUART_STAT_BERR | |
541 | AUART_STAT_PERR | AUART_STAT_FERR); | 862 | AUART_STAT_PERR | AUART_STAT_FERR); |
542 | 863 | ||
543 | count = stat & AUART_STAT_RXCOUNT_MASK; | 864 | count = stat & AUART_STAT_RXCOUNT_MASK; |
544 | tty_insert_flip_string(port, s->rx_dma_buf, count); | 865 | tty_insert_flip_string(port, s->rx_dma_buf, count); |
545 | 866 | ||
546 | writel(stat, s->port.membase + AUART_STAT); | 867 | mxs_write(stat, s, REG_STAT); |
547 | tty_flip_buffer_push(port); | 868 | tty_flip_buffer_push(port); |
548 | 869 | ||
549 | /* start the next DMA for RX. */ | 870 | /* start the next DMA for RX. */ |
@@ -606,8 +927,8 @@ static void mxs_auart_dma_exit_channel(struct mxs_auart_port *s) | |||
606 | static void mxs_auart_dma_exit(struct mxs_auart_port *s) | 927 | static void mxs_auart_dma_exit(struct mxs_auart_port *s) |
607 | { | 928 | { |
608 | 929 | ||
609 | writel(AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR, | 930 | mxs_clr(AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR, |
610 | s->port.membase + AUART_CTRL2_CLR); | 931 | s, REG_CTRL2); |
611 | 932 | ||
612 | mxs_auart_dma_exit_channel(s); | 933 | mxs_auart_dma_exit_channel(s); |
613 | s->flags &= ~MXS_AUART_DMA_ENABLED; | 934 | s->flags &= ~MXS_AUART_DMA_ENABLED; |
@@ -666,7 +987,7 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
666 | cflag = termios->c_cflag; | 987 | cflag = termios->c_cflag; |
667 | 988 | ||
668 | ctrl = AUART_LINECTRL_FEN; | 989 | ctrl = AUART_LINECTRL_FEN; |
669 | ctrl2 = readl(u->membase + AUART_CTRL2); | 990 | ctrl2 = mxs_read(s, REG_CTRL2); |
670 | 991 | ||
671 | /* byte size */ | 992 | /* byte size */ |
672 | switch (cflag & CSIZE) { | 993 | switch (cflag & CSIZE) { |
@@ -754,15 +1075,24 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
754 | } | 1075 | } |
755 | 1076 | ||
756 | /* set baud rate */ | 1077 | /* set baud rate */ |
757 | baud_min = DIV_ROUND_UP(u->uartclk * 32, AUART_LINECTRL_BAUD_DIV_MAX); | 1078 | if (is_asm9260_auart(s)) { |
758 | baud_max = u->uartclk * 32 / AUART_LINECTRL_BAUD_DIV_MIN; | 1079 | baud = uart_get_baud_rate(u, termios, old, |
759 | baud = uart_get_baud_rate(u, termios, old, baud_min, baud_max); | 1080 | u->uartclk * 4 / 0x3FFFFF, |
760 | div = u->uartclk * 32 / baud; | 1081 | u->uartclk / 16); |
1082 | div = u->uartclk * 4 / baud; | ||
1083 | } else { | ||
1084 | baud_min = DIV_ROUND_UP(u->uartclk * 32, | ||
1085 | AUART_LINECTRL_BAUD_DIV_MAX); | ||
1086 | baud_max = u->uartclk * 32 / AUART_LINECTRL_BAUD_DIV_MIN; | ||
1087 | baud = uart_get_baud_rate(u, termios, old, baud_min, baud_max); | ||
1088 | div = u->uartclk * 32 / baud; | ||
1089 | } | ||
1090 | |||
761 | ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F); | 1091 | ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F); |
762 | ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6); | 1092 | ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6); |
1093 | mxs_write(ctrl, s, REG_LINECTRL); | ||
763 | 1094 | ||
764 | writel(ctrl, u->membase + AUART_LINECTRL); | 1095 | mxs_write(ctrl2, s, REG_CTRL2); |
765 | writel(ctrl2, u->membase + AUART_CTRL2); | ||
766 | 1096 | ||
767 | uart_update_timeout(u, termios->c_cflag, baud); | 1097 | uart_update_timeout(u, termios->c_cflag, baud); |
768 | 1098 | ||
@@ -771,8 +1101,8 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
771 | !test_and_set_bit(MXS_AUART_DMA_RX_READY, &s->flags)) { | 1101 | !test_and_set_bit(MXS_AUART_DMA_RX_READY, &s->flags)) { |
772 | if (!mxs_auart_dma_prep_rx(s)) { | 1102 | if (!mxs_auart_dma_prep_rx(s)) { |
773 | /* Disable the normal RX interrupt. */ | 1103 | /* Disable the normal RX interrupt. */ |
774 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN, | 1104 | mxs_clr(AUART_INTR_RXIEN | AUART_INTR_RTIEN, |
775 | u->membase + AUART_INTR_CLR); | 1105 | s, REG_INTR); |
776 | } else { | 1106 | } else { |
777 | mxs_auart_dma_exit(s); | 1107 | mxs_auart_dma_exit(s); |
778 | dev_err(s->dev, "We can not start up the DMA.\n"); | 1108 | dev_err(s->dev, "We can not start up the DMA.\n"); |
@@ -802,16 +1132,13 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | |||
802 | u32 istat; | 1132 | u32 istat; |
803 | struct mxs_auart_port *s = context; | 1133 | struct mxs_auart_port *s = context; |
804 | u32 mctrl_temp = s->mctrl_prev; | 1134 | u32 mctrl_temp = s->mctrl_prev; |
805 | u32 stat = readl(s->port.membase + AUART_STAT); | 1135 | u32 stat = mxs_read(s, REG_STAT); |
806 | 1136 | ||
807 | istat = readl(s->port.membase + AUART_INTR); | 1137 | istat = mxs_read(s, REG_INTR); |
808 | 1138 | ||
809 | /* ack irq */ | 1139 | /* ack irq */ |
810 | writel(istat & (AUART_INTR_RTIS | 1140 | mxs_clr(istat & (AUART_INTR_RTIS | AUART_INTR_TXIS | AUART_INTR_RXIS |
811 | | AUART_INTR_TXIS | 1141 | | AUART_INTR_CTSMIS), s, REG_INTR); |
812 | | AUART_INTR_RXIS | ||
813 | | AUART_INTR_CTSMIS), | ||
814 | s->port.membase + AUART_INTR_CLR); | ||
815 | 1142 | ||
816 | /* | 1143 | /* |
817 | * Dealing with GPIO interrupt | 1144 | * Dealing with GPIO interrupt |
@@ -827,8 +1154,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | |||
827 | if (CTS_AT_AUART() && s->ms_irq_enabled) | 1154 | if (CTS_AT_AUART() && s->ms_irq_enabled) |
828 | uart_handle_cts_change(&s->port, | 1155 | uart_handle_cts_change(&s->port, |
829 | stat & AUART_STAT_CTS); | 1156 | stat & AUART_STAT_CTS); |
830 | writel(AUART_INTR_CTSMIS, | 1157 | mxs_clr(AUART_INTR_CTSMIS, s, REG_INTR); |
831 | s->port.membase + AUART_INTR_CLR); | ||
832 | istat &= ~AUART_INTR_CTSMIS; | 1158 | istat &= ~AUART_INTR_CTSMIS; |
833 | } | 1159 | } |
834 | 1160 | ||
@@ -846,44 +1172,44 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | |||
846 | return IRQ_HANDLED; | 1172 | return IRQ_HANDLED; |
847 | } | 1173 | } |
848 | 1174 | ||
849 | static void mxs_auart_reset_deassert(struct uart_port *u) | 1175 | static void mxs_auart_reset_deassert(struct mxs_auart_port *s) |
850 | { | 1176 | { |
851 | int i; | 1177 | int i; |
852 | unsigned int reg; | 1178 | unsigned int reg; |
853 | 1179 | ||
854 | writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_CLR); | 1180 | mxs_clr(AUART_CTRL0_SFTRST, s, REG_CTRL0); |
855 | 1181 | ||
856 | for (i = 0; i < 10000; i++) { | 1182 | for (i = 0; i < 10000; i++) { |
857 | reg = readl(u->membase + AUART_CTRL0); | 1183 | reg = mxs_read(s, REG_CTRL0); |
858 | if (!(reg & AUART_CTRL0_SFTRST)) | 1184 | if (!(reg & AUART_CTRL0_SFTRST)) |
859 | break; | 1185 | break; |
860 | udelay(3); | 1186 | udelay(3); |
861 | } | 1187 | } |
862 | writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); | 1188 | mxs_clr(AUART_CTRL0_CLKGATE, s, REG_CTRL0); |
863 | } | 1189 | } |
864 | 1190 | ||
865 | static void mxs_auart_reset_assert(struct uart_port *u) | 1191 | static void mxs_auart_reset_assert(struct mxs_auart_port *s) |
866 | { | 1192 | { |
867 | int i; | 1193 | int i; |
868 | u32 reg; | 1194 | u32 reg; |
869 | 1195 | ||
870 | reg = readl(u->membase + AUART_CTRL0); | 1196 | reg = mxs_read(s, REG_CTRL0); |
871 | /* if already in reset state, keep it untouched */ | 1197 | /* if already in reset state, keep it untouched */ |
872 | if (reg & AUART_CTRL0_SFTRST) | 1198 | if (reg & AUART_CTRL0_SFTRST) |
873 | return; | 1199 | return; |
874 | 1200 | ||
875 | writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); | 1201 | mxs_clr(AUART_CTRL0_CLKGATE, s, REG_CTRL0); |
876 | writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_SET); | 1202 | mxs_set(AUART_CTRL0_SFTRST, s, REG_CTRL0); |
877 | 1203 | ||
878 | for (i = 0; i < 1000; i++) { | 1204 | for (i = 0; i < 1000; i++) { |
879 | reg = readl(u->membase + AUART_CTRL0); | 1205 | reg = mxs_read(s, REG_CTRL0); |
880 | /* reset is finished when the clock is gated */ | 1206 | /* reset is finished when the clock is gated */ |
881 | if (reg & AUART_CTRL0_CLKGATE) | 1207 | if (reg & AUART_CTRL0_CLKGATE) |
882 | return; | 1208 | return; |
883 | udelay(10); | 1209 | udelay(10); |
884 | } | 1210 | } |
885 | 1211 | ||
886 | dev_err(u->dev, "Failed to reset the unit."); | 1212 | dev_err(s->dev, "Failed to reset the unit."); |
887 | } | 1213 | } |
888 | 1214 | ||
889 | static int mxs_auart_startup(struct uart_port *u) | 1215 | static int mxs_auart_startup(struct uart_port *u) |
@@ -896,17 +1222,17 @@ static int mxs_auart_startup(struct uart_port *u) | |||
896 | return ret; | 1222 | return ret; |
897 | 1223 | ||
898 | if (uart_console(u)) { | 1224 | if (uart_console(u)) { |
899 | writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); | 1225 | mxs_clr(AUART_CTRL0_CLKGATE, s, REG_CTRL0); |
900 | } else { | 1226 | } else { |
901 | /* reset the unit to a well known state */ | 1227 | /* reset the unit to a well known state */ |
902 | mxs_auart_reset_assert(u); | 1228 | mxs_auart_reset_assert(s); |
903 | mxs_auart_reset_deassert(u); | 1229 | mxs_auart_reset_deassert(s); |
904 | } | 1230 | } |
905 | 1231 | ||
906 | writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET); | 1232 | mxs_set(AUART_CTRL2_UARTEN, s, REG_CTRL2); |
907 | 1233 | ||
908 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, | 1234 | mxs_write(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, |
909 | u->membase + AUART_INTR); | 1235 | s, REG_INTR); |
910 | 1236 | ||
911 | /* Reset FIFO size (it could have changed if DMA was enabled) */ | 1237 | /* Reset FIFO size (it could have changed if DMA was enabled) */ |
912 | u->fifosize = MXS_AUART_FIFO_SIZE; | 1238 | u->fifosize = MXS_AUART_FIFO_SIZE; |
@@ -915,7 +1241,7 @@ static int mxs_auart_startup(struct uart_port *u) | |||
915 | * Enable fifo so all four bytes of a DMA word are written to | 1241 | * Enable fifo so all four bytes of a DMA word are written to |
916 | * output (otherwise, only the LSB is written, ie. 1 in 4 bytes) | 1242 | * output (otherwise, only the LSB is written, ie. 1 in 4 bytes) |
917 | */ | 1243 | */ |
918 | writel(AUART_LINECTRL_FEN, u->membase + AUART_LINECTRL_SET); | 1244 | mxs_set(AUART_LINECTRL_FEN, s, REG_LINECTRL); |
919 | 1245 | ||
920 | /* get initial status of modem lines */ | 1246 | /* get initial status of modem lines */ |
921 | mctrl_gpio_get(s->gpios, &s->mctrl_prev); | 1247 | mctrl_gpio_get(s->gpios, &s->mctrl_prev); |
@@ -934,12 +1260,13 @@ static void mxs_auart_shutdown(struct uart_port *u) | |||
934 | mxs_auart_dma_exit(s); | 1260 | mxs_auart_dma_exit(s); |
935 | 1261 | ||
936 | if (uart_console(u)) { | 1262 | if (uart_console(u)) { |
937 | writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); | 1263 | mxs_clr(AUART_CTRL2_UARTEN, s, REG_CTRL2); |
938 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, | 1264 | |
939 | u->membase + AUART_INTR_CLR); | 1265 | mxs_clr(AUART_INTR_RXIEN | AUART_INTR_RTIEN | |
940 | writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); | 1266 | AUART_INTR_CTSMIEN, s, REG_INTR); |
1267 | mxs_set(AUART_CTRL0_CLKGATE, s, REG_CTRL0); | ||
941 | } else { | 1268 | } else { |
942 | mxs_auart_reset_assert(u); | 1269 | mxs_auart_reset_assert(s); |
943 | } | 1270 | } |
944 | 1271 | ||
945 | clk_disable_unprepare(s->clk); | 1272 | clk_disable_unprepare(s->clk); |
@@ -947,7 +1274,9 @@ static void mxs_auart_shutdown(struct uart_port *u) | |||
947 | 1274 | ||
948 | static unsigned int mxs_auart_tx_empty(struct uart_port *u) | 1275 | static unsigned int mxs_auart_tx_empty(struct uart_port *u) |
949 | { | 1276 | { |
950 | if ((readl(u->membase + AUART_STAT) & | 1277 | struct mxs_auart_port *s = to_auart_port(u); |
1278 | |||
1279 | if ((mxs_read(s, REG_STAT) & | ||
951 | (AUART_STAT_TXFE | AUART_STAT_BUSY)) == AUART_STAT_TXFE) | 1280 | (AUART_STAT_TXFE | AUART_STAT_BUSY)) == AUART_STAT_TXFE) |
952 | return TIOCSER_TEMT; | 1281 | return TIOCSER_TEMT; |
953 | 1282 | ||
@@ -959,29 +1288,33 @@ static void mxs_auart_start_tx(struct uart_port *u) | |||
959 | struct mxs_auart_port *s = to_auart_port(u); | 1288 | struct mxs_auart_port *s = to_auart_port(u); |
960 | 1289 | ||
961 | /* enable transmitter */ | 1290 | /* enable transmitter */ |
962 | writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_SET); | 1291 | mxs_set(AUART_CTRL2_TXE, s, REG_CTRL2); |
963 | 1292 | ||
964 | mxs_auart_tx_chars(s); | 1293 | mxs_auart_tx_chars(s); |
965 | } | 1294 | } |
966 | 1295 | ||
967 | static void mxs_auart_stop_tx(struct uart_port *u) | 1296 | static void mxs_auart_stop_tx(struct uart_port *u) |
968 | { | 1297 | { |
969 | writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_CLR); | 1298 | struct mxs_auart_port *s = to_auart_port(u); |
1299 | |||
1300 | mxs_clr(AUART_CTRL2_TXE, s, REG_CTRL2); | ||
970 | } | 1301 | } |
971 | 1302 | ||
972 | static void mxs_auart_stop_rx(struct uart_port *u) | 1303 | static void mxs_auart_stop_rx(struct uart_port *u) |
973 | { | 1304 | { |
974 | writel(AUART_CTRL2_RXE, u->membase + AUART_CTRL2_CLR); | 1305 | struct mxs_auart_port *s = to_auart_port(u); |
1306 | |||
1307 | mxs_clr(AUART_CTRL2_RXE, s, REG_CTRL2); | ||
975 | } | 1308 | } |
976 | 1309 | ||
977 | static void mxs_auart_break_ctl(struct uart_port *u, int ctl) | 1310 | static void mxs_auart_break_ctl(struct uart_port *u, int ctl) |
978 | { | 1311 | { |
1312 | struct mxs_auart_port *s = to_auart_port(u); | ||
1313 | |||
979 | if (ctl) | 1314 | if (ctl) |
980 | writel(AUART_LINECTRL_BRK, | 1315 | mxs_set(AUART_LINECTRL_BRK, s, REG_LINECTRL); |
981 | u->membase + AUART_LINECTRL_SET); | ||
982 | else | 1316 | else |
983 | writel(AUART_LINECTRL_BRK, | 1317 | mxs_clr(AUART_LINECTRL_BRK, s, REG_LINECTRL); |
984 | u->membase + AUART_LINECTRL_CLR); | ||
985 | } | 1318 | } |
986 | 1319 | ||
987 | static struct uart_ops mxs_auart_ops = { | 1320 | static struct uart_ops mxs_auart_ops = { |
@@ -1009,15 +1342,16 @@ static struct mxs_auart_port *auart_port[MXS_AUART_PORTS]; | |||
1009 | #ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE | 1342 | #ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE |
1010 | static void mxs_auart_console_putchar(struct uart_port *port, int ch) | 1343 | static void mxs_auart_console_putchar(struct uart_port *port, int ch) |
1011 | { | 1344 | { |
1345 | struct mxs_auart_port *s = to_auart_port(port); | ||
1012 | unsigned int to = 1000; | 1346 | unsigned int to = 1000; |
1013 | 1347 | ||
1014 | while (readl(port->membase + AUART_STAT) & AUART_STAT_TXFF) { | 1348 | while (mxs_read(s, REG_STAT) & AUART_STAT_TXFF) { |
1015 | if (!to--) | 1349 | if (!to--) |
1016 | break; | 1350 | break; |
1017 | udelay(1); | 1351 | udelay(1); |
1018 | } | 1352 | } |
1019 | 1353 | ||
1020 | writel(ch, port->membase + AUART_DATA); | 1354 | mxs_write(ch, s, REG_DATA); |
1021 | } | 1355 | } |
1022 | 1356 | ||
1023 | static void | 1357 | static void |
@@ -1037,18 +1371,16 @@ auart_console_write(struct console *co, const char *str, unsigned int count) | |||
1037 | clk_enable(s->clk); | 1371 | clk_enable(s->clk); |
1038 | 1372 | ||
1039 | /* First save the CR then disable the interrupts */ | 1373 | /* First save the CR then disable the interrupts */ |
1040 | old_ctrl2 = readl(port->membase + AUART_CTRL2); | 1374 | old_ctrl2 = mxs_read(s, REG_CTRL2); |
1041 | old_ctrl0 = readl(port->membase + AUART_CTRL0); | 1375 | old_ctrl0 = mxs_read(s, REG_CTRL0); |
1042 | 1376 | ||
1043 | writel(AUART_CTRL0_CLKGATE, | 1377 | mxs_clr(AUART_CTRL0_CLKGATE, s, REG_CTRL0); |
1044 | port->membase + AUART_CTRL0_CLR); | 1378 | mxs_set(AUART_CTRL2_UARTEN | AUART_CTRL2_TXE, s, REG_CTRL2); |
1045 | writel(AUART_CTRL2_UARTEN | AUART_CTRL2_TXE, | ||
1046 | port->membase + AUART_CTRL2_SET); | ||
1047 | 1379 | ||
1048 | uart_console_write(port, str, count, mxs_auart_console_putchar); | 1380 | uart_console_write(port, str, count, mxs_auart_console_putchar); |
1049 | 1381 | ||
1050 | /* Finally, wait for transmitter to become empty ... */ | 1382 | /* Finally, wait for transmitter to become empty ... */ |
1051 | while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { | 1383 | while (mxs_read(s, REG_STAT) & AUART_STAT_BUSY) { |
1052 | udelay(1); | 1384 | udelay(1); |
1053 | if (!to--) | 1385 | if (!to--) |
1054 | break; | 1386 | break; |
@@ -1060,24 +1392,25 @@ auart_console_write(struct console *co, const char *str, unsigned int count) | |||
1060 | * unused, but that is better than to disable it while it is still | 1392 | * unused, but that is better than to disable it while it is still |
1061 | * transmitting. | 1393 | * transmitting. |
1062 | */ | 1394 | */ |
1063 | if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) { | 1395 | if (!(mxs_read(s, REG_STAT) & AUART_STAT_BUSY)) { |
1064 | writel(old_ctrl0, port->membase + AUART_CTRL0); | 1396 | mxs_write(old_ctrl0, s, REG_CTRL0); |
1065 | writel(old_ctrl2, port->membase + AUART_CTRL2); | 1397 | mxs_write(old_ctrl2, s, REG_CTRL2); |
1066 | } | 1398 | } |
1067 | 1399 | ||
1068 | clk_disable(s->clk); | 1400 | clk_disable(s->clk); |
1069 | } | 1401 | } |
1070 | 1402 | ||
1071 | static void __init | 1403 | static void __init |
1072 | auart_console_get_options(struct uart_port *port, int *baud, | 1404 | auart_console_get_options(struct mxs_auart_port *s, int *baud, |
1073 | int *parity, int *bits) | 1405 | int *parity, int *bits) |
1074 | { | 1406 | { |
1407 | struct uart_port *port = &s->port; | ||
1075 | unsigned int lcr_h, quot; | 1408 | unsigned int lcr_h, quot; |
1076 | 1409 | ||
1077 | if (!(readl(port->membase + AUART_CTRL2) & AUART_CTRL2_UARTEN)) | 1410 | if (!(mxs_read(s, REG_CTRL2) & AUART_CTRL2_UARTEN)) |
1078 | return; | 1411 | return; |
1079 | 1412 | ||
1080 | lcr_h = readl(port->membase + AUART_LINECTRL); | 1413 | lcr_h = mxs_read(s, REG_LINECTRL); |
1081 | 1414 | ||
1082 | *parity = 'n'; | 1415 | *parity = 'n'; |
1083 | if (lcr_h & AUART_LINECTRL_PEN) { | 1416 | if (lcr_h & AUART_LINECTRL_PEN) { |
@@ -1092,12 +1425,10 @@ auart_console_get_options(struct uart_port *port, int *baud, | |||
1092 | else | 1425 | else |
1093 | *bits = 8; | 1426 | *bits = 8; |
1094 | 1427 | ||
1095 | quot = ((readl(port->membase + AUART_LINECTRL) | 1428 | quot = ((mxs_read(s, REG_LINECTRL) & AUART_LINECTRL_BAUD_DIVINT_MASK)) |
1096 | & AUART_LINECTRL_BAUD_DIVINT_MASK)) | 1429 | >> (AUART_LINECTRL_BAUD_DIVINT_SHIFT - 6); |
1097 | >> (AUART_LINECTRL_BAUD_DIVINT_SHIFT - 6); | 1430 | quot |= ((mxs_read(s, REG_LINECTRL) & AUART_LINECTRL_BAUD_DIVFRAC_MASK)) |
1098 | quot |= ((readl(port->membase + AUART_LINECTRL) | 1431 | >> AUART_LINECTRL_BAUD_DIVFRAC_SHIFT; |
1099 | & AUART_LINECTRL_BAUD_DIVFRAC_MASK)) | ||
1100 | >> AUART_LINECTRL_BAUD_DIVFRAC_SHIFT; | ||
1101 | if (quot == 0) | 1432 | if (quot == 0) |
1102 | quot = 1; | 1433 | quot = 1; |
1103 | 1434 | ||
@@ -1132,7 +1463,7 @@ auart_console_setup(struct console *co, char *options) | |||
1132 | if (options) | 1463 | if (options) |
1133 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1464 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
1134 | else | 1465 | else |
1135 | auart_console_get_options(&s->port, &baud, &parity, &bits); | 1466 | auart_console_get_options(s, &baud, &parity, &bits); |
1136 | 1467 | ||
1137 | ret = uart_set_options(&s->port, co, baud, parity, bits, flow); | 1468 | ret = uart_set_options(&s->port, co, baud, parity, bits, flow); |
1138 | 1469 | ||
@@ -1164,6 +1495,60 @@ static struct uart_driver auart_driver = { | |||
1164 | #endif | 1495 | #endif |
1165 | }; | 1496 | }; |
1166 | 1497 | ||
1498 | static void mxs_init_regs(struct mxs_auart_port *s) | ||
1499 | { | ||
1500 | if (is_asm9260_auart(s)) | ||
1501 | s->vendor = &vendor_alphascale_asm9260; | ||
1502 | else | ||
1503 | s->vendor = &vendor_freescale_stmp37xx; | ||
1504 | } | ||
1505 | |||
1506 | static int mxs_get_clks(struct mxs_auart_port *s, | ||
1507 | struct platform_device *pdev) | ||
1508 | { | ||
1509 | int err; | ||
1510 | |||
1511 | if (!is_asm9260_auart(s)) { | ||
1512 | s->clk = devm_clk_get(&pdev->dev, NULL); | ||
1513 | if (IS_ERR(s->clk)) | ||
1514 | return PTR_ERR(s->clk); | ||
1515 | |||
1516 | return 0; | ||
1517 | } | ||
1518 | |||
1519 | s->clk = devm_clk_get(s->dev, "mod"); | ||
1520 | if (IS_ERR(s->clk)) { | ||
1521 | dev_err(s->dev, "Failed to get \"mod\" clk\n"); | ||
1522 | return PTR_ERR(s->clk); | ||
1523 | } | ||
1524 | |||
1525 | s->clk_ahb = devm_clk_get(s->dev, "ahb"); | ||
1526 | if (IS_ERR(s->clk_ahb)) { | ||
1527 | dev_err(s->dev, "Failed to get \"ahb\" clk\n"); | ||
1528 | return PTR_ERR(s->clk_ahb); | ||
1529 | } | ||
1530 | |||
1531 | err = clk_prepare_enable(s->clk_ahb); | ||
1532 | if (err) { | ||
1533 | dev_err(s->dev, "Failed to enable ahb_clk!\n"); | ||
1534 | return err; | ||
1535 | } | ||
1536 | |||
1537 | err = clk_set_rate(s->clk, clk_get_rate(s->clk_ahb)); | ||
1538 | if (err) { | ||
1539 | dev_err(s->dev, "Failed to set rate!\n"); | ||
1540 | return err; | ||
1541 | } | ||
1542 | |||
1543 | err = clk_prepare_enable(s->clk); | ||
1544 | if (err) { | ||
1545 | dev_err(s->dev, "Failed to enable clk!\n"); | ||
1546 | return err; | ||
1547 | } | ||
1548 | |||
1549 | return 0; | ||
1550 | } | ||
1551 | |||
1167 | /* | 1552 | /* |
1168 | * This function returns 1 if pdev isn't a device instatiated by dt, 0 if it | 1553 | * This function returns 1 if pdev isn't a device instatiated by dt, 0 if it |
1169 | * could successfully get all information from dt or a negative errno. | 1554 | * could successfully get all information from dt or a negative errno. |
@@ -1185,7 +1570,8 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, | |||
1185 | } | 1570 | } |
1186 | s->port.line = ret; | 1571 | s->port.line = ret; |
1187 | 1572 | ||
1188 | if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) | 1573 | if (of_get_property(np, "uart-has-rtscts", NULL) || |
1574 | of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */) | ||
1189 | set_bit(MXS_AUART_RTSCTS, &s->flags); | 1575 | set_bit(MXS_AUART_RTSCTS, &s->flags); |
1190 | 1576 | ||
1191 | return 0; | 1577 | return 0; |
@@ -1269,6 +1655,9 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1269 | if (!s) | 1655 | if (!s) |
1270 | return -ENOMEM; | 1656 | return -ENOMEM; |
1271 | 1657 | ||
1658 | s->port.dev = &pdev->dev; | ||
1659 | s->dev = &pdev->dev; | ||
1660 | |||
1272 | ret = serial_mxs_probe_dt(s, pdev); | 1661 | ret = serial_mxs_probe_dt(s, pdev); |
1273 | if (ret > 0) | 1662 | if (ret > 0) |
1274 | s->port.line = pdev->id < 0 ? 0 : pdev->id; | 1663 | s->port.line = pdev->id < 0 ? 0 : pdev->id; |
@@ -1280,15 +1669,14 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1280 | s->devtype = pdev->id_entry->driver_data; | 1669 | s->devtype = pdev->id_entry->driver_data; |
1281 | } | 1670 | } |
1282 | 1671 | ||
1283 | s->clk = devm_clk_get(&pdev->dev, NULL); | 1672 | ret = mxs_get_clks(s, pdev); |
1284 | if (IS_ERR(s->clk)) | 1673 | if (ret) |
1285 | return PTR_ERR(s->clk); | 1674 | return ret; |
1286 | 1675 | ||
1287 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1676 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1288 | if (!r) | 1677 | if (!r) |
1289 | return -ENXIO; | 1678 | return -ENXIO; |
1290 | 1679 | ||
1291 | |||
1292 | s->port.mapbase = r->start; | 1680 | s->port.mapbase = r->start; |
1293 | s->port.membase = ioremap(r->start, resource_size(r)); | 1681 | s->port.membase = ioremap(r->start, resource_size(r)); |
1294 | s->port.ops = &mxs_auart_ops; | 1682 | s->port.ops = &mxs_auart_ops; |
@@ -1296,7 +1684,8 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1296 | s->port.fifosize = MXS_AUART_FIFO_SIZE; | 1684 | s->port.fifosize = MXS_AUART_FIFO_SIZE; |
1297 | s->port.uartclk = clk_get_rate(s->clk); | 1685 | s->port.uartclk = clk_get_rate(s->clk); |
1298 | s->port.type = PORT_IMX; | 1686 | s->port.type = PORT_IMX; |
1299 | s->port.dev = s->dev = &pdev->dev; | 1687 | |
1688 | mxs_init_regs(s); | ||
1300 | 1689 | ||
1301 | s->mctrl_prev = 0; | 1690 | s->mctrl_prev = 0; |
1302 | 1691 | ||
@@ -1327,16 +1716,21 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1327 | 1716 | ||
1328 | auart_port[s->port.line] = s; | 1717 | auart_port[s->port.line] = s; |
1329 | 1718 | ||
1330 | mxs_auart_reset_deassert(&s->port); | 1719 | mxs_auart_reset_deassert(s); |
1331 | 1720 | ||
1332 | ret = uart_add_one_port(&auart_driver, &s->port); | 1721 | ret = uart_add_one_port(&auart_driver, &s->port); |
1333 | if (ret) | 1722 | if (ret) |
1334 | goto out_free_gpio_irq; | 1723 | goto out_free_gpio_irq; |
1335 | 1724 | ||
1336 | version = readl(s->port.membase + AUART_VERSION); | 1725 | /* ASM9260 don't have version reg */ |
1337 | dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n", | 1726 | if (is_asm9260_auart(s)) { |
1338 | (version >> 24) & 0xff, | 1727 | dev_info(&pdev->dev, "Found APPUART ASM9260\n"); |
1339 | (version >> 16) & 0xff, version & 0xffff); | 1728 | } else { |
1729 | version = mxs_read(s, REG_VERSION); | ||
1730 | dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n", | ||
1731 | (version >> 24) & 0xff, | ||
1732 | (version >> 16) & 0xff, version & 0xffff); | ||
1733 | } | ||
1340 | 1734 | ||
1341 | return 0; | 1735 | return 0; |
1342 | 1736 | ||
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index ac7f8df54406..99bb23161dd6 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -1271,6 +1271,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
1271 | /* check to see if we need to change clock source */ | 1271 | /* check to see if we need to change clock source */ |
1272 | 1272 | ||
1273 | if (ourport->baudclk != clk) { | 1273 | if (ourport->baudclk != clk) { |
1274 | clk_prepare_enable(clk); | ||
1275 | |||
1274 | s3c24xx_serial_setsource(port, clk_sel); | 1276 | s3c24xx_serial_setsource(port, clk_sel); |
1275 | 1277 | ||
1276 | if (!IS_ERR(ourport->baudclk)) { | 1278 | if (!IS_ERR(ourport->baudclk)) { |
@@ -1278,8 +1280,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
1278 | ourport->baudclk = ERR_PTR(-EINVAL); | 1280 | ourport->baudclk = ERR_PTR(-EINVAL); |
1279 | } | 1281 | } |
1280 | 1282 | ||
1281 | clk_prepare_enable(clk); | ||
1282 | |||
1283 | ourport->baudclk = clk; | 1283 | ourport->baudclk = clk; |
1284 | ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; | 1284 | ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; |
1285 | } | 1285 | } |
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index e6393619405a..f36e6df2fa90 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c | |||
@@ -666,7 +666,7 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) | |||
666 | struct uart_port *port = &s->p[portno].port; | 666 | struct uart_port *port = &s->p[portno].port; |
667 | 667 | ||
668 | do { | 668 | do { |
669 | unsigned int iir, msr, rxlen; | 669 | unsigned int iir, rxlen; |
670 | 670 | ||
671 | iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG); | 671 | iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG); |
672 | if (iir & SC16IS7XX_IIR_NO_INT_BIT) | 672 | if (iir & SC16IS7XX_IIR_NO_INT_BIT) |
@@ -683,12 +683,6 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) | |||
683 | if (rxlen) | 683 | if (rxlen) |
684 | sc16is7xx_handle_rx(port, rxlen, iir); | 684 | sc16is7xx_handle_rx(port, rxlen, iir); |
685 | break; | 685 | break; |
686 | |||
687 | case SC16IS7XX_IIR_CTSRTS_SRC: | ||
688 | msr = sc16is7xx_port_read(port, SC16IS7XX_MSR_REG); | ||
689 | uart_handle_cts_change(port, | ||
690 | !!(msr & SC16IS7XX_MSR_DCTS_BIT)); | ||
691 | break; | ||
692 | case SC16IS7XX_IIR_THRI_SRC: | 686 | case SC16IS7XX_IIR_THRI_SRC: |
693 | sc16is7xx_handle_tx(port); | 687 | sc16is7xx_handle_tx(port); |
694 | break; | 688 | break; |
@@ -1014,9 +1008,8 @@ static int sc16is7xx_startup(struct uart_port *port) | |||
1014 | SC16IS7XX_EFCR_TXDISABLE_BIT, | 1008 | SC16IS7XX_EFCR_TXDISABLE_BIT, |
1015 | 0); | 1009 | 0); |
1016 | 1010 | ||
1017 | /* Enable RX, TX, CTS change interrupts */ | 1011 | /* Enable RX, TX interrupts */ |
1018 | val = SC16IS7XX_IER_RDI_BIT | SC16IS7XX_IER_THRI_BIT | | 1012 | val = SC16IS7XX_IER_RDI_BIT | SC16IS7XX_IER_THRI_BIT; |
1019 | SC16IS7XX_IER_CTSI_BIT; | ||
1020 | sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); | 1013 | sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); |
1021 | 1014 | ||
1022 | return 0; | 1015 | return 0; |
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 1d6fc60ed013..1dba6719db8d 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c | |||
@@ -206,10 +206,8 @@ static void set_dtr(struct tegra_uart_port *tup, bool active) | |||
206 | static void tegra_uart_set_mctrl(struct uart_port *u, unsigned int mctrl) | 206 | static void tegra_uart_set_mctrl(struct uart_port *u, unsigned int mctrl) |
207 | { | 207 | { |
208 | struct tegra_uart_port *tup = to_tegra_uport(u); | 208 | struct tegra_uart_port *tup = to_tegra_uport(u); |
209 | unsigned long mcr; | ||
210 | int dtr_enable; | 209 | int dtr_enable; |
211 | 210 | ||
212 | mcr = tup->mcr_shadow; | ||
213 | tup->rts_active = !!(mctrl & TIOCM_RTS); | 211 | tup->rts_active = !!(mctrl & TIOCM_RTS); |
214 | set_rts(tup, tup->rts_active); | 212 | set_rts(tup, tup->rts_active); |
215 | 213 | ||
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a126a603b083..a333c59cba2c 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -64,6 +64,41 @@ static int uart_dcd_enabled(struct uart_port *uport) | |||
64 | return !!(uport->status & UPSTAT_DCD_ENABLE); | 64 | return !!(uport->status & UPSTAT_DCD_ENABLE); |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline struct uart_port *uart_port_ref(struct uart_state *state) | ||
68 | { | ||
69 | if (atomic_add_unless(&state->refcount, 1, 0)) | ||
70 | return state->uart_port; | ||
71 | return NULL; | ||
72 | } | ||
73 | |||
74 | static inline void uart_port_deref(struct uart_port *uport) | ||
75 | { | ||
76 | if (uport && atomic_dec_and_test(&uport->state->refcount)) | ||
77 | wake_up(&uport->state->remove_wait); | ||
78 | } | ||
79 | |||
80 | #define uart_port_lock(state, flags) \ | ||
81 | ({ \ | ||
82 | struct uart_port *__uport = uart_port_ref(state); \ | ||
83 | if (__uport) \ | ||
84 | spin_lock_irqsave(&__uport->lock, flags); \ | ||
85 | __uport; \ | ||
86 | }) | ||
87 | |||
88 | #define uart_port_unlock(uport, flags) \ | ||
89 | ({ \ | ||
90 | struct uart_port *__uport = uport; \ | ||
91 | if (__uport) \ | ||
92 | spin_unlock_irqrestore(&__uport->lock, flags); \ | ||
93 | uart_port_deref(__uport); \ | ||
94 | }) | ||
95 | |||
96 | static inline struct uart_port *uart_port_check(struct uart_state *state) | ||
97 | { | ||
98 | lockdep_assert_held(&state->port.mutex); | ||
99 | return state->uart_port; | ||
100 | } | ||
101 | |||
67 | /* | 102 | /* |
68 | * This routine is used by the interrupt handler to schedule processing in | 103 | * This routine is used by the interrupt handler to schedule processing in |
69 | * the software interrupt portion of the driver. | 104 | * the software interrupt portion of the driver. |
@@ -82,12 +117,13 @@ void uart_write_wakeup(struct uart_port *port) | |||
82 | static void uart_stop(struct tty_struct *tty) | 117 | static void uart_stop(struct tty_struct *tty) |
83 | { | 118 | { |
84 | struct uart_state *state = tty->driver_data; | 119 | struct uart_state *state = tty->driver_data; |
85 | struct uart_port *port = state->uart_port; | 120 | struct uart_port *port; |
86 | unsigned long flags; | 121 | unsigned long flags; |
87 | 122 | ||
88 | spin_lock_irqsave(&port->lock, flags); | 123 | port = uart_port_lock(state, flags); |
89 | port->ops->stop_tx(port); | 124 | if (port) |
90 | spin_unlock_irqrestore(&port->lock, flags); | 125 | port->ops->stop_tx(port); |
126 | uart_port_unlock(port, flags); | ||
91 | } | 127 | } |
92 | 128 | ||
93 | static void __uart_start(struct tty_struct *tty) | 129 | static void __uart_start(struct tty_struct *tty) |
@@ -95,19 +131,19 @@ static void __uart_start(struct tty_struct *tty) | |||
95 | struct uart_state *state = tty->driver_data; | 131 | struct uart_state *state = tty->driver_data; |
96 | struct uart_port *port = state->uart_port; | 132 | struct uart_port *port = state->uart_port; |
97 | 133 | ||
98 | if (!uart_tx_stopped(port)) | 134 | if (port && !uart_tx_stopped(port)) |
99 | port->ops->start_tx(port); | 135 | port->ops->start_tx(port); |
100 | } | 136 | } |
101 | 137 | ||
102 | static void uart_start(struct tty_struct *tty) | 138 | static void uart_start(struct tty_struct *tty) |
103 | { | 139 | { |
104 | struct uart_state *state = tty->driver_data; | 140 | struct uart_state *state = tty->driver_data; |
105 | struct uart_port *port = state->uart_port; | 141 | struct uart_port *port; |
106 | unsigned long flags; | 142 | unsigned long flags; |
107 | 143 | ||
108 | spin_lock_irqsave(&port->lock, flags); | 144 | port = uart_port_lock(state, flags); |
109 | __uart_start(tty); | 145 | __uart_start(tty); |
110 | spin_unlock_irqrestore(&port->lock, flags); | 146 | uart_port_unlock(port, flags); |
111 | } | 147 | } |
112 | 148 | ||
113 | static void | 149 | static void |
@@ -134,7 +170,7 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) | |||
134 | static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | 170 | static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, |
135 | int init_hw) | 171 | int init_hw) |
136 | { | 172 | { |
137 | struct uart_port *uport = state->uart_port; | 173 | struct uart_port *uport = uart_port_check(state); |
138 | unsigned long page; | 174 | unsigned long page; |
139 | int retval = 0; | 175 | int retval = 0; |
140 | 176 | ||
@@ -196,7 +232,7 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, | |||
196 | struct tty_port *port = &state->port; | 232 | struct tty_port *port = &state->port; |
197 | int retval; | 233 | int retval; |
198 | 234 | ||
199 | if (port->flags & ASYNC_INITIALIZED) | 235 | if (tty_port_initialized(port)) |
200 | return 0; | 236 | return 0; |
201 | 237 | ||
202 | /* | 238 | /* |
@@ -207,7 +243,7 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, | |||
207 | 243 | ||
208 | retval = uart_port_startup(tty, state, init_hw); | 244 | retval = uart_port_startup(tty, state, init_hw); |
209 | if (!retval) { | 245 | if (!retval) { |
210 | set_bit(ASYNCB_INITIALIZED, &port->flags); | 246 | tty_port_set_initialized(port, 1); |
211 | clear_bit(TTY_IO_ERROR, &tty->flags); | 247 | clear_bit(TTY_IO_ERROR, &tty->flags); |
212 | } else if (retval > 0) | 248 | } else if (retval > 0) |
213 | retval = 0; | 249 | retval = 0; |
@@ -219,10 +255,12 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, | |||
219 | * This routine will shutdown a serial port; interrupts are disabled, and | 255 | * This routine will shutdown a serial port; interrupts are disabled, and |
220 | * DTR is dropped if the hangup on close termio flag is on. Calls to | 256 | * DTR is dropped if the hangup on close termio flag is on. Calls to |
221 | * uart_shutdown are serialised by the per-port semaphore. | 257 | * uart_shutdown are serialised by the per-port semaphore. |
258 | * | ||
259 | * uport == NULL if uart_port has already been removed | ||
222 | */ | 260 | */ |
223 | static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) | 261 | static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) |
224 | { | 262 | { |
225 | struct uart_port *uport = state->uart_port; | 263 | struct uart_port *uport = uart_port_check(state); |
226 | struct tty_port *port = &state->port; | 264 | struct tty_port *port = &state->port; |
227 | 265 | ||
228 | /* | 266 | /* |
@@ -231,11 +269,13 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) | |||
231 | if (tty) | 269 | if (tty) |
232 | set_bit(TTY_IO_ERROR, &tty->flags); | 270 | set_bit(TTY_IO_ERROR, &tty->flags); |
233 | 271 | ||
234 | if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { | 272 | if (tty_port_initialized(port)) { |
273 | tty_port_set_initialized(port, 0); | ||
274 | |||
235 | /* | 275 | /* |
236 | * Turn off DTR and RTS early. | 276 | * Turn off DTR and RTS early. |
237 | */ | 277 | */ |
238 | if (uart_console(uport) && tty) | 278 | if (uport && uart_console(uport) && tty) |
239 | uport->cons->cflag = tty->termios.c_cflag; | 279 | uport->cons->cflag = tty->termios.c_cflag; |
240 | 280 | ||
241 | if (!tty || C_HUPCL(tty)) | 281 | if (!tty || C_HUPCL(tty)) |
@@ -249,7 +289,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) | |||
249 | * a DCD drop (hangup) at just the right time. Clear suspended bit so | 289 | * a DCD drop (hangup) at just the right time. Clear suspended bit so |
250 | * we don't try to resume a port that has been shutdown. | 290 | * we don't try to resume a port that has been shutdown. |
251 | */ | 291 | */ |
252 | clear_bit(ASYNCB_SUSPENDED, &port->flags); | 292 | tty_port_set_suspended(port, 0); |
253 | 293 | ||
254 | /* | 294 | /* |
255 | * Free the transmit buffer page. | 295 | * Free the transmit buffer page. |
@@ -441,7 +481,7 @@ EXPORT_SYMBOL(uart_get_divisor); | |||
441 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | 481 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
442 | struct ktermios *old_termios) | 482 | struct ktermios *old_termios) |
443 | { | 483 | { |
444 | struct uart_port *uport = state->uart_port; | 484 | struct uart_port *uport = uart_port_check(state); |
445 | struct ktermios *termios; | 485 | struct ktermios *termios; |
446 | int hw_stopped; | 486 | int hw_stopped; |
447 | 487 | ||
@@ -486,7 +526,7 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | |||
486 | static int uart_put_char(struct tty_struct *tty, unsigned char c) | 526 | static int uart_put_char(struct tty_struct *tty, unsigned char c) |
487 | { | 527 | { |
488 | struct uart_state *state = tty->driver_data; | 528 | struct uart_state *state = tty->driver_data; |
489 | struct uart_port *port = state->uart_port; | 529 | struct uart_port *port; |
490 | struct circ_buf *circ; | 530 | struct circ_buf *circ; |
491 | unsigned long flags; | 531 | unsigned long flags; |
492 | int ret = 0; | 532 | int ret = 0; |
@@ -495,13 +535,13 @@ static int uart_put_char(struct tty_struct *tty, unsigned char c) | |||
495 | if (!circ->buf) | 535 | if (!circ->buf) |
496 | return 0; | 536 | return 0; |
497 | 537 | ||
498 | spin_lock_irqsave(&port->lock, flags); | 538 | port = uart_port_lock(state, flags); |
499 | if (uart_circ_chars_free(circ) != 0) { | 539 | if (port && uart_circ_chars_free(circ) != 0) { |
500 | circ->buf[circ->head] = c; | 540 | circ->buf[circ->head] = c; |
501 | circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); | 541 | circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); |
502 | ret = 1; | 542 | ret = 1; |
503 | } | 543 | } |
504 | spin_unlock_irqrestore(&port->lock, flags); | 544 | uart_port_unlock(port, flags); |
505 | return ret; | 545 | return ret; |
506 | } | 546 | } |
507 | 547 | ||
@@ -528,14 +568,12 @@ static int uart_write(struct tty_struct *tty, | |||
528 | return -EL3HLT; | 568 | return -EL3HLT; |
529 | } | 569 | } |
530 | 570 | ||
531 | port = state->uart_port; | ||
532 | circ = &state->xmit; | 571 | circ = &state->xmit; |
533 | |||
534 | if (!circ->buf) | 572 | if (!circ->buf) |
535 | return 0; | 573 | return 0; |
536 | 574 | ||
537 | spin_lock_irqsave(&port->lock, flags); | 575 | port = uart_port_lock(state, flags); |
538 | while (1) { | 576 | while (port) { |
539 | c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); | 577 | c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); |
540 | if (count < c) | 578 | if (count < c) |
541 | c = count; | 579 | c = count; |
@@ -549,32 +587,33 @@ static int uart_write(struct tty_struct *tty, | |||
549 | } | 587 | } |
550 | 588 | ||
551 | __uart_start(tty); | 589 | __uart_start(tty); |
552 | spin_unlock_irqrestore(&port->lock, flags); | 590 | uart_port_unlock(port, flags); |
553 | |||
554 | return ret; | 591 | return ret; |
555 | } | 592 | } |
556 | 593 | ||
557 | static int uart_write_room(struct tty_struct *tty) | 594 | static int uart_write_room(struct tty_struct *tty) |
558 | { | 595 | { |
559 | struct uart_state *state = tty->driver_data; | 596 | struct uart_state *state = tty->driver_data; |
597 | struct uart_port *port; | ||
560 | unsigned long flags; | 598 | unsigned long flags; |
561 | int ret; | 599 | int ret; |
562 | 600 | ||
563 | spin_lock_irqsave(&state->uart_port->lock, flags); | 601 | port = uart_port_lock(state, flags); |
564 | ret = uart_circ_chars_free(&state->xmit); | 602 | ret = uart_circ_chars_free(&state->xmit); |
565 | spin_unlock_irqrestore(&state->uart_port->lock, flags); | 603 | uart_port_unlock(port, flags); |
566 | return ret; | 604 | return ret; |
567 | } | 605 | } |
568 | 606 | ||
569 | static int uart_chars_in_buffer(struct tty_struct *tty) | 607 | static int uart_chars_in_buffer(struct tty_struct *tty) |
570 | { | 608 | { |
571 | struct uart_state *state = tty->driver_data; | 609 | struct uart_state *state = tty->driver_data; |
610 | struct uart_port *port; | ||
572 | unsigned long flags; | 611 | unsigned long flags; |
573 | int ret; | 612 | int ret; |
574 | 613 | ||
575 | spin_lock_irqsave(&state->uart_port->lock, flags); | 614 | port = uart_port_lock(state, flags); |
576 | ret = uart_circ_chars_pending(&state->xmit); | 615 | ret = uart_circ_chars_pending(&state->xmit); |
577 | spin_unlock_irqrestore(&state->uart_port->lock, flags); | 616 | uart_port_unlock(port, flags); |
578 | return ret; | 617 | return ret; |
579 | } | 618 | } |
580 | 619 | ||
@@ -593,14 +632,15 @@ static void uart_flush_buffer(struct tty_struct *tty) | |||
593 | return; | 632 | return; |
594 | } | 633 | } |
595 | 634 | ||
596 | port = state->uart_port; | ||
597 | pr_debug("uart_flush_buffer(%d) called\n", tty->index); | 635 | pr_debug("uart_flush_buffer(%d) called\n", tty->index); |
598 | 636 | ||
599 | spin_lock_irqsave(&port->lock, flags); | 637 | port = uart_port_lock(state, flags); |
638 | if (!port) | ||
639 | return; | ||
600 | uart_circ_clear(&state->xmit); | 640 | uart_circ_clear(&state->xmit); |
601 | if (port->ops->flush_buffer) | 641 | if (port->ops->flush_buffer) |
602 | port->ops->flush_buffer(port); | 642 | port->ops->flush_buffer(port); |
603 | spin_unlock_irqrestore(&port->lock, flags); | 643 | uart_port_unlock(port, flags); |
604 | tty_wakeup(tty); | 644 | tty_wakeup(tty); |
605 | } | 645 | } |
606 | 646 | ||
@@ -611,9 +651,13 @@ static void uart_flush_buffer(struct tty_struct *tty) | |||
611 | static void uart_send_xchar(struct tty_struct *tty, char ch) | 651 | static void uart_send_xchar(struct tty_struct *tty, char ch) |
612 | { | 652 | { |
613 | struct uart_state *state = tty->driver_data; | 653 | struct uart_state *state = tty->driver_data; |
614 | struct uart_port *port = state->uart_port; | 654 | struct uart_port *port; |
615 | unsigned long flags; | 655 | unsigned long flags; |
616 | 656 | ||
657 | port = uart_port_ref(state); | ||
658 | if (!port) | ||
659 | return; | ||
660 | |||
617 | if (port->ops->send_xchar) | 661 | if (port->ops->send_xchar) |
618 | port->ops->send_xchar(port, ch); | 662 | port->ops->send_xchar(port, ch); |
619 | else { | 663 | else { |
@@ -623,14 +667,19 @@ static void uart_send_xchar(struct tty_struct *tty, char ch) | |||
623 | port->ops->start_tx(port); | 667 | port->ops->start_tx(port); |
624 | spin_unlock_irqrestore(&port->lock, flags); | 668 | spin_unlock_irqrestore(&port->lock, flags); |
625 | } | 669 | } |
670 | uart_port_deref(port); | ||
626 | } | 671 | } |
627 | 672 | ||
628 | static void uart_throttle(struct tty_struct *tty) | 673 | static void uart_throttle(struct tty_struct *tty) |
629 | { | 674 | { |
630 | struct uart_state *state = tty->driver_data; | 675 | struct uart_state *state = tty->driver_data; |
631 | struct uart_port *port = state->uart_port; | 676 | struct uart_port *port; |
632 | upstat_t mask = 0; | 677 | upstat_t mask = 0; |
633 | 678 | ||
679 | port = uart_port_ref(state); | ||
680 | if (!port) | ||
681 | return; | ||
682 | |||
634 | if (I_IXOFF(tty)) | 683 | if (I_IXOFF(tty)) |
635 | mask |= UPSTAT_AUTOXOFF; | 684 | mask |= UPSTAT_AUTOXOFF; |
636 | if (C_CRTSCTS(tty)) | 685 | if (C_CRTSCTS(tty)) |
@@ -646,14 +695,20 @@ static void uart_throttle(struct tty_struct *tty) | |||
646 | 695 | ||
647 | if (mask & UPSTAT_AUTOXOFF) | 696 | if (mask & UPSTAT_AUTOXOFF) |
648 | uart_send_xchar(tty, STOP_CHAR(tty)); | 697 | uart_send_xchar(tty, STOP_CHAR(tty)); |
698 | |||
699 | uart_port_deref(port); | ||
649 | } | 700 | } |
650 | 701 | ||
651 | static void uart_unthrottle(struct tty_struct *tty) | 702 | static void uart_unthrottle(struct tty_struct *tty) |
652 | { | 703 | { |
653 | struct uart_state *state = tty->driver_data; | 704 | struct uart_state *state = tty->driver_data; |
654 | struct uart_port *port = state->uart_port; | 705 | struct uart_port *port; |
655 | upstat_t mask = 0; | 706 | upstat_t mask = 0; |
656 | 707 | ||
708 | port = uart_port_ref(state); | ||
709 | if (!port) | ||
710 | return; | ||
711 | |||
657 | if (I_IXOFF(tty)) | 712 | if (I_IXOFF(tty)) |
658 | mask |= UPSTAT_AUTOXOFF; | 713 | mask |= UPSTAT_AUTOXOFF; |
659 | if (C_CRTSCTS(tty)) | 714 | if (C_CRTSCTS(tty)) |
@@ -669,12 +724,15 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
669 | 724 | ||
670 | if (mask & UPSTAT_AUTOXOFF) | 725 | if (mask & UPSTAT_AUTOXOFF) |
671 | uart_send_xchar(tty, START_CHAR(tty)); | 726 | uart_send_xchar(tty, START_CHAR(tty)); |
727 | |||
728 | uart_port_deref(port); | ||
672 | } | 729 | } |
673 | 730 | ||
674 | static void uart_get_info(struct tty_port *port, struct serial_struct *retinfo) | 731 | static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo) |
675 | { | 732 | { |
676 | struct uart_state *state = container_of(port, struct uart_state, port); | 733 | struct uart_state *state = container_of(port, struct uart_state, port); |
677 | struct uart_port *uport = state->uart_port; | 734 | struct uart_port *uport; |
735 | int ret = -ENODEV; | ||
678 | 736 | ||
679 | memset(retinfo, 0, sizeof(*retinfo)); | 737 | memset(retinfo, 0, sizeof(*retinfo)); |
680 | 738 | ||
@@ -683,6 +741,10 @@ static void uart_get_info(struct tty_port *port, struct serial_struct *retinfo) | |||
683 | * occur as we go | 741 | * occur as we go |
684 | */ | 742 | */ |
685 | mutex_lock(&port->mutex); | 743 | mutex_lock(&port->mutex); |
744 | uport = uart_port_check(state); | ||
745 | if (!uport) | ||
746 | goto out; | ||
747 | |||
686 | retinfo->type = uport->type; | 748 | retinfo->type = uport->type; |
687 | retinfo->line = uport->line; | 749 | retinfo->line = uport->line; |
688 | retinfo->port = uport->iobase; | 750 | retinfo->port = uport->iobase; |
@@ -701,7 +763,11 @@ static void uart_get_info(struct tty_port *port, struct serial_struct *retinfo) | |||
701 | retinfo->io_type = uport->iotype; | 763 | retinfo->io_type = uport->iotype; |
702 | retinfo->iomem_reg_shift = uport->regshift; | 764 | retinfo->iomem_reg_shift = uport->regshift; |
703 | retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; | 765 | retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; |
766 | |||
767 | ret = 0; | ||
768 | out: | ||
704 | mutex_unlock(&port->mutex); | 769 | mutex_unlock(&port->mutex); |
770 | return ret; | ||
705 | } | 771 | } |
706 | 772 | ||
707 | static int uart_get_info_user(struct tty_port *port, | 773 | static int uart_get_info_user(struct tty_port *port, |
@@ -709,7 +775,8 @@ static int uart_get_info_user(struct tty_port *port, | |||
709 | { | 775 | { |
710 | struct serial_struct tmp; | 776 | struct serial_struct tmp; |
711 | 777 | ||
712 | uart_get_info(port, &tmp); | 778 | if (uart_get_info(port, &tmp) < 0) |
779 | return -EIO; | ||
713 | 780 | ||
714 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 781 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
715 | return -EFAULT; | 782 | return -EFAULT; |
@@ -720,13 +787,16 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
720 | struct uart_state *state, | 787 | struct uart_state *state, |
721 | struct serial_struct *new_info) | 788 | struct serial_struct *new_info) |
722 | { | 789 | { |
723 | struct uart_port *uport = state->uart_port; | 790 | struct uart_port *uport = uart_port_check(state); |
724 | unsigned long new_port; | 791 | unsigned long new_port; |
725 | unsigned int change_irq, change_port, closing_wait; | 792 | unsigned int change_irq, change_port, closing_wait; |
726 | unsigned int old_custom_divisor, close_delay; | 793 | unsigned int old_custom_divisor, close_delay; |
727 | upf_t old_flags, new_flags; | 794 | upf_t old_flags, new_flags; |
728 | int retval = 0; | 795 | int retval = 0; |
729 | 796 | ||
797 | if (!uport) | ||
798 | return -EIO; | ||
799 | |||
730 | new_port = new_info->port; | 800 | new_port = new_info->port; |
731 | if (HIGH_BITS_OFFSET) | 801 | if (HIGH_BITS_OFFSET) |
732 | new_port += (unsigned long) new_info->port_high << HIGH_BITS_OFFSET; | 802 | new_port += (unsigned long) new_info->port_high << HIGH_BITS_OFFSET; |
@@ -886,7 +956,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
886 | retval = 0; | 956 | retval = 0; |
887 | if (uport->type == PORT_UNKNOWN) | 957 | if (uport->type == PORT_UNKNOWN) |
888 | goto exit; | 958 | goto exit; |
889 | if (port->flags & ASYNC_INITIALIZED) { | 959 | if (tty_port_initialized(port)) { |
890 | if (((old_flags ^ uport->flags) & UPF_SPD_MASK) || | 960 | if (((old_flags ^ uport->flags) & UPF_SPD_MASK) || |
891 | old_custom_divisor != uport->custom_divisor) { | 961 | old_custom_divisor != uport->custom_divisor) { |
892 | /* | 962 | /* |
@@ -936,13 +1006,11 @@ static int uart_set_info_user(struct tty_struct *tty, struct uart_state *state, | |||
936 | * @tty: tty associated with the UART | 1006 | * @tty: tty associated with the UART |
937 | * @state: UART being queried | 1007 | * @state: UART being queried |
938 | * @value: returned modem value | 1008 | * @value: returned modem value |
939 | * | ||
940 | * Note: uart_ioctl protects us against hangups. | ||
941 | */ | 1009 | */ |
942 | static int uart_get_lsr_info(struct tty_struct *tty, | 1010 | static int uart_get_lsr_info(struct tty_struct *tty, |
943 | struct uart_state *state, unsigned int __user *value) | 1011 | struct uart_state *state, unsigned int __user *value) |
944 | { | 1012 | { |
945 | struct uart_port *uport = state->uart_port; | 1013 | struct uart_port *uport = uart_port_check(state); |
946 | unsigned int result; | 1014 | unsigned int result; |
947 | 1015 | ||
948 | result = uport->ops->tx_empty(uport); | 1016 | result = uport->ops->tx_empty(uport); |
@@ -965,18 +1033,22 @@ static int uart_tiocmget(struct tty_struct *tty) | |||
965 | { | 1033 | { |
966 | struct uart_state *state = tty->driver_data; | 1034 | struct uart_state *state = tty->driver_data; |
967 | struct tty_port *port = &state->port; | 1035 | struct tty_port *port = &state->port; |
968 | struct uart_port *uport = state->uart_port; | 1036 | struct uart_port *uport; |
969 | int result = -EIO; | 1037 | int result = -EIO; |
970 | 1038 | ||
971 | mutex_lock(&port->mutex); | 1039 | mutex_lock(&port->mutex); |
972 | if (!(tty->flags & (1 << TTY_IO_ERROR))) { | 1040 | uport = uart_port_check(state); |
1041 | if (!uport) | ||
1042 | goto out; | ||
1043 | |||
1044 | if (!tty_io_error(tty)) { | ||
973 | result = uport->mctrl; | 1045 | result = uport->mctrl; |
974 | spin_lock_irq(&uport->lock); | 1046 | spin_lock_irq(&uport->lock); |
975 | result |= uport->ops->get_mctrl(uport); | 1047 | result |= uport->ops->get_mctrl(uport); |
976 | spin_unlock_irq(&uport->lock); | 1048 | spin_unlock_irq(&uport->lock); |
977 | } | 1049 | } |
1050 | out: | ||
978 | mutex_unlock(&port->mutex); | 1051 | mutex_unlock(&port->mutex); |
979 | |||
980 | return result; | 1052 | return result; |
981 | } | 1053 | } |
982 | 1054 | ||
@@ -984,15 +1056,20 @@ static int | |||
984 | uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) | 1056 | uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) |
985 | { | 1057 | { |
986 | struct uart_state *state = tty->driver_data; | 1058 | struct uart_state *state = tty->driver_data; |
987 | struct uart_port *uport = state->uart_port; | ||
988 | struct tty_port *port = &state->port; | 1059 | struct tty_port *port = &state->port; |
1060 | struct uart_port *uport; | ||
989 | int ret = -EIO; | 1061 | int ret = -EIO; |
990 | 1062 | ||
991 | mutex_lock(&port->mutex); | 1063 | mutex_lock(&port->mutex); |
992 | if (!(tty->flags & (1 << TTY_IO_ERROR))) { | 1064 | uport = uart_port_check(state); |
1065 | if (!uport) | ||
1066 | goto out; | ||
1067 | |||
1068 | if (!tty_io_error(tty)) { | ||
993 | uart_update_mctrl(uport, set, clear); | 1069 | uart_update_mctrl(uport, set, clear); |
994 | ret = 0; | 1070 | ret = 0; |
995 | } | 1071 | } |
1072 | out: | ||
996 | mutex_unlock(&port->mutex); | 1073 | mutex_unlock(&port->mutex); |
997 | return ret; | 1074 | return ret; |
998 | } | 1075 | } |
@@ -1001,21 +1078,26 @@ static int uart_break_ctl(struct tty_struct *tty, int break_state) | |||
1001 | { | 1078 | { |
1002 | struct uart_state *state = tty->driver_data; | 1079 | struct uart_state *state = tty->driver_data; |
1003 | struct tty_port *port = &state->port; | 1080 | struct tty_port *port = &state->port; |
1004 | struct uart_port *uport = state->uart_port; | 1081 | struct uart_port *uport; |
1082 | int ret = -EIO; | ||
1005 | 1083 | ||
1006 | mutex_lock(&port->mutex); | 1084 | mutex_lock(&port->mutex); |
1085 | uport = uart_port_check(state); | ||
1086 | if (!uport) | ||
1087 | goto out; | ||
1007 | 1088 | ||
1008 | if (uport->type != PORT_UNKNOWN) | 1089 | if (uport->type != PORT_UNKNOWN) |
1009 | uport->ops->break_ctl(uport, break_state); | 1090 | uport->ops->break_ctl(uport, break_state); |
1010 | 1091 | ret = 0; | |
1092 | out: | ||
1011 | mutex_unlock(&port->mutex); | 1093 | mutex_unlock(&port->mutex); |
1012 | return 0; | 1094 | return ret; |
1013 | } | 1095 | } |
1014 | 1096 | ||
1015 | static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) | 1097 | static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) |
1016 | { | 1098 | { |
1017 | struct uart_port *uport = state->uart_port; | ||
1018 | struct tty_port *port = &state->port; | 1099 | struct tty_port *port = &state->port; |
1100 | struct uart_port *uport; | ||
1019 | int flags, ret; | 1101 | int flags, ret; |
1020 | 1102 | ||
1021 | if (!capable(CAP_SYS_ADMIN)) | 1103 | if (!capable(CAP_SYS_ADMIN)) |
@@ -1029,6 +1111,12 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) | |||
1029 | if (mutex_lock_interruptible(&port->mutex)) | 1111 | if (mutex_lock_interruptible(&port->mutex)) |
1030 | return -ERESTARTSYS; | 1112 | return -ERESTARTSYS; |
1031 | 1113 | ||
1114 | uport = uart_port_check(state); | ||
1115 | if (!uport) { | ||
1116 | ret = -EIO; | ||
1117 | goto out; | ||
1118 | } | ||
1119 | |||
1032 | ret = -EBUSY; | 1120 | ret = -EBUSY; |
1033 | if (tty_port_users(port) == 1) { | 1121 | if (tty_port_users(port) == 1) { |
1034 | uart_shutdown(tty, state); | 1122 | uart_shutdown(tty, state); |
@@ -1052,6 +1140,7 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) | |||
1052 | 1140 | ||
1053 | ret = uart_startup(tty, state, 1); | 1141 | ret = uart_startup(tty, state, 1); |
1054 | } | 1142 | } |
1143 | out: | ||
1055 | mutex_unlock(&port->mutex); | 1144 | mutex_unlock(&port->mutex); |
1056 | return ret; | 1145 | return ret; |
1057 | } | 1146 | } |
@@ -1074,10 +1163,9 @@ static void uart_enable_ms(struct uart_port *uport) | |||
1074 | * FIXME: This wants extracting into a common all driver implementation | 1163 | * FIXME: This wants extracting into a common all driver implementation |
1075 | * of TIOCMWAIT using tty_port. | 1164 | * of TIOCMWAIT using tty_port. |
1076 | */ | 1165 | */ |
1077 | static int | 1166 | static int uart_wait_modem_status(struct uart_state *state, unsigned long arg) |
1078 | uart_wait_modem_status(struct uart_state *state, unsigned long arg) | ||
1079 | { | 1167 | { |
1080 | struct uart_port *uport = state->uart_port; | 1168 | struct uart_port *uport; |
1081 | struct tty_port *port = &state->port; | 1169 | struct tty_port *port = &state->port; |
1082 | DECLARE_WAITQUEUE(wait, current); | 1170 | DECLARE_WAITQUEUE(wait, current); |
1083 | struct uart_icount cprev, cnow; | 1171 | struct uart_icount cprev, cnow; |
@@ -1086,6 +1174,9 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg) | |||
1086 | /* | 1174 | /* |
1087 | * note the counters on entry | 1175 | * note the counters on entry |
1088 | */ | 1176 | */ |
1177 | uport = uart_port_ref(state); | ||
1178 | if (!uport) | ||
1179 | return -EIO; | ||
1089 | spin_lock_irq(&uport->lock); | 1180 | spin_lock_irq(&uport->lock); |
1090 | memcpy(&cprev, &uport->icount, sizeof(struct uart_icount)); | 1181 | memcpy(&cprev, &uport->icount, sizeof(struct uart_icount)); |
1091 | uart_enable_ms(uport); | 1182 | uart_enable_ms(uport); |
@@ -1119,6 +1210,7 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg) | |||
1119 | } | 1210 | } |
1120 | __set_current_state(TASK_RUNNING); | 1211 | __set_current_state(TASK_RUNNING); |
1121 | remove_wait_queue(&port->delta_msr_wait, &wait); | 1212 | remove_wait_queue(&port->delta_msr_wait, &wait); |
1213 | uart_port_deref(uport); | ||
1122 | 1214 | ||
1123 | return ret; | 1215 | return ret; |
1124 | } | 1216 | } |
@@ -1134,11 +1226,15 @@ static int uart_get_icount(struct tty_struct *tty, | |||
1134 | { | 1226 | { |
1135 | struct uart_state *state = tty->driver_data; | 1227 | struct uart_state *state = tty->driver_data; |
1136 | struct uart_icount cnow; | 1228 | struct uart_icount cnow; |
1137 | struct uart_port *uport = state->uart_port; | 1229 | struct uart_port *uport; |
1138 | 1230 | ||
1231 | uport = uart_port_ref(state); | ||
1232 | if (!uport) | ||
1233 | return -EIO; | ||
1139 | spin_lock_irq(&uport->lock); | 1234 | spin_lock_irq(&uport->lock); |
1140 | memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); | 1235 | memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); |
1141 | spin_unlock_irq(&uport->lock); | 1236 | spin_unlock_irq(&uport->lock); |
1237 | uart_port_deref(uport); | ||
1142 | 1238 | ||
1143 | icount->cts = cnow.cts; | 1239 | icount->cts = cnow.cts; |
1144 | icount->dsr = cnow.dsr; | 1240 | icount->dsr = cnow.dsr; |
@@ -1200,11 +1296,11 @@ static int uart_set_rs485_config(struct uart_port *port, | |||
1200 | * Called via sys_ioctl. We can use spin_lock_irq() here. | 1296 | * Called via sys_ioctl. We can use spin_lock_irq() here. |
1201 | */ | 1297 | */ |
1202 | static int | 1298 | static int |
1203 | uart_ioctl(struct tty_struct *tty, unsigned int cmd, | 1299 | uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) |
1204 | unsigned long arg) | ||
1205 | { | 1300 | { |
1206 | struct uart_state *state = tty->driver_data; | 1301 | struct uart_state *state = tty->driver_data; |
1207 | struct tty_port *port = &state->port; | 1302 | struct tty_port *port = &state->port; |
1303 | struct uart_port *uport; | ||
1208 | void __user *uarg = (void __user *)arg; | 1304 | void __user *uarg = (void __user *)arg; |
1209 | int ret = -ENOIOCTLCMD; | 1305 | int ret = -ENOIOCTLCMD; |
1210 | 1306 | ||
@@ -1238,7 +1334,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
1238 | if (ret != -ENOIOCTLCMD) | 1334 | if (ret != -ENOIOCTLCMD) |
1239 | goto out; | 1335 | goto out; |
1240 | 1336 | ||
1241 | if (tty->flags & (1 << TTY_IO_ERROR)) { | 1337 | if (tty_io_error(tty)) { |
1242 | ret = -EIO; | 1338 | ret = -EIO; |
1243 | goto out; | 1339 | goto out; |
1244 | } | 1340 | } |
@@ -1256,8 +1352,9 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
1256 | goto out; | 1352 | goto out; |
1257 | 1353 | ||
1258 | mutex_lock(&port->mutex); | 1354 | mutex_lock(&port->mutex); |
1355 | uport = uart_port_check(state); | ||
1259 | 1356 | ||
1260 | if (tty->flags & (1 << TTY_IO_ERROR)) { | 1357 | if (!uport || tty_io_error(tty)) { |
1261 | ret = -EIO; | 1358 | ret = -EIO; |
1262 | goto out_up; | 1359 | goto out_up; |
1263 | } | 1360 | } |
@@ -1273,19 +1370,17 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
1273 | break; | 1370 | break; |
1274 | 1371 | ||
1275 | case TIOCGRS485: | 1372 | case TIOCGRS485: |
1276 | ret = uart_get_rs485_config(state->uart_port, uarg); | 1373 | ret = uart_get_rs485_config(uport, uarg); |
1277 | break; | 1374 | break; |
1278 | 1375 | ||
1279 | case TIOCSRS485: | 1376 | case TIOCSRS485: |
1280 | ret = uart_set_rs485_config(state->uart_port, uarg); | 1377 | ret = uart_set_rs485_config(uport, uarg); |
1281 | break; | 1378 | break; |
1282 | default: { | 1379 | default: |
1283 | struct uart_port *uport = state->uart_port; | ||
1284 | if (uport->ops->ioctl) | 1380 | if (uport->ops->ioctl) |
1285 | ret = uport->ops->ioctl(uport, cmd, arg); | 1381 | ret = uport->ops->ioctl(uport, cmd, arg); |
1286 | break; | 1382 | break; |
1287 | } | 1383 | } |
1288 | } | ||
1289 | out_up: | 1384 | out_up: |
1290 | mutex_unlock(&port->mutex); | 1385 | mutex_unlock(&port->mutex); |
1291 | out: | 1386 | out: |
@@ -1295,24 +1390,29 @@ out: | |||
1295 | static void uart_set_ldisc(struct tty_struct *tty) | 1390 | static void uart_set_ldisc(struct tty_struct *tty) |
1296 | { | 1391 | { |
1297 | struct uart_state *state = tty->driver_data; | 1392 | struct uart_state *state = tty->driver_data; |
1298 | struct uart_port *uport = state->uart_port; | 1393 | struct uart_port *uport; |
1299 | 1394 | ||
1300 | if (uport->ops->set_ldisc) { | 1395 | mutex_lock(&state->port.mutex); |
1301 | mutex_lock(&state->port.mutex); | 1396 | uport = uart_port_check(state); |
1397 | if (uport && uport->ops->set_ldisc) | ||
1302 | uport->ops->set_ldisc(uport, &tty->termios); | 1398 | uport->ops->set_ldisc(uport, &tty->termios); |
1303 | mutex_unlock(&state->port.mutex); | 1399 | mutex_unlock(&state->port.mutex); |
1304 | } | ||
1305 | } | 1400 | } |
1306 | 1401 | ||
1307 | static void uart_set_termios(struct tty_struct *tty, | 1402 | static void uart_set_termios(struct tty_struct *tty, |
1308 | struct ktermios *old_termios) | 1403 | struct ktermios *old_termios) |
1309 | { | 1404 | { |
1310 | struct uart_state *state = tty->driver_data; | 1405 | struct uart_state *state = tty->driver_data; |
1311 | struct uart_port *uport = state->uart_port; | 1406 | struct uart_port *uport; |
1312 | unsigned int cflag = tty->termios.c_cflag; | 1407 | unsigned int cflag = tty->termios.c_cflag; |
1313 | unsigned int iflag_mask = IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK; | 1408 | unsigned int iflag_mask = IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK; |
1314 | bool sw_changed = false; | 1409 | bool sw_changed = false; |
1315 | 1410 | ||
1411 | mutex_lock(&state->port.mutex); | ||
1412 | uport = uart_port_check(state); | ||
1413 | if (!uport) | ||
1414 | goto out; | ||
1415 | |||
1316 | /* | 1416 | /* |
1317 | * Drivers doing software flow control also need to know | 1417 | * Drivers doing software flow control also need to know |
1318 | * about changes to these input settings. | 1418 | * about changes to these input settings. |
@@ -1335,12 +1435,10 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1335 | tty->termios.c_ispeed == old_termios->c_ispeed && | 1435 | tty->termios.c_ispeed == old_termios->c_ispeed && |
1336 | ((tty->termios.c_iflag ^ old_termios->c_iflag) & iflag_mask) == 0 && | 1436 | ((tty->termios.c_iflag ^ old_termios->c_iflag) & iflag_mask) == 0 && |
1337 | !sw_changed) { | 1437 | !sw_changed) { |
1338 | return; | 1438 | goto out; |
1339 | } | 1439 | } |
1340 | 1440 | ||
1341 | mutex_lock(&state->port.mutex); | ||
1342 | uart_change_speed(tty, state, old_termios); | 1441 | uart_change_speed(tty, state, old_termios); |
1343 | mutex_unlock(&state->port.mutex); | ||
1344 | /* reload cflag from termios; port driver may have overriden flags */ | 1442 | /* reload cflag from termios; port driver may have overriden flags */ |
1345 | cflag = tty->termios.c_cflag; | 1443 | cflag = tty->termios.c_cflag; |
1346 | 1444 | ||
@@ -1350,17 +1448,18 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1350 | /* Handle transition away from B0 status */ | 1448 | /* Handle transition away from B0 status */ |
1351 | else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { | 1449 | else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
1352 | unsigned int mask = TIOCM_DTR; | 1450 | unsigned int mask = TIOCM_DTR; |
1353 | if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) | 1451 | if (!(cflag & CRTSCTS) || !tty_throttled(tty)) |
1354 | mask |= TIOCM_RTS; | 1452 | mask |= TIOCM_RTS; |
1355 | uart_set_mctrl(uport, mask); | 1453 | uart_set_mctrl(uport, mask); |
1356 | } | 1454 | } |
1455 | out: | ||
1456 | mutex_unlock(&state->port.mutex); | ||
1357 | } | 1457 | } |
1358 | 1458 | ||
1359 | /* | 1459 | /* |
1360 | * Calls to uart_close() are serialised via the tty_lock in | 1460 | * Calls to uart_close() are serialised via the tty_lock in |
1361 | * drivers/tty/tty_io.c:tty_release() | 1461 | * drivers/tty/tty_io.c:tty_release() |
1362 | * drivers/tty/tty_io.c:do_tty_hangup() | 1462 | * drivers/tty/tty_io.c:do_tty_hangup() |
1363 | * This runs from a workqueue and can sleep for a _short_ time only. | ||
1364 | */ | 1463 | */ |
1365 | static void uart_close(struct tty_struct *tty, struct file *filp) | 1464 | static void uart_close(struct tty_struct *tty, struct file *filp) |
1366 | { | 1465 | { |
@@ -1379,18 +1478,21 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1379 | return; | 1478 | return; |
1380 | } | 1479 | } |
1381 | 1480 | ||
1382 | uport = state->uart_port; | ||
1383 | port = &state->port; | 1481 | port = &state->port; |
1384 | pr_debug("uart_close(%d) called\n", tty->index); | 1482 | pr_debug("uart_close(%d) called\n", tty->index); |
1385 | 1483 | ||
1386 | if (!port->count || tty_port_close_start(port, tty, filp) == 0) | 1484 | if (tty_port_close_start(port, tty, filp) == 0) |
1387 | return; | 1485 | return; |
1388 | 1486 | ||
1487 | mutex_lock(&port->mutex); | ||
1488 | uport = uart_port_check(state); | ||
1489 | |||
1389 | /* | 1490 | /* |
1390 | * At this point, we stop accepting input. To do this, we | 1491 | * At this point, we stop accepting input. To do this, we |
1391 | * disable the receive line status interrupts. | 1492 | * disable the receive line status interrupts. |
1392 | */ | 1493 | */ |
1393 | if (port->flags & ASYNC_INITIALIZED) { | 1494 | if (tty_port_initialized(port) && |
1495 | !WARN(!uport, "detached port still initialized!\n")) { | ||
1394 | spin_lock_irq(&uport->lock); | 1496 | spin_lock_irq(&uport->lock); |
1395 | uport->ops->stop_rx(uport); | 1497 | uport->ops->stop_rx(uport); |
1396 | spin_unlock_irq(&uport->lock); | 1498 | spin_unlock_irq(&uport->lock); |
@@ -1402,7 +1504,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1402 | uart_wait_until_sent(tty, uport->timeout); | 1504 | uart_wait_until_sent(tty, uport->timeout); |
1403 | } | 1505 | } |
1404 | 1506 | ||
1405 | mutex_lock(&port->mutex); | ||
1406 | uart_shutdown(tty, state); | 1507 | uart_shutdown(tty, state); |
1407 | tty_port_tty_set(port, NULL); | 1508 | tty_port_tty_set(port, NULL); |
1408 | 1509 | ||
@@ -1413,17 +1514,17 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1413 | if (port->close_delay) | 1514 | if (port->close_delay) |
1414 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); | 1515 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); |
1415 | spin_lock_irq(&port->lock); | 1516 | spin_lock_irq(&port->lock); |
1416 | } else if (!uart_console(uport)) { | 1517 | } else if (uport && !uart_console(uport)) { |
1417 | spin_unlock_irq(&port->lock); | 1518 | spin_unlock_irq(&port->lock); |
1418 | uart_change_pm(state, UART_PM_STATE_OFF); | 1519 | uart_change_pm(state, UART_PM_STATE_OFF); |
1419 | spin_lock_irq(&port->lock); | 1520 | spin_lock_irq(&port->lock); |
1420 | } | 1521 | } |
1522 | spin_unlock_irq(&port->lock); | ||
1523 | tty_port_set_active(port, 0); | ||
1421 | 1524 | ||
1422 | /* | 1525 | /* |
1423 | * Wake up anyone trying to open this port. | 1526 | * Wake up anyone trying to open this port. |
1424 | */ | 1527 | */ |
1425 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); | ||
1426 | spin_unlock_irq(&port->lock); | ||
1427 | wake_up_interruptible(&port->open_wait); | 1528 | wake_up_interruptible(&port->open_wait); |
1428 | 1529 | ||
1429 | mutex_unlock(&port->mutex); | 1530 | mutex_unlock(&port->mutex); |
@@ -1435,11 +1536,14 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1435 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | 1536 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) |
1436 | { | 1537 | { |
1437 | struct uart_state *state = tty->driver_data; | 1538 | struct uart_state *state = tty->driver_data; |
1438 | struct uart_port *port = state->uart_port; | 1539 | struct uart_port *port; |
1439 | unsigned long char_time, expire; | 1540 | unsigned long char_time, expire; |
1440 | 1541 | ||
1441 | if (port->type == PORT_UNKNOWN || port->fifosize == 0) | 1542 | port = uart_port_ref(state); |
1543 | if (!port || port->type == PORT_UNKNOWN || port->fifosize == 0) { | ||
1544 | uart_port_deref(port); | ||
1442 | return; | 1545 | return; |
1546 | } | ||
1443 | 1547 | ||
1444 | /* | 1548 | /* |
1445 | * Set the check interval to be 1/5 of the estimated time to | 1549 | * Set the check interval to be 1/5 of the estimated time to |
@@ -1485,6 +1589,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1485 | if (time_after(jiffies, expire)) | 1589 | if (time_after(jiffies, expire)) |
1486 | break; | 1590 | break; |
1487 | } | 1591 | } |
1592 | uart_port_deref(port); | ||
1488 | } | 1593 | } |
1489 | 1594 | ||
1490 | /* | 1595 | /* |
@@ -1496,20 +1601,24 @@ static void uart_hangup(struct tty_struct *tty) | |||
1496 | { | 1601 | { |
1497 | struct uart_state *state = tty->driver_data; | 1602 | struct uart_state *state = tty->driver_data; |
1498 | struct tty_port *port = &state->port; | 1603 | struct tty_port *port = &state->port; |
1604 | struct uart_port *uport; | ||
1499 | unsigned long flags; | 1605 | unsigned long flags; |
1500 | 1606 | ||
1501 | pr_debug("uart_hangup(%d)\n", tty->index); | 1607 | pr_debug("uart_hangup(%d)\n", tty->index); |
1502 | 1608 | ||
1503 | mutex_lock(&port->mutex); | 1609 | mutex_lock(&port->mutex); |
1504 | if (port->flags & ASYNC_NORMAL_ACTIVE) { | 1610 | uport = uart_port_check(state); |
1611 | WARN(!uport, "hangup of detached port!\n"); | ||
1612 | |||
1613 | if (tty_port_active(port)) { | ||
1505 | uart_flush_buffer(tty); | 1614 | uart_flush_buffer(tty); |
1506 | uart_shutdown(tty, state); | 1615 | uart_shutdown(tty, state); |
1507 | spin_lock_irqsave(&port->lock, flags); | 1616 | spin_lock_irqsave(&port->lock, flags); |
1508 | port->count = 0; | 1617 | port->count = 0; |
1509 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); | ||
1510 | spin_unlock_irqrestore(&port->lock, flags); | 1618 | spin_unlock_irqrestore(&port->lock, flags); |
1619 | tty_port_set_active(port, 0); | ||
1511 | tty_port_tty_set(port, NULL); | 1620 | tty_port_tty_set(port, NULL); |
1512 | if (!uart_console(state->uart_port)) | 1621 | if (uport && !uart_console(uport)) |
1513 | uart_change_pm(state, UART_PM_STATE_OFF); | 1622 | uart_change_pm(state, UART_PM_STATE_OFF); |
1514 | wake_up_interruptible(&port->open_wait); | 1623 | wake_up_interruptible(&port->open_wait); |
1515 | wake_up_interruptible(&port->delta_msr_wait); | 1624 | wake_up_interruptible(&port->delta_msr_wait); |
@@ -1517,10 +1626,11 @@ static void uart_hangup(struct tty_struct *tty) | |||
1517 | mutex_unlock(&port->mutex); | 1626 | mutex_unlock(&port->mutex); |
1518 | } | 1627 | } |
1519 | 1628 | ||
1629 | /* uport == NULL if uart_port has already been removed */ | ||
1520 | static void uart_port_shutdown(struct tty_port *port) | 1630 | static void uart_port_shutdown(struct tty_port *port) |
1521 | { | 1631 | { |
1522 | struct uart_state *state = container_of(port, struct uart_state, port); | 1632 | struct uart_state *state = container_of(port, struct uart_state, port); |
1523 | struct uart_port *uport = state->uart_port; | 1633 | struct uart_port *uport = uart_port_check(state); |
1524 | 1634 | ||
1525 | /* | 1635 | /* |
1526 | * clear delta_msr_wait queue to avoid mem leaks: we may free | 1636 | * clear delta_msr_wait queue to avoid mem leaks: we may free |
@@ -1534,23 +1644,36 @@ static void uart_port_shutdown(struct tty_port *port) | |||
1534 | /* | 1644 | /* |
1535 | * Free the IRQ and disable the port. | 1645 | * Free the IRQ and disable the port. |
1536 | */ | 1646 | */ |
1537 | uport->ops->shutdown(uport); | 1647 | if (uport) |
1648 | uport->ops->shutdown(uport); | ||
1538 | 1649 | ||
1539 | /* | 1650 | /* |
1540 | * Ensure that the IRQ handler isn't running on another CPU. | 1651 | * Ensure that the IRQ handler isn't running on another CPU. |
1541 | */ | 1652 | */ |
1542 | synchronize_irq(uport->irq); | 1653 | if (uport) |
1654 | synchronize_irq(uport->irq); | ||
1543 | } | 1655 | } |
1544 | 1656 | ||
1545 | static int uart_carrier_raised(struct tty_port *port) | 1657 | static int uart_carrier_raised(struct tty_port *port) |
1546 | { | 1658 | { |
1547 | struct uart_state *state = container_of(port, struct uart_state, port); | 1659 | struct uart_state *state = container_of(port, struct uart_state, port); |
1548 | struct uart_port *uport = state->uart_port; | 1660 | struct uart_port *uport; |
1549 | int mctrl; | 1661 | int mctrl; |
1662 | |||
1663 | uport = uart_port_ref(state); | ||
1664 | /* | ||
1665 | * Should never observe uport == NULL since checks for hangup should | ||
1666 | * abort the tty_port_block_til_ready() loop before checking for carrier | ||
1667 | * raised -- but report carrier raised if it does anyway so open will | ||
1668 | * continue and not sleep | ||
1669 | */ | ||
1670 | if (WARN_ON(!uport)) | ||
1671 | return 1; | ||
1550 | spin_lock_irq(&uport->lock); | 1672 | spin_lock_irq(&uport->lock); |
1551 | uart_enable_ms(uport); | 1673 | uart_enable_ms(uport); |
1552 | mctrl = uport->ops->get_mctrl(uport); | 1674 | mctrl = uport->ops->get_mctrl(uport); |
1553 | spin_unlock_irq(&uport->lock); | 1675 | spin_unlock_irq(&uport->lock); |
1676 | uart_port_deref(uport); | ||
1554 | if (mctrl & TIOCM_CAR) | 1677 | if (mctrl & TIOCM_CAR) |
1555 | return 1; | 1678 | return 1; |
1556 | return 0; | 1679 | return 0; |
@@ -1559,12 +1682,18 @@ static int uart_carrier_raised(struct tty_port *port) | |||
1559 | static void uart_dtr_rts(struct tty_port *port, int onoff) | 1682 | static void uart_dtr_rts(struct tty_port *port, int onoff) |
1560 | { | 1683 | { |
1561 | struct uart_state *state = container_of(port, struct uart_state, port); | 1684 | struct uart_state *state = container_of(port, struct uart_state, port); |
1562 | struct uart_port *uport = state->uart_port; | 1685 | struct uart_port *uport; |
1686 | |||
1687 | uport = uart_port_ref(state); | ||
1688 | if (!uport) | ||
1689 | return; | ||
1563 | 1690 | ||
1564 | if (onoff) | 1691 | if (onoff) |
1565 | uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 1692 | uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
1566 | else | 1693 | else |
1567 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 1694 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
1695 | |||
1696 | uart_port_deref(uport); | ||
1568 | } | 1697 | } |
1569 | 1698 | ||
1570 | /* | 1699 | /* |
@@ -1583,6 +1712,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1583 | int retval, line = tty->index; | 1712 | int retval, line = tty->index; |
1584 | struct uart_state *state = drv->state + line; | 1713 | struct uart_state *state = drv->state + line; |
1585 | struct tty_port *port = &state->port; | 1714 | struct tty_port *port = &state->port; |
1715 | struct uart_port *uport; | ||
1586 | 1716 | ||
1587 | pr_debug("uart_open(%d) called\n", line); | 1717 | pr_debug("uart_open(%d) called\n", line); |
1588 | 1718 | ||
@@ -1602,15 +1732,15 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1602 | goto end; | 1732 | goto end; |
1603 | } | 1733 | } |
1604 | 1734 | ||
1605 | if (!state->uart_port || state->uart_port->flags & UPF_DEAD) { | 1735 | uport = uart_port_check(state); |
1736 | if (!uport || uport->flags & UPF_DEAD) { | ||
1606 | retval = -ENXIO; | 1737 | retval = -ENXIO; |
1607 | goto err_unlock; | 1738 | goto err_unlock; |
1608 | } | 1739 | } |
1609 | 1740 | ||
1610 | tty->driver_data = state; | 1741 | tty->driver_data = state; |
1611 | state->uart_port->state = state; | 1742 | uport->state = state; |
1612 | state->port.low_latency = | 1743 | port->low_latency = (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; |
1613 | (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
1614 | tty_port_tty_set(port, tty); | 1744 | tty_port_tty_set(port, tty); |
1615 | 1745 | ||
1616 | /* | 1746 | /* |
@@ -1649,13 +1779,15 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1649 | struct uart_state *state = drv->state + i; | 1779 | struct uart_state *state = drv->state + i; |
1650 | struct tty_port *port = &state->port; | 1780 | struct tty_port *port = &state->port; |
1651 | enum uart_pm_state pm_state; | 1781 | enum uart_pm_state pm_state; |
1652 | struct uart_port *uport = state->uart_port; | 1782 | struct uart_port *uport; |
1653 | char stat_buf[32]; | 1783 | char stat_buf[32]; |
1654 | unsigned int status; | 1784 | unsigned int status; |
1655 | int mmio; | 1785 | int mmio; |
1656 | 1786 | ||
1787 | mutex_lock(&port->mutex); | ||
1788 | uport = uart_port_check(state); | ||
1657 | if (!uport) | 1789 | if (!uport) |
1658 | return; | 1790 | goto out; |
1659 | 1791 | ||
1660 | mmio = uport->iotype >= UPIO_MEM; | 1792 | mmio = uport->iotype >= UPIO_MEM; |
1661 | seq_printf(m, "%d: uart:%s %s%08llX irq:%d", | 1793 | seq_printf(m, "%d: uart:%s %s%08llX irq:%d", |
@@ -1667,11 +1799,10 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1667 | 1799 | ||
1668 | if (uport->type == PORT_UNKNOWN) { | 1800 | if (uport->type == PORT_UNKNOWN) { |
1669 | seq_putc(m, '\n'); | 1801 | seq_putc(m, '\n'); |
1670 | return; | 1802 | goto out; |
1671 | } | 1803 | } |
1672 | 1804 | ||
1673 | if (capable(CAP_SYS_ADMIN)) { | 1805 | if (capable(CAP_SYS_ADMIN)) { |
1674 | mutex_lock(&port->mutex); | ||
1675 | pm_state = state->pm_state; | 1806 | pm_state = state->pm_state; |
1676 | if (pm_state != UART_PM_STATE_ON) | 1807 | if (pm_state != UART_PM_STATE_ON) |
1677 | uart_change_pm(state, UART_PM_STATE_ON); | 1808 | uart_change_pm(state, UART_PM_STATE_ON); |
@@ -1680,7 +1811,6 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1680 | spin_unlock_irq(&uport->lock); | 1811 | spin_unlock_irq(&uport->lock); |
1681 | if (pm_state != UART_PM_STATE_ON) | 1812 | if (pm_state != UART_PM_STATE_ON) |
1682 | uart_change_pm(state, pm_state); | 1813 | uart_change_pm(state, pm_state); |
1683 | mutex_unlock(&port->mutex); | ||
1684 | 1814 | ||
1685 | seq_printf(m, " tx:%d rx:%d", | 1815 | seq_printf(m, " tx:%d rx:%d", |
1686 | uport->icount.tx, uport->icount.rx); | 1816 | uport->icount.tx, uport->icount.rx); |
@@ -1718,6 +1848,8 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1718 | seq_putc(m, '\n'); | 1848 | seq_putc(m, '\n'); |
1719 | #undef STATBIT | 1849 | #undef STATBIT |
1720 | #undef INFOBIT | 1850 | #undef INFOBIT |
1851 | out: | ||
1852 | mutex_unlock(&port->mutex); | ||
1721 | } | 1853 | } |
1722 | 1854 | ||
1723 | static int uart_proc_show(struct seq_file *m, void *v) | 1855 | static int uart_proc_show(struct seq_file *m, void *v) |
@@ -1954,10 +2086,10 @@ EXPORT_SYMBOL_GPL(uart_set_options); | |||
1954 | static void uart_change_pm(struct uart_state *state, | 2086 | static void uart_change_pm(struct uart_state *state, |
1955 | enum uart_pm_state pm_state) | 2087 | enum uart_pm_state pm_state) |
1956 | { | 2088 | { |
1957 | struct uart_port *port = state->uart_port; | 2089 | struct uart_port *port = uart_port_check(state); |
1958 | 2090 | ||
1959 | if (state->pm_state != pm_state) { | 2091 | if (state->pm_state != pm_state) { |
1960 | if (port->ops->pm) | 2092 | if (port && port->ops->pm) |
1961 | port->ops->pm(port, pm_state, state->pm_state); | 2093 | port->ops->pm(port, pm_state, state->pm_state); |
1962 | state->pm_state = pm_state; | 2094 | state->pm_state = pm_state; |
1963 | } | 2095 | } |
@@ -2003,12 +2135,12 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2003 | 2135 | ||
2004 | uport->suspended = 1; | 2136 | uport->suspended = 1; |
2005 | 2137 | ||
2006 | if (port->flags & ASYNC_INITIALIZED) { | 2138 | if (tty_port_initialized(port)) { |
2007 | const struct uart_ops *ops = uport->ops; | 2139 | const struct uart_ops *ops = uport->ops; |
2008 | int tries; | 2140 | int tries; |
2009 | 2141 | ||
2010 | set_bit(ASYNCB_SUSPENDED, &port->flags); | 2142 | tty_port_set_suspended(port, 1); |
2011 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | 2143 | tty_port_set_initialized(port, 0); |
2012 | 2144 | ||
2013 | spin_lock_irq(&uport->lock); | 2145 | spin_lock_irq(&uport->lock); |
2014 | ops->stop_tx(uport); | 2146 | ops->stop_tx(uport); |
@@ -2088,7 +2220,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2088 | console_start(uport->cons); | 2220 | console_start(uport->cons); |
2089 | } | 2221 | } |
2090 | 2222 | ||
2091 | if (port->flags & ASYNC_SUSPENDED) { | 2223 | if (tty_port_suspended(port)) { |
2092 | const struct uart_ops *ops = uport->ops; | 2224 | const struct uart_ops *ops = uport->ops; |
2093 | int ret; | 2225 | int ret; |
2094 | 2226 | ||
@@ -2107,7 +2239,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2107 | ops->set_mctrl(uport, uport->mctrl); | 2239 | ops->set_mctrl(uport, uport->mctrl); |
2108 | ops->start_tx(uport); | 2240 | ops->start_tx(uport); |
2109 | spin_unlock_irq(&uport->lock); | 2241 | spin_unlock_irq(&uport->lock); |
2110 | set_bit(ASYNCB_INITIALIZED, &port->flags); | 2242 | tty_port_set_initialized(port, 1); |
2111 | } else { | 2243 | } else { |
2112 | /* | 2244 | /* |
2113 | * Failed to resume - maybe hardware went away? | 2245 | * Failed to resume - maybe hardware went away? |
@@ -2118,7 +2250,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2118 | } | 2250 | } |
2119 | } | 2251 | } |
2120 | 2252 | ||
2121 | clear_bit(ASYNCB_SUSPENDED, &port->flags); | 2253 | tty_port_set_suspended(port, 0); |
2122 | } | 2254 | } |
2123 | 2255 | ||
2124 | mutex_unlock(&port->mutex); | 2256 | mutex_unlock(&port->mutex); |
@@ -2228,42 +2360,42 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) | |||
2228 | { | 2360 | { |
2229 | struct uart_driver *drv = driver->driver_state; | 2361 | struct uart_driver *drv = driver->driver_state; |
2230 | struct uart_state *state = drv->state + line; | 2362 | struct uart_state *state = drv->state + line; |
2363 | struct tty_port *tport; | ||
2231 | struct uart_port *port; | 2364 | struct uart_port *port; |
2232 | int baud = 9600; | 2365 | int baud = 9600; |
2233 | int bits = 8; | 2366 | int bits = 8; |
2234 | int parity = 'n'; | 2367 | int parity = 'n'; |
2235 | int flow = 'n'; | 2368 | int flow = 'n'; |
2236 | int ret; | 2369 | int ret = 0; |
2237 | 2370 | ||
2238 | if (!state || !state->uart_port) | 2371 | if (!state) |
2239 | return -1; | 2372 | return -1; |
2240 | 2373 | ||
2241 | port = state->uart_port; | 2374 | tport = &state->port; |
2242 | if (!(port->ops->poll_get_char && port->ops->poll_put_char)) | 2375 | mutex_lock(&tport->mutex); |
2243 | return -1; | ||
2244 | 2376 | ||
2245 | if (port->ops->poll_init) { | 2377 | port = uart_port_check(state); |
2246 | struct tty_port *tport = &state->port; | 2378 | if (!port || !(port->ops->poll_get_char && port->ops->poll_put_char)) { |
2379 | ret = -1; | ||
2380 | goto out; | ||
2381 | } | ||
2247 | 2382 | ||
2248 | ret = 0; | 2383 | if (port->ops->poll_init) { |
2249 | mutex_lock(&tport->mutex); | ||
2250 | /* | 2384 | /* |
2251 | * We don't set ASYNCB_INITIALIZED as we only initialized the | 2385 | * We don't set initialized as we only initialized the hw, |
2252 | * hw, e.g. state->xmit is still uninitialized. | 2386 | * e.g. state->xmit is still uninitialized. |
2253 | */ | 2387 | */ |
2254 | if (!test_bit(ASYNCB_INITIALIZED, &tport->flags)) | 2388 | if (!tty_port_initialized(tport)) |
2255 | ret = port->ops->poll_init(port); | 2389 | ret = port->ops->poll_init(port); |
2256 | mutex_unlock(&tport->mutex); | ||
2257 | if (ret) | ||
2258 | return ret; | ||
2259 | } | 2390 | } |
2260 | 2391 | ||
2261 | if (options) { | 2392 | if (!ret && options) { |
2262 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 2393 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
2263 | return uart_set_options(port, NULL, baud, parity, bits, flow); | 2394 | ret = uart_set_options(port, NULL, baud, parity, bits, flow); |
2264 | } | 2395 | } |
2265 | 2396 | out: | |
2266 | return 0; | 2397 | mutex_unlock(&tport->mutex); |
2398 | return ret; | ||
2267 | } | 2399 | } |
2268 | 2400 | ||
2269 | static int uart_poll_get_char(struct tty_driver *driver, int line) | 2401 | static int uart_poll_get_char(struct tty_driver *driver, int line) |
@@ -2271,12 +2403,15 @@ static int uart_poll_get_char(struct tty_driver *driver, int line) | |||
2271 | struct uart_driver *drv = driver->driver_state; | 2403 | struct uart_driver *drv = driver->driver_state; |
2272 | struct uart_state *state = drv->state + line; | 2404 | struct uart_state *state = drv->state + line; |
2273 | struct uart_port *port; | 2405 | struct uart_port *port; |
2406 | int ret = -1; | ||
2274 | 2407 | ||
2275 | if (!state || !state->uart_port) | 2408 | if (state) { |
2276 | return -1; | 2409 | port = uart_port_ref(state); |
2277 | 2410 | if (port) | |
2278 | port = state->uart_port; | 2411 | ret = port->ops->poll_get_char(port); |
2279 | return port->ops->poll_get_char(port); | 2412 | uart_port_deref(port); |
2413 | } | ||
2414 | return ret; | ||
2280 | } | 2415 | } |
2281 | 2416 | ||
2282 | static void uart_poll_put_char(struct tty_driver *driver, int line, char ch) | 2417 | static void uart_poll_put_char(struct tty_driver *driver, int line, char ch) |
@@ -2285,14 +2420,17 @@ static void uart_poll_put_char(struct tty_driver *driver, int line, char ch) | |||
2285 | struct uart_state *state = drv->state + line; | 2420 | struct uart_state *state = drv->state + line; |
2286 | struct uart_port *port; | 2421 | struct uart_port *port; |
2287 | 2422 | ||
2288 | if (!state || !state->uart_port) | 2423 | if (!state) |
2289 | return; | 2424 | return; |
2290 | 2425 | ||
2291 | port = state->uart_port; | 2426 | port = uart_port_ref(state); |
2427 | if (!port) | ||
2428 | return; | ||
2292 | 2429 | ||
2293 | if (ch == '\n') | 2430 | if (ch == '\n') |
2294 | port->ops->poll_put_char(port, '\r'); | 2431 | port->ops->poll_put_char(port, '\r'); |
2295 | port->ops->poll_put_char(port, ch); | 2432 | port->ops->poll_put_char(port, ch); |
2433 | uart_port_deref(port); | ||
2296 | } | 2434 | } |
2297 | #endif | 2435 | #endif |
2298 | 2436 | ||
@@ -2639,6 +2777,8 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2639 | } | 2777 | } |
2640 | 2778 | ||
2641 | /* Link the port to the driver state table and vice versa */ | 2779 | /* Link the port to the driver state table and vice versa */ |
2780 | atomic_set(&state->refcount, 1); | ||
2781 | init_waitqueue_head(&state->remove_wait); | ||
2642 | state->uart_port = uport; | 2782 | state->uart_port = uport; |
2643 | uport->state = state; | 2783 | uport->state = state; |
2644 | 2784 | ||
@@ -2711,15 +2851,12 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2711 | { | 2851 | { |
2712 | struct uart_state *state = drv->state + uport->line; | 2852 | struct uart_state *state = drv->state + uport->line; |
2713 | struct tty_port *port = &state->port; | 2853 | struct tty_port *port = &state->port; |
2854 | struct uart_port *uart_port; | ||
2714 | struct tty_struct *tty; | 2855 | struct tty_struct *tty; |
2715 | int ret = 0; | 2856 | int ret = 0; |
2716 | 2857 | ||
2717 | BUG_ON(in_interrupt()); | 2858 | BUG_ON(in_interrupt()); |
2718 | 2859 | ||
2719 | if (state->uart_port != uport) | ||
2720 | dev_alert(uport->dev, "Removing wrong port: %p != %p\n", | ||
2721 | state->uart_port, uport); | ||
2722 | |||
2723 | mutex_lock(&port_mutex); | 2860 | mutex_lock(&port_mutex); |
2724 | 2861 | ||
2725 | /* | 2862 | /* |
@@ -2727,7 +2864,12 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2727 | * succeeding while we shut down the port. | 2864 | * succeeding while we shut down the port. |
2728 | */ | 2865 | */ |
2729 | mutex_lock(&port->mutex); | 2866 | mutex_lock(&port->mutex); |
2730 | if (!state->uart_port) { | 2867 | uart_port = uart_port_check(state); |
2868 | if (uart_port != uport) | ||
2869 | dev_alert(uport->dev, "Removing wrong port: %p != %p\n", | ||
2870 | uart_port, uport); | ||
2871 | |||
2872 | if (!uart_port) { | ||
2731 | mutex_unlock(&port->mutex); | 2873 | mutex_unlock(&port->mutex); |
2732 | ret = -EINVAL; | 2874 | ret = -EINVAL; |
2733 | goto out; | 2875 | goto out; |
@@ -2764,7 +2906,11 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2764 | */ | 2906 | */ |
2765 | uport->type = PORT_UNKNOWN; | 2907 | uport->type = PORT_UNKNOWN; |
2766 | 2908 | ||
2909 | mutex_lock(&port->mutex); | ||
2910 | WARN_ON(atomic_dec_return(&state->refcount) < 0); | ||
2911 | wait_event(state->remove_wait, !atomic_read(&state->refcount)); | ||
2767 | state->uart_port = NULL; | 2912 | state->uart_port = NULL; |
2913 | mutex_unlock(&port->mutex); | ||
2768 | out: | 2914 | out: |
2769 | mutex_unlock(&port_mutex); | 2915 | mutex_unlock(&port_mutex); |
2770 | 2916 | ||
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index 02147361eaa9..e8dd5097dc56 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c | |||
@@ -43,8 +43,6 @@ static const struct { | |||
43 | { "rng", TIOCM_RNG, false, }, | 43 | { "rng", TIOCM_RNG, false, }, |
44 | { "rts", TIOCM_RTS, true, }, | 44 | { "rts", TIOCM_RTS, true, }, |
45 | { "dtr", TIOCM_DTR, true, }, | 45 | { "dtr", TIOCM_DTR, true, }, |
46 | { "out1", TIOCM_OUT1, true, }, | ||
47 | { "out2", TIOCM_OUT2, true, }, | ||
48 | }; | 46 | }; |
49 | 47 | ||
50 | void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl) | 48 | void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl) |
@@ -125,9 +123,12 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context) | |||
125 | struct uart_port *port = gpios->port; | 123 | struct uart_port *port = gpios->port; |
126 | u32 mctrl = gpios->mctrl_prev; | 124 | u32 mctrl = gpios->mctrl_prev; |
127 | u32 mctrl_diff; | 125 | u32 mctrl_diff; |
126 | unsigned long flags; | ||
128 | 127 | ||
129 | mctrl_gpio_get(gpios, &mctrl); | 128 | mctrl_gpio_get(gpios, &mctrl); |
130 | 129 | ||
130 | spin_lock_irqsave(&port->lock, flags); | ||
131 | |||
131 | mctrl_diff = mctrl ^ gpios->mctrl_prev; | 132 | mctrl_diff = mctrl ^ gpios->mctrl_prev; |
132 | gpios->mctrl_prev = mctrl; | 133 | gpios->mctrl_prev = mctrl; |
133 | 134 | ||
@@ -147,6 +148,8 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context) | |||
147 | wake_up_interruptible(&port->state->port.delta_msr_wait); | 148 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
148 | } | 149 | } |
149 | 150 | ||
151 | spin_unlock_irqrestore(&port->lock, flags); | ||
152 | |||
150 | return IRQ_HANDLED; | 153 | return IRQ_HANDLED; |
151 | } | 154 | } |
152 | 155 | ||
diff --git a/drivers/tty/serial/serial_mctrl_gpio.h b/drivers/tty/serial/serial_mctrl_gpio.h index bcfad5d1db61..332a33ab0647 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.h +++ b/drivers/tty/serial/serial_mctrl_gpio.h | |||
@@ -32,8 +32,6 @@ enum mctrl_gpio_idx { | |||
32 | UART_GPIO_RI = UART_GPIO_RNG, | 32 | UART_GPIO_RI = UART_GPIO_RNG, |
33 | UART_GPIO_RTS, | 33 | UART_GPIO_RTS, |
34 | UART_GPIO_DTR, | 34 | UART_GPIO_DTR, |
35 | UART_GPIO_OUT1, | ||
36 | UART_GPIO_OUT2, | ||
37 | UART_GPIO_MAX, | 35 | UART_GPIO_MAX, |
38 | }; | 36 | }; |
39 | 37 | ||
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index c6657de78997..b186c9c4f850 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -1264,6 +1264,7 @@ MODULE_DEVICE_TABLE(of, sirfsoc_uart_ids); | |||
1264 | 1264 | ||
1265 | static int sirfsoc_uart_probe(struct platform_device *pdev) | 1265 | static int sirfsoc_uart_probe(struct platform_device *pdev) |
1266 | { | 1266 | { |
1267 | struct device_node *np = pdev->dev.of_node; | ||
1267 | struct sirfsoc_uart_port *sirfport; | 1268 | struct sirfsoc_uart_port *sirfport; |
1268 | struct uart_port *port; | 1269 | struct uart_port *port; |
1269 | struct resource *res; | 1270 | struct resource *res; |
@@ -1276,13 +1277,13 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
1276 | }; | 1277 | }; |
1277 | const struct of_device_id *match; | 1278 | const struct of_device_id *match; |
1278 | 1279 | ||
1279 | match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node); | 1280 | match = of_match_node(sirfsoc_uart_ids, np); |
1280 | sirfport = devm_kzalloc(&pdev->dev, sizeof(*sirfport), GFP_KERNEL); | 1281 | sirfport = devm_kzalloc(&pdev->dev, sizeof(*sirfport), GFP_KERNEL); |
1281 | if (!sirfport) { | 1282 | if (!sirfport) { |
1282 | ret = -ENOMEM; | 1283 | ret = -ENOMEM; |
1283 | goto err; | 1284 | goto err; |
1284 | } | 1285 | } |
1285 | sirfport->port.line = of_alias_get_id(pdev->dev.of_node, "serial"); | 1286 | sirfport->port.line = of_alias_get_id(np, "serial"); |
1286 | sirf_ports[sirfport->port.line] = sirfport; | 1287 | sirf_ports[sirfport->port.line] = sirfport; |
1287 | sirfport->port.iotype = UPIO_MEM; | 1288 | sirfport->port.iotype = UPIO_MEM; |
1288 | sirfport->port.flags = UPF_BOOT_AUTOCONF; | 1289 | sirfport->port.flags = UPF_BOOT_AUTOCONF; |
@@ -1291,25 +1292,25 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
1291 | port->private_data = sirfport; | 1292 | port->private_data = sirfport; |
1292 | sirfport->uart_reg = (struct sirfsoc_uart_register *)match->data; | 1293 | sirfport->uart_reg = (struct sirfsoc_uart_register *)match->data; |
1293 | 1294 | ||
1294 | sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node, | 1295 | sirfport->hw_flow_ctrl = |
1295 | "sirf,uart-has-rtscts"); | 1296 | of_property_read_bool(np, "uart-has-rtscts") || |
1296 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart") || | 1297 | of_property_read_bool(np, "sirf,uart-has-rtscts") /* deprecated */; |
1297 | of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart")) | 1298 | if (of_device_is_compatible(np, "sirf,prima2-uart") || |
1299 | of_device_is_compatible(np, "sirf,atlas7-uart")) | ||
1298 | sirfport->uart_reg->uart_type = SIRF_REAL_UART; | 1300 | sirfport->uart_reg->uart_type = SIRF_REAL_UART; |
1299 | if (of_device_is_compatible(pdev->dev.of_node, | 1301 | if (of_device_is_compatible(np, "sirf,prima2-usp-uart") || |
1300 | "sirf,prima2-usp-uart") || of_device_is_compatible( | 1302 | of_device_is_compatible(np, "sirf,atlas7-usp-uart")) { |
1301 | pdev->dev.of_node, "sirf,atlas7-usp-uart")) { | ||
1302 | sirfport->uart_reg->uart_type = SIRF_USP_UART; | 1303 | sirfport->uart_reg->uart_type = SIRF_USP_UART; |
1303 | if (!sirfport->hw_flow_ctrl) | 1304 | if (!sirfport->hw_flow_ctrl) |
1304 | goto usp_no_flow_control; | 1305 | goto usp_no_flow_control; |
1305 | if (of_find_property(pdev->dev.of_node, "cts-gpios", NULL)) | 1306 | if (of_find_property(np, "cts-gpios", NULL)) |
1306 | sirfport->cts_gpio = of_get_named_gpio( | 1307 | sirfport->cts_gpio = |
1307 | pdev->dev.of_node, "cts-gpios", 0); | 1308 | of_get_named_gpio(np, "cts-gpios", 0); |
1308 | else | 1309 | else |
1309 | sirfport->cts_gpio = -1; | 1310 | sirfport->cts_gpio = -1; |
1310 | if (of_find_property(pdev->dev.of_node, "rts-gpios", NULL)) | 1311 | if (of_find_property(np, "rts-gpios", NULL)) |
1311 | sirfport->rts_gpio = of_get_named_gpio( | 1312 | sirfport->rts_gpio = |
1312 | pdev->dev.of_node, "rts-gpios", 0); | 1313 | of_get_named_gpio(np, "rts-gpios", 0); |
1313 | else | 1314 | else |
1314 | sirfport->rts_gpio = -1; | 1315 | sirfport->rts_gpio = -1; |
1315 | 1316 | ||
@@ -1336,13 +1337,11 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
1336 | gpio_direction_output(sirfport->rts_gpio, 1); | 1337 | gpio_direction_output(sirfport->rts_gpio, 1); |
1337 | } | 1338 | } |
1338 | usp_no_flow_control: | 1339 | usp_no_flow_control: |
1339 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart") || | 1340 | if (of_device_is_compatible(np, "sirf,atlas7-uart") || |
1340 | of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-usp-uart")) | 1341 | of_device_is_compatible(np, "sirf,atlas7-usp-uart")) |
1341 | sirfport->is_atlas7 = true; | 1342 | sirfport->is_atlas7 = true; |
1342 | 1343 | ||
1343 | if (of_property_read_u32(pdev->dev.of_node, | 1344 | if (of_property_read_u32(np, "fifosize", &port->fifosize)) { |
1344 | "fifosize", | ||
1345 | &port->fifosize)) { | ||
1346 | dev_err(&pdev->dev, | 1345 | dev_err(&pdev->dev, |
1347 | "Unable to find fifosize in uart node.\n"); | 1346 | "Unable to find fifosize in uart node.\n"); |
1348 | ret = -EFAULT; | 1347 | ret = -EFAULT; |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index d08baa668d5d..05089b6c2f30 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -72,7 +72,7 @@ static void uartlite_outbe32(u32 val, void __iomem *addr) | |||
72 | iowrite32be(val, addr); | 72 | iowrite32be(val, addr); |
73 | } | 73 | } |
74 | 74 | ||
75 | static struct uartlite_reg_ops uartlite_be = { | 75 | static const struct uartlite_reg_ops uartlite_be = { |
76 | .in = uartlite_inbe32, | 76 | .in = uartlite_inbe32, |
77 | .out = uartlite_outbe32, | 77 | .out = uartlite_outbe32, |
78 | }; | 78 | }; |
@@ -87,21 +87,21 @@ static void uartlite_outle32(u32 val, void __iomem *addr) | |||
87 | iowrite32(val, addr); | 87 | iowrite32(val, addr); |
88 | } | 88 | } |
89 | 89 | ||
90 | static struct uartlite_reg_ops uartlite_le = { | 90 | static const struct uartlite_reg_ops uartlite_le = { |
91 | .in = uartlite_inle32, | 91 | .in = uartlite_inle32, |
92 | .out = uartlite_outle32, | 92 | .out = uartlite_outle32, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static inline u32 uart_in32(u32 offset, struct uart_port *port) | 95 | static inline u32 uart_in32(u32 offset, struct uart_port *port) |
96 | { | 96 | { |
97 | struct uartlite_reg_ops *reg_ops = port->private_data; | 97 | const struct uartlite_reg_ops *reg_ops = port->private_data; |
98 | 98 | ||
99 | return reg_ops->in(port->membase + offset); | 99 | return reg_ops->in(port->membase + offset); |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) | 102 | static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) |
103 | { | 103 | { |
104 | struct uartlite_reg_ops *reg_ops = port->private_data; | 104 | const struct uartlite_reg_ops *reg_ops = port->private_data; |
105 | 105 | ||
106 | reg_ops->out(val, port->membase + offset); | 106 | reg_ops->out(val, port->membase + offset); |
107 | } | 107 | } |
@@ -345,13 +345,13 @@ static int ulite_request_port(struct uart_port *port) | |||
345 | return -EBUSY; | 345 | return -EBUSY; |
346 | } | 346 | } |
347 | 347 | ||
348 | port->private_data = &uartlite_be; | 348 | port->private_data = (void *)&uartlite_be; |
349 | ret = uart_in32(ULITE_CONTROL, port); | 349 | ret = uart_in32(ULITE_CONTROL, port); |
350 | uart_out32(ULITE_CONTROL_RST_TX, ULITE_CONTROL, port); | 350 | uart_out32(ULITE_CONTROL_RST_TX, ULITE_CONTROL, port); |
351 | ret = uart_in32(ULITE_STATUS, port); | 351 | ret = uart_in32(ULITE_STATUS, port); |
352 | /* Endianess detection */ | 352 | /* Endianess detection */ |
353 | if ((ret & ULITE_STATUS_TXEMPTY) != ULITE_STATUS_TXEMPTY) | 353 | if ((ret & ULITE_STATUS_TXEMPTY) != ULITE_STATUS_TXEMPTY) |
354 | port->private_data = &uartlite_le; | 354 | port->private_data = (void *)&uartlite_le; |
355 | 355 | ||
356 | return 0; | 356 | return 0; |
357 | } | 357 | } |
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 1a7dc3c590b1..481eb2989a1e 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c | |||
@@ -1478,6 +1478,9 @@ static const struct of_device_id ucc_uart_match[] = { | |||
1478 | .type = "serial", | 1478 | .type = "serial", |
1479 | .compatible = "ucc_uart", | 1479 | .compatible = "ucc_uart", |
1480 | }, | 1480 | }, |
1481 | { | ||
1482 | .compatible = "fsl,t1040-ucc-uart", | ||
1483 | }, | ||
1481 | {}, | 1484 | {}, |
1482 | }; | 1485 | }; |
1483 | MODULE_DEVICE_TABLE(of, ucc_uart_match); | 1486 | MODULE_DEVICE_TABLE(of, ucc_uart_match); |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index c8c760151094..c13e27ecb0b7 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -1340,7 +1340,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info ) | |||
1340 | wake_up_interruptible(&info->status_event_wait_q); | 1340 | wake_up_interruptible(&info->status_event_wait_q); |
1341 | wake_up_interruptible(&info->event_wait_q); | 1341 | wake_up_interruptible(&info->event_wait_q); |
1342 | 1342 | ||
1343 | if ( (info->port.flags & ASYNC_CHECK_CD) && | 1343 | if (tty_port_check_carrier(&info->port) && |
1344 | (status & MISCSTATUS_DCD_LATCHED) ) { | 1344 | (status & MISCSTATUS_DCD_LATCHED) ) { |
1345 | if ( debug_level >= DEBUG_LEVEL_ISR ) | 1345 | if ( debug_level >= DEBUG_LEVEL_ISR ) |
1346 | printk("%s CD now %s...", info->device_name, | 1346 | printk("%s CD now %s...", info->device_name, |
@@ -1361,8 +1361,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info ) | |||
1361 | if (status & MISCSTATUS_CTS) { | 1361 | if (status & MISCSTATUS_CTS) { |
1362 | if ( debug_level >= DEBUG_LEVEL_ISR ) | 1362 | if ( debug_level >= DEBUG_LEVEL_ISR ) |
1363 | printk("CTS tx start..."); | 1363 | printk("CTS tx start..."); |
1364 | if (info->port.tty) | 1364 | info->port.tty->hw_stopped = 0; |
1365 | info->port.tty->hw_stopped = 0; | ||
1366 | usc_start_transmitter(info); | 1365 | usc_start_transmitter(info); |
1367 | info->pending_bh |= BH_TRANSMIT; | 1366 | info->pending_bh |= BH_TRANSMIT; |
1368 | return; | 1367 | return; |
@@ -1749,13 +1748,13 @@ static irqreturn_t mgsl_interrupt(int dummy, void *dev_id) | |||
1749 | static int startup(struct mgsl_struct * info) | 1748 | static int startup(struct mgsl_struct * info) |
1750 | { | 1749 | { |
1751 | int retval = 0; | 1750 | int retval = 0; |
1752 | 1751 | ||
1753 | if ( debug_level >= DEBUG_LEVEL_INFO ) | 1752 | if ( debug_level >= DEBUG_LEVEL_INFO ) |
1754 | printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name); | 1753 | printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name); |
1755 | 1754 | ||
1756 | if (info->port.flags & ASYNC_INITIALIZED) | 1755 | if (tty_port_initialized(&info->port)) |
1757 | return 0; | 1756 | return 0; |
1758 | 1757 | ||
1759 | if (!info->xmit_buf) { | 1758 | if (!info->xmit_buf) { |
1760 | /* allocate a page of memory for a transmit buffer */ | 1759 | /* allocate a page of memory for a transmit buffer */ |
1761 | info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | 1760 | info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); |
@@ -1788,14 +1787,13 @@ static int startup(struct mgsl_struct * info) | |||
1788 | 1787 | ||
1789 | /* program hardware for current parameters */ | 1788 | /* program hardware for current parameters */ |
1790 | mgsl_change_params(info); | 1789 | mgsl_change_params(info); |
1791 | 1790 | ||
1792 | if (info->port.tty) | 1791 | if (info->port.tty) |
1793 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | 1792 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); |
1794 | 1793 | ||
1795 | info->port.flags |= ASYNC_INITIALIZED; | 1794 | tty_port_set_initialized(&info->port, 1); |
1796 | 1795 | ||
1797 | return 0; | 1796 | return 0; |
1798 | |||
1799 | } /* end of startup() */ | 1797 | } /* end of startup() */ |
1800 | 1798 | ||
1801 | /* shutdown() | 1799 | /* shutdown() |
@@ -1808,8 +1806,8 @@ static int startup(struct mgsl_struct * info) | |||
1808 | static void shutdown(struct mgsl_struct * info) | 1806 | static void shutdown(struct mgsl_struct * info) |
1809 | { | 1807 | { |
1810 | unsigned long flags; | 1808 | unsigned long flags; |
1811 | 1809 | ||
1812 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1810 | if (!tty_port_initialized(&info->port)) |
1813 | return; | 1811 | return; |
1814 | 1812 | ||
1815 | if (debug_level >= DEBUG_LEVEL_INFO) | 1813 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -1853,13 +1851,12 @@ static void shutdown(struct mgsl_struct * info) | |||
1853 | 1851 | ||
1854 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 1852 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
1855 | 1853 | ||
1856 | mgsl_release_resources(info); | 1854 | mgsl_release_resources(info); |
1857 | 1855 | ||
1858 | if (info->port.tty) | 1856 | if (info->port.tty) |
1859 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 1857 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
1860 | 1858 | ||
1861 | info->port.flags &= ~ASYNC_INITIALIZED; | 1859 | tty_port_set_initialized(&info->port, 0); |
1862 | |||
1863 | } /* end of shutdown() */ | 1860 | } /* end of shutdown() */ |
1864 | 1861 | ||
1865 | static void mgsl_program_hw(struct mgsl_struct *info) | 1862 | static void mgsl_program_hw(struct mgsl_struct *info) |
@@ -1966,15 +1963,8 @@ static void mgsl_change_params(struct mgsl_struct *info) | |||
1966 | } | 1963 | } |
1967 | info->timeout += HZ/50; /* Add .02 seconds of slop */ | 1964 | info->timeout += HZ/50; /* Add .02 seconds of slop */ |
1968 | 1965 | ||
1969 | if (cflag & CRTSCTS) | 1966 | tty_port_set_cts_flow(&info->port, cflag & CRTSCTS); |
1970 | info->port.flags |= ASYNC_CTS_FLOW; | 1967 | tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL); |
1971 | else | ||
1972 | info->port.flags &= ~ASYNC_CTS_FLOW; | ||
1973 | |||
1974 | if (cflag & CLOCAL) | ||
1975 | info->port.flags &= ~ASYNC_CHECK_CD; | ||
1976 | else | ||
1977 | info->port.flags |= ASYNC_CHECK_CD; | ||
1978 | 1968 | ||
1979 | /* process tty input control flags */ | 1969 | /* process tty input control flags */ |
1980 | 1970 | ||
@@ -2972,7 +2962,7 @@ static int mgsl_ioctl(struct tty_struct *tty, | |||
2972 | 2962 | ||
2973 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 2963 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
2974 | (cmd != TIOCMIWAIT)) { | 2964 | (cmd != TIOCMIWAIT)) { |
2975 | if (tty->flags & (1 << TTY_IO_ERROR)) | 2965 | if (tty_io_error(tty)) |
2976 | return -EIO; | 2966 | return -EIO; |
2977 | } | 2967 | } |
2978 | 2968 | ||
@@ -3049,7 +3039,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
3049 | /* Handle transition away from B0 status */ | 3039 | /* Handle transition away from B0 status */ |
3050 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { | 3040 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
3051 | info->serial_signals |= SerialSignal_DTR; | 3041 | info->serial_signals |= SerialSignal_DTR; |
3052 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) | 3042 | if (!C_CRTSCTS(tty) || !tty_throttled(tty)) |
3053 | info->serial_signals |= SerialSignal_RTS; | 3043 | info->serial_signals |= SerialSignal_RTS; |
3054 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3044 | spin_lock_irqsave(&info->irq_spinlock,flags); |
3055 | usc_set_serial_signals(info); | 3045 | usc_set_serial_signals(info); |
@@ -3091,7 +3081,7 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp) | |||
3091 | goto cleanup; | 3081 | goto cleanup; |
3092 | 3082 | ||
3093 | mutex_lock(&info->port.mutex); | 3083 | mutex_lock(&info->port.mutex); |
3094 | if (info->port.flags & ASYNC_INITIALIZED) | 3084 | if (tty_port_initialized(&info->port)) |
3095 | mgsl_wait_until_sent(tty, info->timeout); | 3085 | mgsl_wait_until_sent(tty, info->timeout); |
3096 | mgsl_flush_buffer(tty); | 3086 | mgsl_flush_buffer(tty); |
3097 | tty_ldisc_flush(tty); | 3087 | tty_ldisc_flush(tty); |
@@ -3129,15 +3119,15 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3129 | if (debug_level >= DEBUG_LEVEL_INFO) | 3119 | if (debug_level >= DEBUG_LEVEL_INFO) |
3130 | printk("%s(%d):mgsl_wait_until_sent(%s) entry\n", | 3120 | printk("%s(%d):mgsl_wait_until_sent(%s) entry\n", |
3131 | __FILE__,__LINE__, info->device_name ); | 3121 | __FILE__,__LINE__, info->device_name ); |
3132 | 3122 | ||
3133 | if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent")) | 3123 | if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent")) |
3134 | return; | 3124 | return; |
3135 | 3125 | ||
3136 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 3126 | if (!tty_port_initialized(&info->port)) |
3137 | goto exit; | 3127 | goto exit; |
3138 | 3128 | ||
3139 | orig_jiffies = jiffies; | 3129 | orig_jiffies = jiffies; |
3140 | 3130 | ||
3141 | /* Set check interval to 1/5 of estimated time to | 3131 | /* Set check interval to 1/5 of estimated time to |
3142 | * send a character, and make it at least 1. The check | 3132 | * send a character, and make it at least 1. The check |
3143 | * interval should also be less than the timeout. | 3133 | * interval should also be less than the timeout. |
@@ -3204,7 +3194,7 @@ static void mgsl_hangup(struct tty_struct *tty) | |||
3204 | shutdown(info); | 3194 | shutdown(info); |
3205 | 3195 | ||
3206 | info->port.count = 0; | 3196 | info->port.count = 0; |
3207 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 3197 | tty_port_set_active(&info->port, 0); |
3208 | info->port.tty = NULL; | 3198 | info->port.tty = NULL; |
3209 | 3199 | ||
3210 | wake_up_interruptible(&info->port.open_wait); | 3200 | wake_up_interruptible(&info->port.open_wait); |
@@ -3270,9 +3260,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3270 | printk("%s(%d):block_til_ready on %s\n", | 3260 | printk("%s(%d):block_til_ready on %s\n", |
3271 | __FILE__,__LINE__, tty->driver->name ); | 3261 | __FILE__,__LINE__, tty->driver->name ); |
3272 | 3262 | ||
3273 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ | 3263 | if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { |
3274 | /* nonblock mode is set or port is not enabled */ | 3264 | /* nonblock mode is set or port is not enabled */ |
3275 | port->flags |= ASYNC_NORMAL_ACTIVE; | 3265 | tty_port_set_active(port, 1); |
3276 | return 0; | 3266 | return 0; |
3277 | } | 3267 | } |
3278 | 3268 | ||
@@ -3297,14 +3287,14 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3297 | port->count--; | 3287 | port->count--; |
3298 | spin_unlock_irqrestore(&info->irq_spinlock, flags); | 3288 | spin_unlock_irqrestore(&info->irq_spinlock, flags); |
3299 | port->blocked_open++; | 3289 | port->blocked_open++; |
3300 | 3290 | ||
3301 | while (1) { | 3291 | while (1) { |
3302 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) | 3292 | if (C_BAUD(tty) && tty_port_initialized(port)) |
3303 | tty_port_raise_dtr_rts(port); | 3293 | tty_port_raise_dtr_rts(port); |
3304 | 3294 | ||
3305 | set_current_state(TASK_INTERRUPTIBLE); | 3295 | set_current_state(TASK_INTERRUPTIBLE); |
3306 | 3296 | ||
3307 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ | 3297 | if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { |
3308 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? | 3298 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
3309 | -EAGAIN : -ERESTARTSYS; | 3299 | -EAGAIN : -ERESTARTSYS; |
3310 | break; | 3300 | break; |
@@ -3341,7 +3331,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3341 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3331 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3342 | 3332 | ||
3343 | if (!retval) | 3333 | if (!retval) |
3344 | port->flags |= ASYNC_NORMAL_ACTIVE; | 3334 | tty_port_set_active(port, 1); |
3345 | 3335 | ||
3346 | return retval; | 3336 | return retval; |
3347 | 3337 | ||
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index d5b6471bece4..7aca2d4670e4 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -726,7 +726,7 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
726 | goto cleanup; | 726 | goto cleanup; |
727 | 727 | ||
728 | mutex_lock(&info->port.mutex); | 728 | mutex_lock(&info->port.mutex); |
729 | if (info->port.flags & ASYNC_INITIALIZED) | 729 | if (tty_port_initialized(&info->port)) |
730 | wait_until_sent(tty, info->timeout); | 730 | wait_until_sent(tty, info->timeout); |
731 | flush_buffer(tty); | 731 | flush_buffer(tty); |
732 | tty_ldisc_flush(tty); | 732 | tty_ldisc_flush(tty); |
@@ -756,9 +756,9 @@ static void hangup(struct tty_struct *tty) | |||
756 | 756 | ||
757 | spin_lock_irqsave(&info->port.lock, flags); | 757 | spin_lock_irqsave(&info->port.lock, flags); |
758 | info->port.count = 0; | 758 | info->port.count = 0; |
759 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | ||
760 | info->port.tty = NULL; | 759 | info->port.tty = NULL; |
761 | spin_unlock_irqrestore(&info->port.lock, flags); | 760 | spin_unlock_irqrestore(&info->port.lock, flags); |
761 | tty_port_set_active(&info->port, 0); | ||
762 | mutex_unlock(&info->port.mutex); | 762 | mutex_unlock(&info->port.mutex); |
763 | 763 | ||
764 | wake_up_interruptible(&info->port.open_wait); | 764 | wake_up_interruptible(&info->port.open_wait); |
@@ -784,7 +784,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
784 | /* Handle transition away from B0 status */ | 784 | /* Handle transition away from B0 status */ |
785 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { | 785 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
786 | info->signals |= SerialSignal_DTR; | 786 | info->signals |= SerialSignal_DTR; |
787 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) | 787 | if (!C_CRTSCTS(tty) || !tty_throttled(tty)) |
788 | info->signals |= SerialSignal_RTS; | 788 | info->signals |= SerialSignal_RTS; |
789 | spin_lock_irqsave(&info->lock,flags); | 789 | spin_lock_irqsave(&info->lock,flags); |
790 | set_signals(info); | 790 | set_signals(info); |
@@ -893,7 +893,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
893 | if (sanity_check(info, tty->name, "wait_until_sent")) | 893 | if (sanity_check(info, tty->name, "wait_until_sent")) |
894 | return; | 894 | return; |
895 | DBGINFO(("%s wait_until_sent entry\n", info->device_name)); | 895 | DBGINFO(("%s wait_until_sent entry\n", info->device_name)); |
896 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 896 | if (!tty_port_initialized(&info->port)) |
897 | goto exit; | 897 | goto exit; |
898 | 898 | ||
899 | orig_jiffies = jiffies; | 899 | orig_jiffies = jiffies; |
@@ -1032,7 +1032,7 @@ static int ioctl(struct tty_struct *tty, | |||
1032 | 1032 | ||
1033 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1033 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1034 | (cmd != TIOCMIWAIT)) { | 1034 | (cmd != TIOCMIWAIT)) { |
1035 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1035 | if (tty_io_error(tty)) |
1036 | return -EIO; | 1036 | return -EIO; |
1037 | } | 1037 | } |
1038 | 1038 | ||
@@ -2080,7 +2080,7 @@ static void dcd_change(struct slgt_info *info, unsigned short status) | |||
2080 | wake_up_interruptible(&info->event_wait_q); | 2080 | wake_up_interruptible(&info->event_wait_q); |
2081 | info->pending_bh |= BH_STATUS; | 2081 | info->pending_bh |= BH_STATUS; |
2082 | 2082 | ||
2083 | if (info->port.flags & ASYNC_CHECK_CD) { | 2083 | if (tty_port_check_carrier(&info->port)) { |
2084 | if (info->signals & SerialSignal_DCD) | 2084 | if (info->signals & SerialSignal_DCD) |
2085 | wake_up_interruptible(&info->port.open_wait); | 2085 | wake_up_interruptible(&info->port.open_wait); |
2086 | else { | 2086 | else { |
@@ -2421,7 +2421,7 @@ static int startup(struct slgt_info *info) | |||
2421 | { | 2421 | { |
2422 | DBGINFO(("%s startup\n", info->device_name)); | 2422 | DBGINFO(("%s startup\n", info->device_name)); |
2423 | 2423 | ||
2424 | if (info->port.flags & ASYNC_INITIALIZED) | 2424 | if (tty_port_initialized(&info->port)) |
2425 | return 0; | 2425 | return 0; |
2426 | 2426 | ||
2427 | if (!info->tx_buf) { | 2427 | if (!info->tx_buf) { |
@@ -2442,7 +2442,7 @@ static int startup(struct slgt_info *info) | |||
2442 | if (info->port.tty) | 2442 | if (info->port.tty) |
2443 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | 2443 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); |
2444 | 2444 | ||
2445 | info->port.flags |= ASYNC_INITIALIZED; | 2445 | tty_port_set_initialized(&info->port, 1); |
2446 | 2446 | ||
2447 | return 0; | 2447 | return 0; |
2448 | } | 2448 | } |
@@ -2454,7 +2454,7 @@ static void shutdown(struct slgt_info *info) | |||
2454 | { | 2454 | { |
2455 | unsigned long flags; | 2455 | unsigned long flags; |
2456 | 2456 | ||
2457 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 2457 | if (!tty_port_initialized(&info->port)) |
2458 | return; | 2458 | return; |
2459 | 2459 | ||
2460 | DBGINFO(("%s shutdown\n", info->device_name)); | 2460 | DBGINFO(("%s shutdown\n", info->device_name)); |
@@ -2489,7 +2489,7 @@ static void shutdown(struct slgt_info *info) | |||
2489 | if (info->port.tty) | 2489 | if (info->port.tty) |
2490 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 2490 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
2491 | 2491 | ||
2492 | info->port.flags &= ~ASYNC_INITIALIZED; | 2492 | tty_port_set_initialized(&info->port, 0); |
2493 | } | 2493 | } |
2494 | 2494 | ||
2495 | static void program_hw(struct slgt_info *info) | 2495 | static void program_hw(struct slgt_info *info) |
@@ -2576,15 +2576,8 @@ static void change_params(struct slgt_info *info) | |||
2576 | } | 2576 | } |
2577 | info->timeout += HZ/50; /* Add .02 seconds of slop */ | 2577 | info->timeout += HZ/50; /* Add .02 seconds of slop */ |
2578 | 2578 | ||
2579 | if (cflag & CRTSCTS) | 2579 | tty_port_set_cts_flow(&info->port, cflag & CRTSCTS); |
2580 | info->port.flags |= ASYNC_CTS_FLOW; | 2580 | tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL); |
2581 | else | ||
2582 | info->port.flags &= ~ASYNC_CTS_FLOW; | ||
2583 | |||
2584 | if (cflag & CLOCAL) | ||
2585 | info->port.flags &= ~ASYNC_CHECK_CD; | ||
2586 | else | ||
2587 | info->port.flags |= ASYNC_CHECK_CD; | ||
2588 | 2581 | ||
2589 | /* process tty input control flags */ | 2582 | /* process tty input control flags */ |
2590 | 2583 | ||
@@ -3269,9 +3262,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3269 | 3262 | ||
3270 | DBGINFO(("%s block_til_ready\n", tty->driver->name)); | 3263 | DBGINFO(("%s block_til_ready\n", tty->driver->name)); |
3271 | 3264 | ||
3272 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ | 3265 | if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { |
3273 | /* nonblock mode is set or port is not enabled */ | 3266 | /* nonblock mode is set or port is not enabled */ |
3274 | port->flags |= ASYNC_NORMAL_ACTIVE; | 3267 | tty_port_set_active(port, 1); |
3275 | return 0; | 3268 | return 0; |
3276 | } | 3269 | } |
3277 | 3270 | ||
@@ -3294,12 +3287,12 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3294 | port->blocked_open++; | 3287 | port->blocked_open++; |
3295 | 3288 | ||
3296 | while (1) { | 3289 | while (1) { |
3297 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) | 3290 | if (C_BAUD(tty) && tty_port_initialized(port)) |
3298 | tty_port_raise_dtr_rts(port); | 3291 | tty_port_raise_dtr_rts(port); |
3299 | 3292 | ||
3300 | set_current_state(TASK_INTERRUPTIBLE); | 3293 | set_current_state(TASK_INTERRUPTIBLE); |
3301 | 3294 | ||
3302 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ | 3295 | if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { |
3303 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? | 3296 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
3304 | -EAGAIN : -ERESTARTSYS; | 3297 | -EAGAIN : -ERESTARTSYS; |
3305 | break; | 3298 | break; |
@@ -3328,7 +3321,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3328 | port->blocked_open--; | 3321 | port->blocked_open--; |
3329 | 3322 | ||
3330 | if (!retval) | 3323 | if (!retval) |
3331 | port->flags |= ASYNC_NORMAL_ACTIVE; | 3324 | tty_port_set_active(port, 1); |
3332 | 3325 | ||
3333 | DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); | 3326 | DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); |
3334 | return retval; | 3327 | return retval; |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 3f8968543af0..dec156586de1 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
@@ -812,7 +812,7 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
812 | goto cleanup; | 812 | goto cleanup; |
813 | 813 | ||
814 | mutex_lock(&info->port.mutex); | 814 | mutex_lock(&info->port.mutex); |
815 | if (info->port.flags & ASYNC_INITIALIZED) | 815 | if (tty_port_initialized(&info->port)) |
816 | wait_until_sent(tty, info->timeout); | 816 | wait_until_sent(tty, info->timeout); |
817 | 817 | ||
818 | flush_buffer(tty); | 818 | flush_buffer(tty); |
@@ -849,9 +849,9 @@ static void hangup(struct tty_struct *tty) | |||
849 | 849 | ||
850 | spin_lock_irqsave(&info->port.lock, flags); | 850 | spin_lock_irqsave(&info->port.lock, flags); |
851 | info->port.count = 0; | 851 | info->port.count = 0; |
852 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | ||
853 | info->port.tty = NULL; | 852 | info->port.tty = NULL; |
854 | spin_unlock_irqrestore(&info->port.lock, flags); | 853 | spin_unlock_irqrestore(&info->port.lock, flags); |
854 | tty_port_set_active(&info->port, 1); | ||
855 | mutex_unlock(&info->port.mutex); | 855 | mutex_unlock(&info->port.mutex); |
856 | 856 | ||
857 | wake_up_interruptible(&info->port.open_wait); | 857 | wake_up_interruptible(&info->port.open_wait); |
@@ -881,7 +881,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
881 | /* Handle transition away from B0 status */ | 881 | /* Handle transition away from B0 status */ |
882 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { | 882 | if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) { |
883 | info->serial_signals |= SerialSignal_DTR; | 883 | info->serial_signals |= SerialSignal_DTR; |
884 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) | 884 | if (!C_CRTSCTS(tty) || !tty_throttled(tty)) |
885 | info->serial_signals |= SerialSignal_RTS; | 885 | info->serial_signals |= SerialSignal_RTS; |
886 | spin_lock_irqsave(&info->lock,flags); | 886 | spin_lock_irqsave(&info->lock,flags); |
887 | set_signals(info); | 887 | set_signals(info); |
@@ -1061,7 +1061,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1061 | if (sanity_check(info, tty->name, "wait_until_sent")) | 1061 | if (sanity_check(info, tty->name, "wait_until_sent")) |
1062 | return; | 1062 | return; |
1063 | 1063 | ||
1064 | if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags)) | 1064 | if (!tty_port_initialized(&info->port)) |
1065 | goto exit; | 1065 | goto exit; |
1066 | 1066 | ||
1067 | orig_jiffies = jiffies; | 1067 | orig_jiffies = jiffies; |
@@ -1261,7 +1261,7 @@ static int ioctl(struct tty_struct *tty, | |||
1261 | 1261 | ||
1262 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1262 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1263 | (cmd != TIOCMIWAIT)) { | 1263 | (cmd != TIOCMIWAIT)) { |
1264 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1264 | if (tty_io_error(tty)) |
1265 | return -EIO; | 1265 | return -EIO; |
1266 | } | 1266 | } |
1267 | 1267 | ||
@@ -2463,7 +2463,7 @@ static void isr_io_pin( SLMP_INFO *info, u16 status ) | |||
2463 | wake_up_interruptible(&info->status_event_wait_q); | 2463 | wake_up_interruptible(&info->status_event_wait_q); |
2464 | wake_up_interruptible(&info->event_wait_q); | 2464 | wake_up_interruptible(&info->event_wait_q); |
2465 | 2465 | ||
2466 | if ( (info->port.flags & ASYNC_CHECK_CD) && | 2466 | if (tty_port_check_carrier(&info->port) && |
2467 | (status & MISCSTATUS_DCD_LATCHED) ) { | 2467 | (status & MISCSTATUS_DCD_LATCHED) ) { |
2468 | if ( debug_level >= DEBUG_LEVEL_ISR ) | 2468 | if ( debug_level >= DEBUG_LEVEL_ISR ) |
2469 | printk("%s CD now %s...", info->device_name, | 2469 | printk("%s CD now %s...", info->device_name, |
@@ -2636,7 +2636,7 @@ static int startup(SLMP_INFO * info) | |||
2636 | if ( debug_level >= DEBUG_LEVEL_INFO ) | 2636 | if ( debug_level >= DEBUG_LEVEL_INFO ) |
2637 | printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name); | 2637 | printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name); |
2638 | 2638 | ||
2639 | if (info->port.flags & ASYNC_INITIALIZED) | 2639 | if (tty_port_initialized(&info->port)) |
2640 | return 0; | 2640 | return 0; |
2641 | 2641 | ||
2642 | if (!info->tx_buf) { | 2642 | if (!info->tx_buf) { |
@@ -2662,7 +2662,7 @@ static int startup(SLMP_INFO * info) | |||
2662 | if (info->port.tty) | 2662 | if (info->port.tty) |
2663 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | 2663 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); |
2664 | 2664 | ||
2665 | info->port.flags |= ASYNC_INITIALIZED; | 2665 | tty_port_set_initialized(&info->port, 1); |
2666 | 2666 | ||
2667 | return 0; | 2667 | return 0; |
2668 | } | 2668 | } |
@@ -2673,7 +2673,7 @@ static void shutdown(SLMP_INFO * info) | |||
2673 | { | 2673 | { |
2674 | unsigned long flags; | 2674 | unsigned long flags; |
2675 | 2675 | ||
2676 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 2676 | if (!tty_port_initialized(&info->port)) |
2677 | return; | 2677 | return; |
2678 | 2678 | ||
2679 | if (debug_level >= DEBUG_LEVEL_INFO) | 2679 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -2705,7 +2705,7 @@ static void shutdown(SLMP_INFO * info) | |||
2705 | if (info->port.tty) | 2705 | if (info->port.tty) |
2706 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 2706 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); |
2707 | 2707 | ||
2708 | info->port.flags &= ~ASYNC_INITIALIZED; | 2708 | tty_port_set_initialized(&info->port, 0); |
2709 | } | 2709 | } |
2710 | 2710 | ||
2711 | static void program_hw(SLMP_INFO *info) | 2711 | static void program_hw(SLMP_INFO *info) |
@@ -2813,15 +2813,8 @@ static void change_params(SLMP_INFO *info) | |||
2813 | } | 2813 | } |
2814 | info->timeout += HZ/50; /* Add .02 seconds of slop */ | 2814 | info->timeout += HZ/50; /* Add .02 seconds of slop */ |
2815 | 2815 | ||
2816 | if (cflag & CRTSCTS) | 2816 | tty_port_set_cts_flow(&info->port, cflag & CRTSCTS); |
2817 | info->port.flags |= ASYNC_CTS_FLOW; | 2817 | tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL); |
2818 | else | ||
2819 | info->port.flags &= ~ASYNC_CTS_FLOW; | ||
2820 | |||
2821 | if (cflag & CLOCAL) | ||
2822 | info->port.flags &= ~ASYNC_CHECK_CD; | ||
2823 | else | ||
2824 | info->port.flags |= ASYNC_CHECK_CD; | ||
2825 | 2818 | ||
2826 | /* process tty input control flags */ | 2819 | /* process tty input control flags */ |
2827 | 2820 | ||
@@ -3285,10 +3278,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3285 | printk("%s(%d):%s block_til_ready()\n", | 3278 | printk("%s(%d):%s block_til_ready()\n", |
3286 | __FILE__,__LINE__, tty->driver->name ); | 3279 | __FILE__,__LINE__, tty->driver->name ); |
3287 | 3280 | ||
3288 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ | 3281 | if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { |
3289 | /* nonblock mode is set or port is not enabled */ | 3282 | /* nonblock mode is set or port is not enabled */ |
3290 | /* just verify that callout device is not active */ | 3283 | /* just verify that callout device is not active */ |
3291 | port->flags |= ASYNC_NORMAL_ACTIVE; | 3284 | tty_port_set_active(port, 1); |
3292 | return 0; | 3285 | return 0; |
3293 | } | 3286 | } |
3294 | 3287 | ||
@@ -3315,12 +3308,12 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3315 | port->blocked_open++; | 3308 | port->blocked_open++; |
3316 | 3309 | ||
3317 | while (1) { | 3310 | while (1) { |
3318 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) | 3311 | if (C_BAUD(tty) && tty_port_initialized(port)) |
3319 | tty_port_raise_dtr_rts(port); | 3312 | tty_port_raise_dtr_rts(port); |
3320 | 3313 | ||
3321 | set_current_state(TASK_INTERRUPTIBLE); | 3314 | set_current_state(TASK_INTERRUPTIBLE); |
3322 | 3315 | ||
3323 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ | 3316 | if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { |
3324 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? | 3317 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
3325 | -EAGAIN : -ERESTARTSYS; | 3318 | -EAGAIN : -ERESTARTSYS; |
3326 | break; | 3319 | break; |
@@ -3355,7 +3348,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3355 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3348 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3356 | 3349 | ||
3357 | if (!retval) | 3350 | if (!retval) |
3358 | port->flags |= ASYNC_NORMAL_ACTIVE; | 3351 | tty_port_set_active(port, 1); |
3359 | 3352 | ||
3360 | return retval; | 3353 | return retval; |
3361 | } | 3354 | } |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index a946e49a2626..aa80dc94ddc2 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -37,29 +37,6 @@ | |||
37 | 37 | ||
38 | #define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) | 38 | #define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) |
39 | 39 | ||
40 | /* | ||
41 | * If all tty flip buffers have been processed by flush_to_ldisc() or | ||
42 | * dropped by tty_buffer_flush(), check if the linked pty has been closed. | ||
43 | * If so, wake the reader/poll to process | ||
44 | */ | ||
45 | static inline void check_other_closed(struct tty_struct *tty) | ||
46 | { | ||
47 | unsigned long flags, old; | ||
48 | |||
49 | /* transition from TTY_OTHER_CLOSED => TTY_OTHER_DONE must be atomic */ | ||
50 | for (flags = ACCESS_ONCE(tty->flags); | ||
51 | test_bit(TTY_OTHER_CLOSED, &flags); | ||
52 | ) { | ||
53 | old = flags; | ||
54 | __set_bit(TTY_OTHER_DONE, &flags); | ||
55 | flags = cmpxchg(&tty->flags, old, flags); | ||
56 | if (old == flags) { | ||
57 | wake_up_interruptible(&tty->read_wait); | ||
58 | break; | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | |||
63 | /** | 40 | /** |
64 | * tty_buffer_lock_exclusive - gain exclusive access to buffer | 41 | * tty_buffer_lock_exclusive - gain exclusive access to buffer |
65 | * tty_buffer_unlock_exclusive - release exclusive access | 42 | * tty_buffer_unlock_exclusive - release exclusive access |
@@ -254,8 +231,6 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld) | |||
254 | if (ld && ld->ops->flush_buffer) | 231 | if (ld && ld->ops->flush_buffer) |
255 | ld->ops->flush_buffer(tty); | 232 | ld->ops->flush_buffer(tty); |
256 | 233 | ||
257 | check_other_closed(tty); | ||
258 | |||
259 | atomic_dec(&buf->priority); | 234 | atomic_dec(&buf->priority); |
260 | mutex_unlock(&buf->lock); | 235 | mutex_unlock(&buf->lock); |
261 | } | 236 | } |
@@ -522,10 +497,8 @@ static void flush_to_ldisc(struct work_struct *work) | |||
522 | */ | 497 | */ |
523 | count = smp_load_acquire(&head->commit) - head->read; | 498 | count = smp_load_acquire(&head->commit) - head->read; |
524 | if (!count) { | 499 | if (!count) { |
525 | if (next == NULL) { | 500 | if (next == NULL) |
526 | check_other_closed(tty); | ||
527 | break; | 501 | break; |
528 | } | ||
529 | buf->head = next; | 502 | buf->head = next; |
530 | tty_buffer_free(port, head); | 503 | tty_buffer_free(port, head); |
531 | continue; | 504 | continue; |
@@ -614,3 +587,8 @@ bool tty_buffer_cancel_work(struct tty_port *port) | |||
614 | { | 587 | { |
615 | return cancel_work_sync(&port->buf.work); | 588 | return cancel_work_sync(&port->buf.work); |
616 | } | 589 | } |
590 | |||
591 | void tty_buffer_flush_work(struct tty_port *port) | ||
592 | { | ||
593 | flush_work(&port->buf.work); | ||
594 | } | ||
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 24d5491ef0da..734a635e7363 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -230,9 +230,6 @@ static void tty_del_file(struct file *file) | |||
230 | tty_free_file(file); | 230 | tty_free_file(file); |
231 | } | 231 | } |
232 | 232 | ||
233 | |||
234 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) | ||
235 | |||
236 | /** | 233 | /** |
237 | * tty_name - return tty naming | 234 | * tty_name - return tty naming |
238 | * @tty: tty structure | 235 | * @tty: tty structure |
@@ -1070,7 +1067,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
1070 | 1067 | ||
1071 | if (tty_paranoia_check(tty, inode, "tty_read")) | 1068 | if (tty_paranoia_check(tty, inode, "tty_read")) |
1072 | return -EIO; | 1069 | return -EIO; |
1073 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) | 1070 | if (!tty || tty_io_error(tty)) |
1074 | return -EIO; | 1071 | return -EIO; |
1075 | 1072 | ||
1076 | /* We want to wait for the line discipline to sort out in this | 1073 | /* We want to wait for the line discipline to sort out in this |
@@ -1245,8 +1242,7 @@ static ssize_t tty_write(struct file *file, const char __user *buf, | |||
1245 | 1242 | ||
1246 | if (tty_paranoia_check(tty, file_inode(file), "tty_write")) | 1243 | if (tty_paranoia_check(tty, file_inode(file), "tty_write")) |
1247 | return -EIO; | 1244 | return -EIO; |
1248 | if (!tty || !tty->ops->write || | 1245 | if (!tty || !tty->ops->write || tty_io_error(tty)) |
1249 | (test_bit(TTY_IO_ERROR, &tty->flags))) | ||
1250 | return -EIO; | 1246 | return -EIO; |
1251 | /* Short term debug to catch buggy drivers */ | 1247 | /* Short term debug to catch buggy drivers */ |
1252 | if (tty->ops->write_room == NULL) | 1248 | if (tty->ops->write_room == NULL) |
@@ -1964,7 +1960,6 @@ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) | |||
1964 | * tty_lookup_driver - lookup a tty driver for a given device file | 1960 | * tty_lookup_driver - lookup a tty driver for a given device file |
1965 | * @device: device number | 1961 | * @device: device number |
1966 | * @filp: file pointer to tty | 1962 | * @filp: file pointer to tty |
1967 | * @noctty: set if the device should not become a controlling tty | ||
1968 | * @index: index for the device in the @return driver | 1963 | * @index: index for the device in the @return driver |
1969 | * @return: driver for this inode (with increased refcount) | 1964 | * @return: driver for this inode (with increased refcount) |
1970 | * | 1965 | * |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 23bf5bb1d8bf..bf36ac9aee41 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -158,7 +158,7 @@ int tty_throttle_safe(struct tty_struct *tty) | |||
158 | int ret = 0; | 158 | int ret = 0; |
159 | 159 | ||
160 | mutex_lock(&tty->throttle_mutex); | 160 | mutex_lock(&tty->throttle_mutex); |
161 | if (!test_bit(TTY_THROTTLED, &tty->flags)) { | 161 | if (!tty_throttled(tty)) { |
162 | if (tty->flow_change != TTY_THROTTLE_SAFE) | 162 | if (tty->flow_change != TTY_THROTTLE_SAFE) |
163 | ret = 1; | 163 | ret = 1; |
164 | else { | 164 | else { |
@@ -189,7 +189,7 @@ int tty_unthrottle_safe(struct tty_struct *tty) | |||
189 | int ret = 0; | 189 | int ret = 0; |
190 | 190 | ||
191 | mutex_lock(&tty->throttle_mutex); | 191 | mutex_lock(&tty->throttle_mutex); |
192 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 192 | if (tty_throttled(tty)) { |
193 | if (tty->flow_change != TTY_UNTHROTTLE_SAFE) | 193 | if (tty->flow_change != TTY_UNTHROTTLE_SAFE) |
194 | ret = 1; | 194 | ret = 1; |
195 | else { | 195 | else { |
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index dbcca30a54b1..c3f9d93ba227 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c | |||
@@ -204,7 +204,8 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty) | |||
204 | if (port->console) | 204 | if (port->console) |
205 | goto out; | 205 | goto out; |
206 | 206 | ||
207 | if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { | 207 | if (tty_port_initialized(port)) { |
208 | tty_port_set_initialized(port, 0); | ||
208 | /* | 209 | /* |
209 | * Drop DTR/RTS if HUPCL is set. This causes any attached | 210 | * Drop DTR/RTS if HUPCL is set. This causes any attached |
210 | * modem to hang up the line. | 211 | * modem to hang up the line. |
@@ -236,12 +237,12 @@ void tty_port_hangup(struct tty_port *port) | |||
236 | 237 | ||
237 | spin_lock_irqsave(&port->lock, flags); | 238 | spin_lock_irqsave(&port->lock, flags); |
238 | port->count = 0; | 239 | port->count = 0; |
239 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
240 | tty = port->tty; | 240 | tty = port->tty; |
241 | if (tty) | 241 | if (tty) |
242 | set_bit(TTY_IO_ERROR, &tty->flags); | 242 | set_bit(TTY_IO_ERROR, &tty->flags); |
243 | port->tty = NULL; | 243 | port->tty = NULL; |
244 | spin_unlock_irqrestore(&port->lock, flags); | 244 | spin_unlock_irqrestore(&port->lock, flags); |
245 | tty_port_set_active(port, 0); | ||
245 | tty_port_shutdown(port, tty); | 246 | tty_port_shutdown(port, tty); |
246 | tty_kref_put(tty); | 247 | tty_kref_put(tty); |
247 | wake_up_interruptible(&port->open_wait); | 248 | wake_up_interruptible(&port->open_wait); |
@@ -364,15 +365,15 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
364 | 365 | ||
365 | /* if non-blocking mode is set we can pass directly to open unless | 366 | /* if non-blocking mode is set we can pass directly to open unless |
366 | the port has just hung up or is in another error state */ | 367 | the port has just hung up or is in another error state */ |
367 | if (tty->flags & (1 << TTY_IO_ERROR)) { | 368 | if (tty_io_error(tty)) { |
368 | port->flags |= ASYNC_NORMAL_ACTIVE; | 369 | tty_port_set_active(port, 1); |
369 | return 0; | 370 | return 0; |
370 | } | 371 | } |
371 | if (filp->f_flags & O_NONBLOCK) { | 372 | if (filp->f_flags & O_NONBLOCK) { |
372 | /* Indicate we are open */ | 373 | /* Indicate we are open */ |
373 | if (C_BAUD(tty)) | 374 | if (C_BAUD(tty)) |
374 | tty_port_raise_dtr_rts(port); | 375 | tty_port_raise_dtr_rts(port); |
375 | port->flags |= ASYNC_NORMAL_ACTIVE; | 376 | tty_port_set_active(port, 1); |
376 | return 0; | 377 | return 0; |
377 | } | 378 | } |
378 | 379 | ||
@@ -393,13 +394,13 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
393 | 394 | ||
394 | while (1) { | 395 | while (1) { |
395 | /* Indicate we are open */ | 396 | /* Indicate we are open */ |
396 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) | 397 | if (C_BAUD(tty) && tty_port_initialized(port)) |
397 | tty_port_raise_dtr_rts(port); | 398 | tty_port_raise_dtr_rts(port); |
398 | 399 | ||
399 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); | 400 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); |
400 | /* Check for a hangup or uninitialised port. | 401 | /* Check for a hangup or uninitialised port. |
401 | Return accordingly */ | 402 | Return accordingly */ |
402 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { | 403 | if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { |
403 | if (port->flags & ASYNC_HUP_NOTIFY) | 404 | if (port->flags & ASYNC_HUP_NOTIFY) |
404 | retval = -EAGAIN; | 405 | retval = -EAGAIN; |
405 | else | 406 | else |
@@ -430,9 +431,9 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
430 | if (!tty_hung_up_p(filp)) | 431 | if (!tty_hung_up_p(filp)) |
431 | port->count++; | 432 | port->count++; |
432 | port->blocked_open--; | 433 | port->blocked_open--; |
433 | if (retval == 0) | ||
434 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
435 | spin_unlock_irqrestore(&port->lock, flags); | 434 | spin_unlock_irqrestore(&port->lock, flags); |
435 | if (retval == 0) | ||
436 | tty_port_set_active(port, 1); | ||
436 | return retval; | 437 | return retval; |
437 | } | 438 | } |
438 | EXPORT_SYMBOL(tty_port_block_til_ready); | 439 | EXPORT_SYMBOL(tty_port_block_til_ready); |
@@ -480,7 +481,7 @@ int tty_port_close_start(struct tty_port *port, | |||
480 | 481 | ||
481 | tty->closing = 1; | 482 | tty->closing = 1; |
482 | 483 | ||
483 | if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { | 484 | if (tty_port_initialized(port)) { |
484 | /* Don't block on a stalled port, just pull the chain */ | 485 | /* Don't block on a stalled port, just pull the chain */ |
485 | if (tty->flow_stopped) | 486 | if (tty->flow_stopped) |
486 | tty_driver_flush_buffer(tty); | 487 | tty_driver_flush_buffer(tty); |
@@ -514,8 +515,8 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) | |||
514 | spin_lock_irqsave(&port->lock, flags); | 515 | spin_lock_irqsave(&port->lock, flags); |
515 | wake_up_interruptible(&port->open_wait); | 516 | wake_up_interruptible(&port->open_wait); |
516 | } | 517 | } |
517 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
518 | spin_unlock_irqrestore(&port->lock, flags); | 518 | spin_unlock_irqrestore(&port->lock, flags); |
519 | tty_port_set_active(port, 0); | ||
519 | } | 520 | } |
520 | EXPORT_SYMBOL(tty_port_close_end); | 521 | EXPORT_SYMBOL(tty_port_close_end); |
521 | 522 | ||
@@ -578,7 +579,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty, | |||
578 | 579 | ||
579 | mutex_lock(&port->mutex); | 580 | mutex_lock(&port->mutex); |
580 | 581 | ||
581 | if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { | 582 | if (!tty_port_initialized(port)) { |
582 | clear_bit(TTY_IO_ERROR, &tty->flags); | 583 | clear_bit(TTY_IO_ERROR, &tty->flags); |
583 | if (port->ops->activate) { | 584 | if (port->ops->activate) { |
584 | int retval = port->ops->activate(port, tty); | 585 | int retval = port->ops->activate(port, tty); |
@@ -587,7 +588,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty, | |||
587 | return retval; | 588 | return retval; |
588 | } | 589 | } |
589 | } | 590 | } |
590 | set_bit(ASYNCB_INITIALIZED, &port->flags); | 591 | tty_port_set_initialized(port, 1); |
591 | } | 592 | } |
592 | mutex_unlock(&port->mutex); | 593 | mutex_unlock(&port->mutex); |
593 | return tty_port_block_til_ready(port, tty, filp); | 594 | return tty_port_block_til_ready(port, tty, filp); |
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 4dd9dd2270a0..368ce1803e8f 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c | |||
@@ -354,7 +354,7 @@ int paste_selection(struct tty_struct *tty) | |||
354 | add_wait_queue(&vc->paste_wait, &wait); | 354 | add_wait_queue(&vc->paste_wait, &wait); |
355 | while (sel_buffer && sel_buffer_lth > pasted) { | 355 | while (sel_buffer && sel_buffer_lth > pasted) { |
356 | set_current_state(TASK_INTERRUPTIBLE); | 356 | set_current_state(TASK_INTERRUPTIBLE); |
357 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 357 | if (tty_throttled(tty)) { |
358 | schedule(); | 358 | schedule(); |
359 | continue; | 359 | continue; |
360 | } | 360 | } |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 3e3c7575e92d..dc125322f48f 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -760,50 +760,54 @@ static void visual_init(struct vc_data *vc, int num, int init) | |||
760 | 760 | ||
761 | int vc_allocate(unsigned int currcons) /* return 0 on success */ | 761 | int vc_allocate(unsigned int currcons) /* return 0 on success */ |
762 | { | 762 | { |
763 | struct vt_notifier_param param; | ||
764 | struct vc_data *vc; | ||
765 | |||
763 | WARN_CONSOLE_UNLOCKED(); | 766 | WARN_CONSOLE_UNLOCKED(); |
764 | 767 | ||
765 | if (currcons >= MAX_NR_CONSOLES) | 768 | if (currcons >= MAX_NR_CONSOLES) |
766 | return -ENXIO; | 769 | return -ENXIO; |
767 | if (!vc_cons[currcons].d) { | 770 | |
768 | struct vc_data *vc; | 771 | if (vc_cons[currcons].d) |
769 | struct vt_notifier_param param; | 772 | return 0; |
770 | 773 | ||
771 | /* prevent users from taking too much memory */ | 774 | /* due to the granularity of kmalloc, we waste some memory here */ |
772 | if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE)) | 775 | /* the alloc is done in two steps, to optimize the common situation |
773 | return -EPERM; | 776 | of a 25x80 console (structsize=216, screenbuf_size=4000) */ |
774 | 777 | /* although the numbers above are not valid since long ago, the | |
775 | /* due to the granularity of kmalloc, we waste some memory here */ | 778 | point is still up-to-date and the comment still has its value |
776 | /* the alloc is done in two steps, to optimize the common situation | 779 | even if only as a historical artifact. --mj, July 1998 */ |
777 | of a 25x80 console (structsize=216, screenbuf_size=4000) */ | 780 | param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL); |
778 | /* although the numbers above are not valid since long ago, the | 781 | if (!vc) |
779 | point is still up-to-date and the comment still has its value | ||
780 | even if only as a historical artifact. --mj, July 1998 */ | ||
781 | param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL); | ||
782 | if (!vc) | ||
783 | return -ENOMEM; | 782 | return -ENOMEM; |
784 | vc_cons[currcons].d = vc; | 783 | |
785 | tty_port_init(&vc->port); | 784 | vc_cons[currcons].d = vc; |
786 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); | 785 | tty_port_init(&vc->port); |
787 | visual_init(vc, currcons, 1); | 786 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); |
788 | if (!*vc->vc_uni_pagedir_loc) | 787 | |
788 | visual_init(vc, currcons, 1); | ||
789 | |||
790 | if (!*vc->vc_uni_pagedir_loc) | ||
789 | con_set_default_unimap(vc); | 791 | con_set_default_unimap(vc); |
790 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); | ||
791 | if (!vc->vc_screenbuf) { | ||
792 | kfree(vc); | ||
793 | vc_cons[currcons].d = NULL; | ||
794 | return -ENOMEM; | ||
795 | } | ||
796 | 792 | ||
797 | /* If no drivers have overridden us and the user didn't pass a | 793 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); |
798 | boot option, default to displaying the cursor */ | 794 | if (!vc->vc_screenbuf) |
799 | if (global_cursor_default == -1) | 795 | goto err_free; |
800 | global_cursor_default = 1; | 796 | |
797 | /* If no drivers have overridden us and the user didn't pass a | ||
798 | boot option, default to displaying the cursor */ | ||
799 | if (global_cursor_default == -1) | ||
800 | global_cursor_default = 1; | ||
801 | |||
802 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); | ||
803 | vcs_make_sysfs(currcons); | ||
804 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); | ||
801 | 805 | ||
802 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); | ||
803 | vcs_make_sysfs(currcons); | ||
804 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); | ||
805 | } | ||
806 | return 0; | 806 | return 0; |
807 | err_free: | ||
808 | kfree(vc); | ||
809 | vc_cons[currcons].d = NULL; | ||
810 | return -ENOMEM; | ||
807 | } | 811 | } |
808 | 812 | ||
809 | static inline int resize_screen(struct vc_data *vc, int width, int height, | 813 | static inline int resize_screen(struct vc_data *vc, int width, int height, |
@@ -1035,20 +1039,27 @@ struct vc_data *vc_deallocate(unsigned int currcons) | |||
1035 | #define VT100ID "\033[?1;2c" | 1039 | #define VT100ID "\033[?1;2c" |
1036 | #define VT102ID "\033[?6c" | 1040 | #define VT102ID "\033[?6c" |
1037 | 1041 | ||
1038 | unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, | 1042 | const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, |
1039 | 8,12,10,14, 9,13,11,15 }; | 1043 | 8,12,10,14, 9,13,11,15 }; |
1040 | 1044 | ||
1041 | /* the default colour table, for VGA+ colour systems */ | 1045 | /* the default colour table, for VGA+ colour systems */ |
1042 | int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa, | 1046 | unsigned char default_red[] = { |
1043 | 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff}; | 1047 | 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, |
1044 | int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, | 1048 | 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff |
1045 | 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff}; | 1049 | }; |
1046 | int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, | 1050 | module_param_array(default_red, byte, NULL, S_IRUGO | S_IWUSR); |
1047 | 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; | ||
1048 | 1051 | ||
1049 | module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR); | 1052 | unsigned char default_grn[] = { |
1050 | module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR); | 1053 | 0x00, 0x00, 0xaa, 0x55, 0x00, 0x00, 0xaa, 0xaa, |
1051 | module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR); | 1054 | 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, 0xff, 0xff |
1055 | }; | ||
1056 | module_param_array(default_grn, byte, NULL, S_IRUGO | S_IWUSR); | ||
1057 | |||
1058 | unsigned char default_blu[] = { | ||
1059 | 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, | ||
1060 | 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff | ||
1061 | }; | ||
1062 | module_param_array(default_blu, byte, NULL, S_IRUGO | S_IWUSR); | ||
1052 | 1063 | ||
1053 | /* | 1064 | /* |
1054 | * gotoxy() must verify all boundaries, because the arguments | 1065 | * gotoxy() must verify all boundaries, because the arguments |
@@ -3564,7 +3575,7 @@ static int do_register_con_driver(const struct consw *csw, int first, int last) | |||
3564 | struct module *owner = csw->owner; | 3575 | struct module *owner = csw->owner; |
3565 | struct con_driver *con_driver; | 3576 | struct con_driver *con_driver; |
3566 | const char *desc; | 3577 | const char *desc; |
3567 | int i, retval = 0; | 3578 | int i, retval; |
3568 | 3579 | ||
3569 | WARN_CONSOLE_UNLOCKED(); | 3580 | WARN_CONSOLE_UNLOCKED(); |
3570 | 3581 | ||
@@ -3575,17 +3586,17 @@ static int do_register_con_driver(const struct consw *csw, int first, int last) | |||
3575 | con_driver = ®istered_con_driver[i]; | 3586 | con_driver = ®istered_con_driver[i]; |
3576 | 3587 | ||
3577 | /* already registered */ | 3588 | /* already registered */ |
3578 | if (con_driver->con == csw) | 3589 | if (con_driver->con == csw) { |
3579 | retval = -EBUSY; | 3590 | retval = -EBUSY; |
3591 | goto err; | ||
3592 | } | ||
3580 | } | 3593 | } |
3581 | 3594 | ||
3582 | if (retval) | ||
3583 | goto err; | ||
3584 | |||
3585 | desc = csw->con_startup(); | 3595 | desc = csw->con_startup(); |
3586 | 3596 | if (!desc) { | |
3587 | if (!desc) | 3597 | retval = -ENODEV; |
3588 | goto err; | 3598 | goto err; |
3599 | } | ||
3589 | 3600 | ||
3590 | retval = -EINVAL; | 3601 | retval = -EINVAL; |
3591 | 3602 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index a6c4a1b895bd..94a14f5dc4d4 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1680,7 +1680,7 @@ static int acm_resume(struct usb_interface *intf) | |||
1680 | if (--acm->susp_count) | 1680 | if (--acm->susp_count) |
1681 | goto out; | 1681 | goto out; |
1682 | 1682 | ||
1683 | if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) { | 1683 | if (tty_port_initialized(&acm->port)) { |
1684 | rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC); | 1684 | rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC); |
1685 | 1685 | ||
1686 | for (;;) { | 1686 | for (;;) { |
@@ -1710,7 +1710,7 @@ static int acm_reset_resume(struct usb_interface *intf) | |||
1710 | { | 1710 | { |
1711 | struct acm *acm = usb_get_intfdata(intf); | 1711 | struct acm *acm = usb_get_intfdata(intf); |
1712 | 1712 | ||
1713 | if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) | 1713 | if (tty_port_initialized(&acm->port)) |
1714 | tty_port_tty_hangup(&acm->port, false); | 1714 | tty_port_tty_hangup(&acm->port, false); |
1715 | 1715 | ||
1716 | return acm_resume(intf); | 1716 | return acm_resume(intf); |
diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 6af145f2a99d..3580f198df8b 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c | |||
@@ -512,7 +512,7 @@ static void gs_rx_push(unsigned long _port) | |||
512 | req = list_first_entry(queue, struct usb_request, list); | 512 | req = list_first_entry(queue, struct usb_request, list); |
513 | 513 | ||
514 | /* leave data queued if tty was rx throttled */ | 514 | /* leave data queued if tty was rx throttled */ |
515 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) | 515 | if (tty && tty_throttled(tty)) |
516 | break; | 516 | break; |
517 | 517 | ||
518 | switch (req->status) { | 518 | switch (req->status) { |
@@ -579,7 +579,7 @@ static void gs_rx_push(unsigned long _port) | |||
579 | * from starving ... but it's not clear that case ever happens. | 579 | * from starving ... but it's not clear that case ever happens. |
580 | */ | 580 | */ |
581 | if (!list_empty(queue) && tty) { | 581 | if (!list_empty(queue) && tty) { |
582 | if (!test_bit(TTY_THROTTLED, &tty->flags)) { | 582 | if (!tty_throttled(tty)) { |
583 | if (do_push) | 583 | if (do_push) |
584 | tasklet_schedule(&port->push); | 584 | tasklet_schedule(&port->push); |
585 | else | 585 | else |
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index ace343088915..afa853209f1d 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c | |||
@@ -601,7 +601,7 @@ sisusbcon_save_screen(struct vc_data *c) | |||
601 | 601 | ||
602 | /* interface routine */ | 602 | /* interface routine */ |
603 | static int | 603 | static int |
604 | sisusbcon_set_palette(struct vc_data *c, unsigned char *table) | 604 | sisusbcon_set_palette(struct vc_data *c, const unsigned char *table) |
605 | { | 605 | { |
606 | struct sisusb_usb_data *sisusb; | 606 | struct sisusb_usb_data *sisusb; |
607 | int i, j; | 607 | int i, j; |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index a66b01bb1fa1..8967715fe6fc 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -127,7 +127,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
127 | info->port = port; | 127 | info->port = port; |
128 | 128 | ||
129 | ++port->port.count; | 129 | ++port->port.count; |
130 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) { | 130 | if (!tty_port_initialized(&port->port)) { |
131 | if (serial->type->set_termios) { | 131 | if (serial->type->set_termios) { |
132 | /* | 132 | /* |
133 | * allocate a fake tty so the driver can initialize | 133 | * allocate a fake tty so the driver can initialize |
@@ -168,7 +168,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
168 | tty_port_tty_set(&port->port, NULL); | 168 | tty_port_tty_set(&port->port, NULL); |
169 | tty_kref_put(tty); | 169 | tty_kref_put(tty); |
170 | } | 170 | } |
171 | set_bit(ASYNCB_INITIALIZED, &port->port.flags); | 171 | tty_port_set_initialized(&port->port, 1); |
172 | } | 172 | } |
173 | /* Now that any required fake tty operations are completed restore | 173 | /* Now that any required fake tty operations are completed restore |
174 | * the tty port count */ | 174 | * the tty port count */ |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 16e8e37b3b36..6a1df9e824ca 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -699,8 +699,7 @@ static void digi_set_termios(struct tty_struct *tty, | |||
699 | /* don't set RTS if using hardware flow control */ | 699 | /* don't set RTS if using hardware flow control */ |
700 | /* and throttling input */ | 700 | /* and throttling input */ |
701 | modem_signals = TIOCM_DTR; | 701 | modem_signals = TIOCM_DTR; |
702 | if (!C_CRTSCTS(tty) || | 702 | if (!C_CRTSCTS(tty) || !tty_throttled(tty)) |
703 | !test_bit(TTY_THROTTLED, &tty->flags)) | ||
704 | modem_signals |= TIOCM_RTS; | 703 | modem_signals |= TIOCM_RTS; |
705 | digi_set_modem_signals(port, modem_signals, 1); | 704 | digi_set_modem_signals(port, modem_signals, 1); |
706 | } | 705 | } |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 54e170dd3dad..ae8c0365abd6 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -473,7 +473,7 @@ static bool usb_serial_generic_msr_changed(struct tty_struct *tty, | |||
473 | * Use tty-port initialised flag to detect all hangups including the | 473 | * Use tty-port initialised flag to detect all hangups including the |
474 | * one generated at USB-device disconnect. | 474 | * one generated at USB-device disconnect. |
475 | */ | 475 | */ |
476 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 476 | if (!tty_port_initialized(&port->port)) |
477 | return true; | 477 | return true; |
478 | 478 | ||
479 | spin_lock_irqsave(&port->lock, flags); | 479 | spin_lock_irqsave(&port->lock, flags); |
@@ -503,7 +503,7 @@ int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg) | |||
503 | 503 | ||
504 | ret = wait_event_interruptible(port->port.delta_msr_wait, | 504 | ret = wait_event_interruptible(port->port.delta_msr_wait, |
505 | usb_serial_generic_msr_changed(tty, arg, &cnow)); | 505 | usb_serial_generic_msr_changed(tty, arg, &cnow)); |
506 | if (!ret && !test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 506 | if (!ret && !tty_port_initialized(&port->port)) |
507 | ret = -EIO; | 507 | ret = -EIO; |
508 | 508 | ||
509 | return ret; | 509 | return ret; |
@@ -606,7 +606,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
606 | 606 | ||
607 | for (i = 0; i < serial->num_ports; i++) { | 607 | for (i = 0; i < serial->num_ports; i++) { |
608 | port = serial->port[i]; | 608 | port = serial->port[i]; |
609 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 609 | if (!tty_port_initialized(&port->port)) |
610 | continue; | 610 | continue; |
611 | 611 | ||
612 | if (port->bulk_in_size) { | 612 | if (port->bulk_in_size) { |
diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c index 31a8b47f1ac6..3722d6c1ba77 100644 --- a/drivers/usb/serial/mxuport.c +++ b/drivers/usb/serial/mxuport.c | |||
@@ -503,7 +503,7 @@ static void mxuport_process_read_urb_demux_data(struct urb *urb) | |||
503 | return; | 503 | return; |
504 | } | 504 | } |
505 | 505 | ||
506 | if (test_bit(ASYNCB_INITIALIZED, &demux_port->port.flags)) { | 506 | if (tty_port_initialized(&demux_port->port)) { |
507 | ch = data + HEADER_SIZE; | 507 | ch = data + HEADER_SIZE; |
508 | mxuport_process_read_urb_data(demux_port, ch, rcv_len); | 508 | mxuport_process_read_urb_data(demux_port, ch, rcv_len); |
509 | } else { | 509 | } else { |
@@ -544,7 +544,7 @@ static void mxuport_process_read_urb_demux_event(struct urb *urb) | |||
544 | } | 544 | } |
545 | 545 | ||
546 | demux_port = serial->port[rcv_port]; | 546 | demux_port = serial->port[rcv_port]; |
547 | if (test_bit(ASYNCB_INITIALIZED, &demux_port->port.flags)) { | 547 | if (tty_port_initialized(&demux_port->port)) { |
548 | ch = data + HEADER_SIZE; | 548 | ch = data + HEADER_SIZE; |
549 | rcv_event = get_unaligned_be16(data + 2); | 549 | rcv_event = get_unaligned_be16(data + 2); |
550 | mxuport_process_read_urb_event(demux_port, ch, | 550 | mxuport_process_read_urb_event(demux_port, ch, |
@@ -1339,7 +1339,7 @@ static int mxuport_resume(struct usb_serial *serial) | |||
1339 | 1339 | ||
1340 | for (i = 0; i < serial->num_ports; i++) { | 1340 | for (i = 0; i < serial->num_ports; i++) { |
1341 | port = serial->port[i]; | 1341 | port = serial->port[i]; |
1342 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 1342 | if (!tty_port_initialized(&port->port)) |
1343 | continue; | 1343 | continue; |
1344 | 1344 | ||
1345 | r = usb_serial_generic_write_start(port, GFP_NOIO); | 1345 | r = usb_serial_generic_write_start(port, GFP_NOIO); |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 07d1ecd564f7..e1994e264cc0 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -776,7 +776,7 @@ static void sierra_close(struct usb_serial_port *port) | |||
776 | 776 | ||
777 | /* | 777 | /* |
778 | * Need to take susp_lock to make sure port is not already being | 778 | * Need to take susp_lock to make sure port is not already being |
779 | * resumed, but no need to hold it due to ASYNC_INITIALIZED. | 779 | * resumed, but no need to hold it due to initialized |
780 | */ | 780 | */ |
781 | spin_lock_irq(&intfdata->susp_lock); | 781 | spin_lock_irq(&intfdata->susp_lock); |
782 | if (--intfdata->open_ports == 0) | 782 | if (--intfdata->open_ports == 0) |
@@ -1039,7 +1039,7 @@ static int sierra_resume(struct usb_serial *serial) | |||
1039 | for (i = 0; i < serial->num_ports; i++) { | 1039 | for (i = 0; i < serial->num_ports; i++) { |
1040 | port = serial->port[i]; | 1040 | port = serial->port[i]; |
1041 | 1041 | ||
1042 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 1042 | if (!tty_port_initialized(&port->port)) |
1043 | continue; | 1043 | continue; |
1044 | 1044 | ||
1045 | err = sierra_submit_delayed_urbs(port); | 1045 | err = sierra_submit_delayed_urbs(port); |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 46f1f13b41f1..3f253aec0c16 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -254,7 +254,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp) | |||
254 | * | 254 | * |
255 | * Shut down a USB serial port. Serialized against activate by the | 255 | * Shut down a USB serial port. Serialized against activate by the |
256 | * tport mutex and kept to matching open/close pairs | 256 | * tport mutex and kept to matching open/close pairs |
257 | * of calls by the ASYNCB_INITIALIZED flag. | 257 | * of calls by the initialized flag. |
258 | * | 258 | * |
259 | * Not called if tty is console. | 259 | * Not called if tty is console. |
260 | */ | 260 | */ |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index be9cb61b4d19..3dfdfc81254b 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -464,7 +464,7 @@ void usb_wwan_close(struct usb_serial_port *port) | |||
464 | 464 | ||
465 | /* | 465 | /* |
466 | * Need to take susp_lock to make sure port is not already being | 466 | * Need to take susp_lock to make sure port is not already being |
467 | * resumed, but no need to hold it due to ASYNC_INITIALIZED. | 467 | * resumed, but no need to hold it due to initialized |
468 | */ | 468 | */ |
469 | spin_lock_irq(&intfdata->susp_lock); | 469 | spin_lock_irq(&intfdata->susp_lock); |
470 | if (--intfdata->open_ports == 0) | 470 | if (--intfdata->open_ports == 0) |
@@ -682,7 +682,7 @@ int usb_wwan_resume(struct usb_serial *serial) | |||
682 | for (i = 0; i < serial->num_ports; i++) { | 682 | for (i = 0; i < serial->num_ports; i++) { |
683 | port = serial->port[i]; | 683 | port = serial->port[i]; |
684 | 684 | ||
685 | if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | 685 | if (!tty_port_initialized(&port->port)) |
686 | continue; | 686 | continue; |
687 | 687 | ||
688 | portdata = usb_get_serial_port_data(port); | 688 | portdata = usb_get_serial_port_data(port); |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 6e92917ba77a..afd3301ac40c 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -170,7 +170,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, | |||
170 | int height, int width); | 170 | int height, int width); |
171 | static int fbcon_switch(struct vc_data *vc); | 171 | static int fbcon_switch(struct vc_data *vc); |
172 | static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); | 172 | static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); |
173 | static int fbcon_set_palette(struct vc_data *vc, unsigned char *table); | 173 | static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table); |
174 | static int fbcon_scrolldelta(struct vc_data *vc, int lines); | 174 | static int fbcon_scrolldelta(struct vc_data *vc, int lines); |
175 | 175 | ||
176 | /* | 176 | /* |
@@ -2652,7 +2652,7 @@ static struct fb_cmap palette_cmap = { | |||
2652 | 0, 16, palette_red, palette_green, palette_blue, NULL | 2652 | 0, 16, palette_red, palette_green, palette_blue, NULL |
2653 | }; | 2653 | }; |
2654 | 2654 | ||
2655 | static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) | 2655 | static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table) |
2656 | { | 2656 | { |
2657 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | 2657 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
2658 | int i, j, k, depth; | 2658 | int i, j, k, depth; |
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 296e94561556..8edc062536a8 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c | |||
@@ -481,7 +481,7 @@ static int mdacon_switch(struct vc_data *c) | |||
481 | return 1; /* redrawing needed */ | 481 | return 1; /* redrawing needed */ |
482 | } | 482 | } |
483 | 483 | ||
484 | static int mdacon_set_palette(struct vc_data *c, unsigned char *table) | 484 | static int mdacon_set_palette(struct vc_data *c, const unsigned char *table) |
485 | { | 485 | { |
486 | return -EINVAL; | 486 | return -EINVAL; |
487 | } | 487 | } |
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index bb4e96255974..0553dfe684ef 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c | |||
@@ -574,7 +574,7 @@ static int newport_font_set(struct vc_data *vc, struct console_font *font, unsig | |||
574 | return newport_set_font(vc->vc_num, font); | 574 | return newport_set_font(vc->vc_num, font); |
575 | } | 575 | } |
576 | 576 | ||
577 | static int newport_set_palette(struct vc_data *vc, unsigned char *table) | 577 | static int newport_set_palette(struct vc_data *vc, const unsigned char *table) |
578 | { | 578 | { |
579 | return -EINVAL; | 579 | return -EINVAL; |
580 | } | 580 | } |
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 026fd1215933..e440c2d9fe7c 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c | |||
@@ -79,7 +79,7 @@ static const char *sticon_startup(void) | |||
79 | return "STI console"; | 79 | return "STI console"; |
80 | } | 80 | } |
81 | 81 | ||
82 | static int sticon_set_palette(struct vc_data *c, unsigned char *table) | 82 | static int sticon_set_palette(struct vc_data *c, const unsigned char *table) |
83 | { | 83 | { |
84 | return -EINVAL; | 84 | return -EINVAL; |
85 | } | 85 | } |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 517f565b65d7..8bf911002cba 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -80,7 +80,6 @@ static void vgacon_deinit(struct vc_data *c); | |||
80 | static void vgacon_cursor(struct vc_data *c, int mode); | 80 | static void vgacon_cursor(struct vc_data *c, int mode); |
81 | static int vgacon_switch(struct vc_data *c); | 81 | static int vgacon_switch(struct vc_data *c); |
82 | static int vgacon_blank(struct vc_data *c, int blank, int mode_switch); | 82 | static int vgacon_blank(struct vc_data *c, int blank, int mode_switch); |
83 | static int vgacon_set_palette(struct vc_data *vc, unsigned char *table); | ||
84 | static int vgacon_scrolldelta(struct vc_data *c, int lines); | 83 | static int vgacon_scrolldelta(struct vc_data *c, int lines); |
85 | static int vgacon_set_origin(struct vc_data *c); | 84 | static int vgacon_set_origin(struct vc_data *c); |
86 | static void vgacon_save_screen(struct vc_data *c); | 85 | static void vgacon_save_screen(struct vc_data *c); |
@@ -847,7 +846,7 @@ static int vgacon_switch(struct vc_data *c) | |||
847 | return 0; /* Redrawing not needed */ | 846 | return 0; /* Redrawing not needed */ |
848 | } | 847 | } |
849 | 848 | ||
850 | static void vga_set_palette(struct vc_data *vc, unsigned char *table) | 849 | static void vga_set_palette(struct vc_data *vc, const unsigned char *table) |
851 | { | 850 | { |
852 | int i, j; | 851 | int i, j; |
853 | 852 | ||
@@ -860,7 +859,7 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table) | |||
860 | } | 859 | } |
861 | } | 860 | } |
862 | 861 | ||
863 | static int vgacon_set_palette(struct vc_data *vc, unsigned char *table) | 862 | static int vgacon_set_palette(struct vc_data *vc, const unsigned char *table) |
864 | { | 863 | { |
865 | #ifdef CAN_LOAD_PALETTE | 864 | #ifdef CAN_LOAD_PALETTE |
866 | if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked | 865 | if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked |
diff --git a/include/linux/console.h b/include/linux/console.h index ea731af2451e..137ac1a1c16f 100644 --- a/include/linux/console.h +++ b/include/linux/console.h | |||
@@ -47,7 +47,7 @@ struct consw { | |||
47 | int (*con_font_copy)(struct vc_data *, int); | 47 | int (*con_font_copy)(struct vc_data *, int); |
48 | int (*con_resize)(struct vc_data *, unsigned int, unsigned int, | 48 | int (*con_resize)(struct vc_data *, unsigned int, unsigned int, |
49 | unsigned int); | 49 | unsigned int); |
50 | int (*con_set_palette)(struct vc_data *, unsigned char *); | 50 | int (*con_set_palette)(struct vc_data *, const unsigned char *); |
51 | int (*con_scrolldelta)(struct vc_data *, int); | 51 | int (*con_scrolldelta)(struct vc_data *, int); |
52 | int (*con_set_origin)(struct vc_data *); | 52 | int (*con_set_origin)(struct vc_data *); |
53 | void (*con_save_screen)(struct vc_data *); | 53 | void (*con_save_screen)(struct vc_data *); |
diff --git a/include/linux/selection.h b/include/linux/selection.h index 85193aa8c1e3..8e4624efdb6f 100644 --- a/include/linux/selection.h +++ b/include/linux/selection.h | |||
@@ -24,10 +24,10 @@ extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry); | |||
24 | 24 | ||
25 | extern int console_blanked; | 25 | extern int console_blanked; |
26 | 26 | ||
27 | extern unsigned char color_table[]; | 27 | extern const unsigned char color_table[]; |
28 | extern int default_red[]; | 28 | extern unsigned char default_red[]; |
29 | extern int default_grn[]; | 29 | extern unsigned char default_grn[]; |
30 | extern int default_blu[]; | 30 | extern unsigned char default_blu[]; |
31 | 31 | ||
32 | extern unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed); | 32 | extern unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed); |
33 | extern u16 screen_glyph(struct vc_data *vc, int offset); | 33 | extern u16 screen_glyph(struct vc_data *vc, int offset); |
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 434879759725..48ec7651989b 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h | |||
@@ -36,6 +36,7 @@ struct plat_serial8250_port { | |||
36 | void (*set_termios)(struct uart_port *, | 36 | void (*set_termios)(struct uart_port *, |
37 | struct ktermios *new, | 37 | struct ktermios *new, |
38 | struct ktermios *old); | 38 | struct ktermios *old); |
39 | unsigned int (*get_mctrl)(struct uart_port *); | ||
39 | int (*handle_irq)(struct uart_port *); | 40 | int (*handle_irq)(struct uart_port *); |
40 | void (*pm)(struct uart_port *, unsigned int state, | 41 | void (*pm)(struct uart_port *, unsigned int state, |
41 | unsigned old); | 42 | unsigned old); |
@@ -148,6 +149,7 @@ extern int early_serial8250_setup(struct earlycon_device *device, | |||
148 | const char *options); | 149 | const char *options); |
149 | extern void serial8250_do_set_termios(struct uart_port *port, | 150 | extern void serial8250_do_set_termios(struct uart_port *port, |
150 | struct ktermios *termios, struct ktermios *old); | 151 | struct ktermios *termios, struct ktermios *old); |
152 | extern unsigned int serial8250_do_get_mctrl(struct uart_port *port); | ||
151 | extern int serial8250_do_startup(struct uart_port *port); | 153 | extern int serial8250_do_startup(struct uart_port *port); |
152 | extern void serial8250_do_shutdown(struct uart_port *port); | 154 | extern void serial8250_do_shutdown(struct uart_port *port); |
153 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, | 155 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index cbfcf38e220d..a3d7c0d4a03e 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -123,6 +123,7 @@ struct uart_port { | |||
123 | void (*set_termios)(struct uart_port *, | 123 | void (*set_termios)(struct uart_port *, |
124 | struct ktermios *new, | 124 | struct ktermios *new, |
125 | struct ktermios *old); | 125 | struct ktermios *old); |
126 | unsigned int (*get_mctrl)(struct uart_port *); | ||
126 | void (*set_mctrl)(struct uart_port *, unsigned int); | 127 | void (*set_mctrl)(struct uart_port *, unsigned int); |
127 | int (*startup)(struct uart_port *port); | 128 | int (*startup)(struct uart_port *port); |
128 | void (*shutdown)(struct uart_port *port); | 129 | void (*shutdown)(struct uart_port *port); |
@@ -281,6 +282,8 @@ struct uart_state { | |||
281 | enum uart_pm_state pm_state; | 282 | enum uart_pm_state pm_state; |
282 | struct circ_buf xmit; | 283 | struct circ_buf xmit; |
283 | 284 | ||
285 | atomic_t refcount; | ||
286 | wait_queue_head_t remove_wait; | ||
284 | struct uart_port *uart_port; | 287 | struct uart_port *uart_port; |
285 | }; | 288 | }; |
286 | 289 | ||
diff --git a/include/linux/tty.h b/include/linux/tty.h index 17b247c94440..40144f382516 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -228,7 +228,8 @@ struct tty_port { | |||
228 | int count; /* Usage count */ | 228 | int count; /* Usage count */ |
229 | wait_queue_head_t open_wait; /* Open waiters */ | 229 | wait_queue_head_t open_wait; /* Open waiters */ |
230 | wait_queue_head_t delta_msr_wait; /* Modem status change */ | 230 | wait_queue_head_t delta_msr_wait; /* Modem status change */ |
231 | unsigned long flags; /* TTY flags ASY_*/ | 231 | unsigned long flags; /* User TTY flags ASYNC_ */ |
232 | unsigned long iflags; /* Internal flags TTY_PORT_ */ | ||
232 | unsigned char console:1, /* port is a console */ | 233 | unsigned char console:1, /* port is a console */ |
233 | low_latency:1; /* optional: tune for latency */ | 234 | low_latency:1; /* optional: tune for latency */ |
234 | struct mutex mutex; /* Locking */ | 235 | struct mutex mutex; /* Locking */ |
@@ -242,6 +243,18 @@ struct tty_port { | |||
242 | struct kref kref; /* Ref counter */ | 243 | struct kref kref; /* Ref counter */ |
243 | }; | 244 | }; |
244 | 245 | ||
246 | /* tty_port::iflags bits -- use atomic bit ops */ | ||
247 | #define TTY_PORT_INITIALIZED 0 /* device is initialized */ | ||
248 | #define TTY_PORT_SUSPENDED 1 /* device is suspended */ | ||
249 | #define TTY_PORT_ACTIVE 2 /* device is open */ | ||
250 | |||
251 | /* | ||
252 | * uart drivers: use the uart_port::status field and the UPSTAT_* defines | ||
253 | * for s/w-based flow control steering and carrier detection status | ||
254 | */ | ||
255 | #define TTY_PORT_CTS_FLOW 3 /* h/w flow control enabled */ | ||
256 | #define TTY_PORT_CHECK_CD 4 /* carrier detect enabled */ | ||
257 | |||
245 | /* | 258 | /* |
246 | * Where all of the state associated with a tty is kept while the tty | 259 | * Where all of the state associated with a tty is kept while the tty |
247 | * is open. Since the termios state should be kept even if the tty | 260 | * is open. Since the termios state should be kept even if the tty |
@@ -338,7 +351,6 @@ struct tty_file_private { | |||
338 | #define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */ | 351 | #define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */ |
339 | #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ | 352 | #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ |
340 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ | 353 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ |
341 | #define TTY_OTHER_DONE 6 /* Closed pty has completed input processing */ | ||
342 | #define TTY_LDISC_OPEN 11 /* Line discipline is open */ | 354 | #define TTY_LDISC_OPEN 11 /* Line discipline is open */ |
343 | #define TTY_PTY_LOCK 16 /* pty private */ | 355 | #define TTY_PTY_LOCK 16 /* pty private */ |
344 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ | 356 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ |
@@ -360,6 +372,16 @@ static inline void tty_set_flow_change(struct tty_struct *tty, int val) | |||
360 | smp_mb(); | 372 | smp_mb(); |
361 | } | 373 | } |
362 | 374 | ||
375 | static inline bool tty_io_error(struct tty_struct *tty) | ||
376 | { | ||
377 | return test_bit(TTY_IO_ERROR, &tty->flags); | ||
378 | } | ||
379 | |||
380 | static inline bool tty_throttled(struct tty_struct *tty) | ||
381 | { | ||
382 | return test_bit(TTY_THROTTLED, &tty->flags); | ||
383 | } | ||
384 | |||
363 | #ifdef CONFIG_TTY | 385 | #ifdef CONFIG_TTY |
364 | extern void console_init(void); | 386 | extern void console_init(void); |
365 | extern void tty_kref_put(struct tty_struct *tty); | 387 | extern void tty_kref_put(struct tty_struct *tty); |
@@ -459,6 +481,7 @@ extern void tty_buffer_init(struct tty_port *port); | |||
459 | extern void tty_buffer_set_lock_subclass(struct tty_port *port); | 481 | extern void tty_buffer_set_lock_subclass(struct tty_port *port); |
460 | extern bool tty_buffer_restart_work(struct tty_port *port); | 482 | extern bool tty_buffer_restart_work(struct tty_port *port); |
461 | extern bool tty_buffer_cancel_work(struct tty_port *port); | 483 | extern bool tty_buffer_cancel_work(struct tty_port *port); |
484 | extern void tty_buffer_flush_work(struct tty_port *port); | ||
462 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); | 485 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); |
463 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); | 486 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); |
464 | extern void tty_termios_encode_baud_rate(struct ktermios *termios, | 487 | extern void tty_termios_encode_baud_rate(struct ktermios *termios, |
@@ -539,7 +562,67 @@ static inline struct tty_port *tty_port_get(struct tty_port *port) | |||
539 | /* If the cts flow control is enabled, return true. */ | 562 | /* If the cts flow control is enabled, return true. */ |
540 | static inline bool tty_port_cts_enabled(struct tty_port *port) | 563 | static inline bool tty_port_cts_enabled(struct tty_port *port) |
541 | { | 564 | { |
542 | return port->flags & ASYNC_CTS_FLOW; | 565 | return test_bit(TTY_PORT_CTS_FLOW, &port->iflags); |
566 | } | ||
567 | |||
568 | static inline void tty_port_set_cts_flow(struct tty_port *port, bool val) | ||
569 | { | ||
570 | if (val) | ||
571 | set_bit(TTY_PORT_CTS_FLOW, &port->iflags); | ||
572 | else | ||
573 | clear_bit(TTY_PORT_CTS_FLOW, &port->iflags); | ||
574 | } | ||
575 | |||
576 | static inline bool tty_port_active(struct tty_port *port) | ||
577 | { | ||
578 | return test_bit(TTY_PORT_ACTIVE, &port->iflags); | ||
579 | } | ||
580 | |||
581 | static inline void tty_port_set_active(struct tty_port *port, bool val) | ||
582 | { | ||
583 | if (val) | ||
584 | set_bit(TTY_PORT_ACTIVE, &port->iflags); | ||
585 | else | ||
586 | clear_bit(TTY_PORT_ACTIVE, &port->iflags); | ||
587 | } | ||
588 | |||
589 | static inline bool tty_port_check_carrier(struct tty_port *port) | ||
590 | { | ||
591 | return test_bit(TTY_PORT_CHECK_CD, &port->iflags); | ||
592 | } | ||
593 | |||
594 | static inline void tty_port_set_check_carrier(struct tty_port *port, bool val) | ||
595 | { | ||
596 | if (val) | ||
597 | set_bit(TTY_PORT_CHECK_CD, &port->iflags); | ||
598 | else | ||
599 | clear_bit(TTY_PORT_CHECK_CD, &port->iflags); | ||
600 | } | ||
601 | |||
602 | static inline bool tty_port_suspended(struct tty_port *port) | ||
603 | { | ||
604 | return test_bit(TTY_PORT_SUSPENDED, &port->iflags); | ||
605 | } | ||
606 | |||
607 | static inline void tty_port_set_suspended(struct tty_port *port, bool val) | ||
608 | { | ||
609 | if (val) | ||
610 | set_bit(TTY_PORT_SUSPENDED, &port->iflags); | ||
611 | else | ||
612 | clear_bit(TTY_PORT_SUSPENDED, &port->iflags); | ||
613 | } | ||
614 | |||
615 | static inline bool tty_port_initialized(struct tty_port *port) | ||
616 | { | ||
617 | return test_bit(TTY_PORT_INITIALIZED, &port->iflags); | ||
618 | } | ||
619 | |||
620 | static inline void tty_port_set_initialized(struct tty_port *port, bool val) | ||
621 | { | ||
622 | if (val) | ||
623 | set_bit(TTY_PORT_INITIALIZED, &port->iflags); | ||
624 | else | ||
625 | clear_bit(TTY_PORT_INITIALIZED, &port->iflags); | ||
543 | } | 626 | } |
544 | 627 | ||
545 | extern struct tty_struct *tty_port_tty_get(struct tty_port *port); | 628 | extern struct tty_struct *tty_port_tty_get(struct tty_port *port); |
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 24da334af7f1..99dbed8a8874 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h | |||
@@ -267,4 +267,7 @@ | |||
267 | /* Microchip PIC32 UART */ | 267 | /* Microchip PIC32 UART */ |
268 | #define PORT_PIC32 115 | 268 | #define PORT_PIC32 115 |
269 | 269 | ||
270 | /* MPS2 UART */ | ||
271 | #define PORT_MPS2UART 116 | ||
272 | |||
270 | #endif /* _UAPILINUX_SERIAL_CORE_H */ | 273 | #endif /* _UAPILINUX_SERIAL_CORE_H */ |
diff --git a/include/uapi/linux/tty_flags.h b/include/uapi/linux/tty_flags.h index 072e41e45ee2..66e4d8bcb16f 100644 --- a/include/uapi/linux/tty_flags.h +++ b/include/uapi/linux/tty_flags.h | |||
@@ -32,7 +32,13 @@ | |||
32 | #define ASYNCB_MAGIC_MULTIPLIER 16 /* Use special CLK or divisor */ | 32 | #define ASYNCB_MAGIC_MULTIPLIER 16 /* Use special CLK or divisor */ |
33 | #define ASYNCB_LAST_USER 16 | 33 | #define ASYNCB_LAST_USER 16 |
34 | 34 | ||
35 | /* Internal flags used only by kernel */ | 35 | /* |
36 | * Internal flags used only by kernel (read-only) | ||
37 | * | ||
38 | * WARNING: These flags are no longer used and have been superceded by the | ||
39 | * TTY_PORT_ flags in the iflags field (and not userspace-visible) | ||
40 | */ | ||
41 | #ifndef _KERNEL_ | ||
36 | #define ASYNCB_INITIALIZED 31 /* Serial port was initialized */ | 42 | #define ASYNCB_INITIALIZED 31 /* Serial port was initialized */ |
37 | #define ASYNCB_SUSPENDED 30 /* Serial port is suspended */ | 43 | #define ASYNCB_SUSPENDED 30 /* Serial port is suspended */ |
38 | #define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */ | 44 | #define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */ |
@@ -43,7 +49,9 @@ | |||
43 | #define ASYNCB_SHARE_IRQ 24 /* for multifunction cards, no longer used */ | 49 | #define ASYNCB_SHARE_IRQ 24 /* for multifunction cards, no longer used */ |
44 | #define ASYNCB_CONS_FLOW 23 /* flow control for console */ | 50 | #define ASYNCB_CONS_FLOW 23 /* flow control for console */ |
45 | #define ASYNCB_FIRST_KERNEL 22 | 51 | #define ASYNCB_FIRST_KERNEL 22 |
52 | #endif | ||
46 | 53 | ||
54 | /* Masks */ | ||
47 | #define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY) | 55 | #define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY) |
48 | #define ASYNC_SUSPENDED (1U << ASYNCB_SUSPENDED) | 56 | #define ASYNC_SUSPENDED (1U << ASYNCB_SUSPENDED) |
49 | #define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT) | 57 | #define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT) |
@@ -72,6 +80,8 @@ | |||
72 | #define ASYNC_SPD_WARP (ASYNC_SPD_HI|ASYNC_SPD_SHI) | 80 | #define ASYNC_SPD_WARP (ASYNC_SPD_HI|ASYNC_SPD_SHI) |
73 | #define ASYNC_SPD_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI) | 81 | #define ASYNC_SPD_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI) |
74 | 82 | ||
83 | #ifndef _KERNEL_ | ||
84 | /* These flags are no longer used (and were always masked from userspace) */ | ||
75 | #define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED) | 85 | #define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED) |
76 | #define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE) | 86 | #define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE) |
77 | #define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF) | 87 | #define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF) |
@@ -81,5 +91,6 @@ | |||
81 | #define ASYNC_SHARE_IRQ (1U << ASYNCB_SHARE_IRQ) | 91 | #define ASYNC_SHARE_IRQ (1U << ASYNCB_SHARE_IRQ) |
82 | #define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW) | 92 | #define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW) |
83 | #define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1)) | 93 | #define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1)) |
94 | #endif | ||
84 | 95 | ||
85 | #endif | 96 | #endif |
diff --git a/include/uapi/linux/vt.h b/include/uapi/linux/vt.h index 978578bd1895..f69034887e68 100644 --- a/include/uapi/linux/vt.h +++ b/include/uapi/linux/vt.h | |||
@@ -8,7 +8,6 @@ | |||
8 | */ | 8 | */ |
9 | #define MIN_NR_CONSOLES 1 /* must be at least 1 */ | 9 | #define MIN_NR_CONSOLES 1 /* must be at least 1 */ |
10 | #define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ | 10 | #define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ |
11 | #define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */ | ||
12 | /* Note: the ioctl VT_GETSTATE does not work for | 11 | /* Note: the ioctl VT_GETSTATE does not work for |
13 | consoles 16 and higher (since it returns a short) */ | 12 | consoles 16 and higher (since it returns a short) */ |
14 | 13 | ||
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index da126ee6d218..873c4b707d6a 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
@@ -220,10 +220,11 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) | |||
220 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 220 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
221 | 221 | ||
222 | /* Check if already open */ | 222 | /* Check if already open */ |
223 | if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) { | 223 | if (tty_port_initialized(&self->port)) { |
224 | pr_debug("%s(), already open so break out!\n", __func__); | 224 | pr_debug("%s(), already open so break out!\n", __func__); |
225 | return 0; | 225 | return 0; |
226 | } | 226 | } |
227 | tty_port_set_initialized(&self->port, 1); | ||
227 | 228 | ||
228 | /* Register with IrCOMM */ | 229 | /* Register with IrCOMM */ |
229 | irda_notify_init(¬ify); | 230 | irda_notify_init(¬ify); |
@@ -257,7 +258,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) | |||
257 | 258 | ||
258 | return 0; | 259 | return 0; |
259 | err: | 260 | err: |
260 | clear_bit(ASYNCB_INITIALIZED, &self->port.flags); | 261 | tty_port_set_initialized(&self->port, 0); |
261 | return ret; | 262 | return ret; |
262 | } | 263 | } |
263 | 264 | ||
@@ -280,8 +281,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
280 | * If non-blocking mode is set, or the port is not enabled, | 281 | * If non-blocking mode is set, or the port is not enabled, |
281 | * then make the check up front and then exit. | 282 | * then make the check up front and then exit. |
282 | */ | 283 | */ |
283 | if (test_bit(TTY_IO_ERROR, &tty->flags)) { | 284 | if (tty_io_error(tty)) { |
284 | port->flags |= ASYNC_NORMAL_ACTIVE; | 285 | tty_port_set_active(port, 1); |
285 | return 0; | 286 | return 0; |
286 | } | 287 | } |
287 | 288 | ||
@@ -289,7 +290,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
289 | /* nonblock mode is set */ | 290 | /* nonblock mode is set */ |
290 | if (C_BAUD(tty)) | 291 | if (C_BAUD(tty)) |
291 | tty_port_raise_dtr_rts(port); | 292 | tty_port_raise_dtr_rts(port); |
292 | port->flags |= ASYNC_NORMAL_ACTIVE; | 293 | tty_port_set_active(port, 1); |
293 | pr_debug("%s(), O_NONBLOCK requested!\n", __func__); | 294 | pr_debug("%s(), O_NONBLOCK requested!\n", __func__); |
294 | return 0; | 295 | return 0; |
295 | } | 296 | } |
@@ -318,13 +319,12 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
318 | spin_unlock_irqrestore(&port->lock, flags); | 319 | spin_unlock_irqrestore(&port->lock, flags); |
319 | 320 | ||
320 | while (1) { | 321 | while (1) { |
321 | if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) | 322 | if (C_BAUD(tty) && tty_port_initialized(port)) |
322 | tty_port_raise_dtr_rts(port); | 323 | tty_port_raise_dtr_rts(port); |
323 | 324 | ||
324 | set_current_state(TASK_INTERRUPTIBLE); | 325 | set_current_state(TASK_INTERRUPTIBLE); |
325 | 326 | ||
326 | if (tty_hung_up_p(filp) || | 327 | if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { |
327 | !test_bit(ASYNCB_INITIALIZED, &port->flags)) { | ||
328 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? | 328 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
329 | -EAGAIN : -ERESTARTSYS; | 329 | -EAGAIN : -ERESTARTSYS; |
330 | break; | 330 | break; |
@@ -365,7 +365,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
365 | __FILE__, __LINE__, tty->driver->name, port->count); | 365 | __FILE__, __LINE__, tty->driver->name, port->count); |
366 | 366 | ||
367 | if (!retval) | 367 | if (!retval) |
368 | port->flags |= ASYNC_NORMAL_ACTIVE; | 368 | tty_port_set_active(port, 1); |
369 | 369 | ||
370 | return retval; | 370 | return retval; |
371 | } | 371 | } |
@@ -876,8 +876,9 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) | |||
876 | IRDA_ASSERT(self != NULL, return;); | 876 | IRDA_ASSERT(self != NULL, return;); |
877 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 877 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
878 | 878 | ||
879 | if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags)) | 879 | if (!tty_port_initialized(&self->port)) |
880 | return; | 880 | return; |
881 | tty_port_set_initialized(&self->port, 0); | ||
881 | 882 | ||
882 | ircomm_tty_detach_cable(self); | 883 | ircomm_tty_detach_cable(self); |
883 | 884 | ||
@@ -925,7 +926,6 @@ static void ircomm_tty_hangup(struct tty_struct *tty) | |||
925 | ircomm_tty_shutdown(self); | 926 | ircomm_tty_shutdown(self); |
926 | 927 | ||
927 | spin_lock_irqsave(&port->lock, flags); | 928 | spin_lock_irqsave(&port->lock, flags); |
928 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
929 | if (port->tty) { | 929 | if (port->tty) { |
930 | set_bit(TTY_IO_ERROR, &port->tty->flags); | 930 | set_bit(TTY_IO_ERROR, &port->tty->flags); |
931 | tty_kref_put(port->tty); | 931 | tty_kref_put(port->tty); |
@@ -933,6 +933,7 @@ static void ircomm_tty_hangup(struct tty_struct *tty) | |||
933 | port->tty = NULL; | 933 | port->tty = NULL; |
934 | port->count = 0; | 934 | port->count = 0; |
935 | spin_unlock_irqrestore(&port->lock, flags); | 935 | spin_unlock_irqrestore(&port->lock, flags); |
936 | tty_port_set_active(port, 0); | ||
936 | 937 | ||
937 | wake_up_interruptible(&port->open_wait); | 938 | wake_up_interruptible(&port->open_wait); |
938 | } | 939 | } |
@@ -999,7 +1000,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
999 | if (status & IRCOMM_DCE_DELTA_ANY) { | 1000 | if (status & IRCOMM_DCE_DELTA_ANY) { |
1000 | /*wake_up_interruptible(&self->delta_msr_wait);*/ | 1001 | /*wake_up_interruptible(&self->delta_msr_wait);*/ |
1001 | } | 1002 | } |
1002 | if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { | 1003 | if (tty_port_check_carrier(&self->port) && (status & IRCOMM_DELTA_CD)) { |
1003 | pr_debug("%s(), ircomm%d CD now %s...\n", __func__ , self->line, | 1004 | pr_debug("%s(), ircomm%d CD now %s...\n", __func__ , self->line, |
1004 | (status & IRCOMM_CD) ? "on" : "off"); | 1005 | (status & IRCOMM_CD) ? "on" : "off"); |
1005 | 1006 | ||
@@ -1255,11 +1256,11 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | |||
1255 | seq_printf(m, "%cASYNC_CTS_FLOW", sep); | 1256 | seq_printf(m, "%cASYNC_CTS_FLOW", sep); |
1256 | sep = '|'; | 1257 | sep = '|'; |
1257 | } | 1258 | } |
1258 | if (self->port.flags & ASYNC_CHECK_CD) { | 1259 | if (tty_port_check_carrier(&self->port)) { |
1259 | seq_printf(m, "%cASYNC_CHECK_CD", sep); | 1260 | seq_printf(m, "%cASYNC_CHECK_CD", sep); |
1260 | sep = '|'; | 1261 | sep = '|'; |
1261 | } | 1262 | } |
1262 | if (self->port.flags & ASYNC_INITIALIZED) { | 1263 | if (tty_port_initialized(&self->port)) { |
1263 | seq_printf(m, "%cASYNC_INITIALIZED", sep); | 1264 | seq_printf(m, "%cASYNC_INITIALIZED", sep); |
1264 | sep = '|'; | 1265 | sep = '|'; |
1265 | } | 1266 | } |
@@ -1267,7 +1268,7 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | |||
1267 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); | 1268 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); |
1268 | sep = '|'; | 1269 | sep = '|'; |
1269 | } | 1270 | } |
1270 | if (self->port.flags & ASYNC_NORMAL_ACTIVE) { | 1271 | if (tty_port_active(&self->port)) { |
1271 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); | 1272 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); |
1272 | sep = '|'; | 1273 | sep = '|'; |
1273 | } | 1274 | } |
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index 61137f8b5293..0a411019c098 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c | |||
@@ -968,7 +968,7 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, | |||
968 | ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); | 968 | ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); |
969 | ircomm_tty_start_watchdog_timer(self, 3*HZ); | 969 | ircomm_tty_start_watchdog_timer(self, 3*HZ); |
970 | 970 | ||
971 | if (self->port.flags & ASYNC_CHECK_CD) { | 971 | if (tty_port_check_carrier(&self->port)) { |
972 | /* Drop carrier */ | 972 | /* Drop carrier */ |
973 | self->settings.dce = IRCOMM_DELTA_CD; | 973 | self->settings.dce = IRCOMM_DELTA_CD; |
974 | ircomm_tty_check_modem_status(self); | 974 | ircomm_tty_check_modem_status(self); |
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index d3687aaa23de..d4fdf8f7b471 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c | |||
@@ -86,21 +86,17 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self, | |||
86 | ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE); | 86 | ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE); |
87 | 87 | ||
88 | /* CTS flow control flag and modem status interrupts */ | 88 | /* CTS flow control flag and modem status interrupts */ |
89 | tty_port_set_cts_flow(&self->port, cflag & CRTSCTS); | ||
89 | if (cflag & CRTSCTS) { | 90 | if (cflag & CRTSCTS) { |
90 | self->port.flags |= ASYNC_CTS_FLOW; | ||
91 | self->settings.flow_control |= IRCOMM_RTS_CTS_IN; | 91 | self->settings.flow_control |= IRCOMM_RTS_CTS_IN; |
92 | /* This got me. Bummer. Jean II */ | 92 | /* This got me. Bummer. Jean II */ |
93 | if (self->service_type == IRCOMM_3_WIRE_RAW) | 93 | if (self->service_type == IRCOMM_3_WIRE_RAW) |
94 | net_warn_ratelimited("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", | 94 | net_warn_ratelimited("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", |
95 | __func__); | 95 | __func__); |
96 | } else { | 96 | } else { |
97 | self->port.flags &= ~ASYNC_CTS_FLOW; | ||
98 | self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN; | 97 | self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN; |
99 | } | 98 | } |
100 | if (cflag & CLOCAL) | 99 | tty_port_set_check_carrier(&self->port, ~cflag & CLOCAL); |
101 | self->port.flags &= ~ASYNC_CHECK_CD; | ||
102 | else | ||
103 | self->port.flags |= ASYNC_CHECK_CD; | ||
104 | #if 0 | 100 | #if 0 |
105 | /* | 101 | /* |
106 | * Set up parity check flag | 102 | * Set up parity check flag |
@@ -166,7 +162,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
166 | /* Handle transition away from B0 status */ | 162 | /* Handle transition away from B0 status */ |
167 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { | 163 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
168 | self->settings.dte |= IRCOMM_DTR; | 164 | self->settings.dte |= IRCOMM_DTR; |
169 | if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) | 165 | if (!C_CRTSCTS(tty) || !tty_throttled(tty)) |
170 | self->settings.dte |= IRCOMM_RTS; | 166 | self->settings.dte |= IRCOMM_RTS; |
171 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 167 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
172 | } | 168 | } |
@@ -190,7 +186,7 @@ int ircomm_tty_tiocmget(struct tty_struct *tty) | |||
190 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 186 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
191 | unsigned int result; | 187 | unsigned int result; |
192 | 188 | ||
193 | if (tty->flags & (1 << TTY_IO_ERROR)) | 189 | if (tty_io_error(tty)) |
194 | return -EIO; | 190 | return -EIO; |
195 | 191 | ||
196 | result = ((self->settings.dte & IRCOMM_RTS) ? TIOCM_RTS : 0) | 192 | result = ((self->settings.dte & IRCOMM_RTS) ? TIOCM_RTS : 0) |
@@ -213,7 +209,7 @@ int ircomm_tty_tiocmset(struct tty_struct *tty, | |||
213 | { | 209 | { |
214 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 210 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
215 | 211 | ||
216 | if (tty->flags & (1 << TTY_IO_ERROR)) | 212 | if (tty_io_error(tty)) |
217 | return -EIO; | 213 | return -EIO; |
218 | 214 | ||
219 | IRDA_ASSERT(self != NULL, return -1;); | 215 | IRDA_ASSERT(self != NULL, return -1;); |
@@ -328,7 +324,7 @@ static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *self, | |||
328 | 324 | ||
329 | check_and_exit: | 325 | check_and_exit: |
330 | 326 | ||
331 | if (self->flags & ASYNC_INITIALIZED) { | 327 | if (tty_port_initialized(self)) { |
332 | if (((old_state.flags & ASYNC_SPD_MASK) != | 328 | if (((old_state.flags & ASYNC_SPD_MASK) != |
333 | (self->flags & ASYNC_SPD_MASK)) || | 329 | (self->flags & ASYNC_SPD_MASK)) || |
334 | (old_driver.custom_divisor != driver->custom_divisor)) { | 330 | (old_driver.custom_divisor != driver->custom_divisor)) { |
@@ -362,7 +358,7 @@ int ircomm_tty_ioctl(struct tty_struct *tty, | |||
362 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 358 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
363 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && | 359 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && |
364 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 360 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { |
365 | if (tty->flags & (1 << TTY_IO_ERROR)) | 361 | if (tty_io_error(tty)) |
366 | return -EIO; | 362 | return -EIO; |
367 | } | 363 | } |
368 | 364 | ||