diff options
97 files changed, 3233 insertions, 1802 deletions
diff --git a/Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt b/Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt new file mode 100644 index 000000000000..4163e7eb7763 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt | |||
@@ -0,0 +1,10 @@ | |||
1 | * ARM SBSA defined generic UART | ||
2 | This UART uses a subset of the PL011 registers and consequently lives | ||
3 | in the PL011 driver. It's baudrate and other communication parameters | ||
4 | cannot be adjusted at runtime, so it lacks a clock specifier here. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: must be "arm,sbsa-uart" | ||
8 | - reg: exactly one register range | ||
9 | - interrupts: exactly one interrupt specifier | ||
10 | - current-speed: the (fixed) baud rate set by the firmware | ||
diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt index 44152261e5c5..8d63f1da07aa 100644 --- a/Documentation/devicetree/bindings/serial/mtk-uart.txt +++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt | |||
@@ -14,7 +14,14 @@ Required properties: | |||
14 | 14 | ||
15 | - interrupts: A single interrupt specifier. | 15 | - interrupts: A single interrupt specifier. |
16 | 16 | ||
17 | - clocks: Clock driving the hardware. | 17 | - clocks : Must contain an entry for each entry in clock-names. |
18 | See ../clocks/clock-bindings.txt for details. | ||
19 | - clock-names: | ||
20 | - "baud": The clock the baudrate is derived from | ||
21 | - "bus": The bus clock for register accesses (optional) | ||
22 | |||
23 | For compatibility with older device trees an unnamed clock is used for the | ||
24 | baud clock if the baudclk does not exist. Do not use this for new designs. | ||
18 | 25 | ||
19 | Example: | 26 | Example: |
20 | 27 | ||
@@ -22,5 +29,6 @@ Example: | |||
22 | compatible = "mediatek,mt6589-uart", "mediatek,mt6577-uart"; | 29 | compatible = "mediatek,mt6589-uart", "mediatek,mt6577-uart"; |
23 | reg = <0x11006000 0x400>; | 30 | reg = <0x11006000 0x400>; |
24 | interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>; | 31 | interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>; |
25 | clocks = <&uart_clk>; | 32 | clocks = <&uart_clk>, <&bus_clk>; |
33 | clock-names = "baud", "bus"; | ||
26 | }; | 34 | }; |
diff --git a/Documentation/devicetree/bindings/serial/nxp,lpc1850-uart.txt b/Documentation/devicetree/bindings/serial/nxp,lpc1850-uart.txt new file mode 100644 index 000000000000..04e23e63ee4f --- /dev/null +++ b/Documentation/devicetree/bindings/serial/nxp,lpc1850-uart.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | * NXP LPC1850 UART | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "nxp,lpc1850-uart", "ns16550a". | ||
5 | - reg : offset and length of the register set for the device. | ||
6 | - interrupts : should contain uart interrupt. | ||
7 | - clocks : phandle to the input clocks. | ||
8 | - clock-names : required elements: "uartclk", "reg". | ||
9 | |||
10 | Optional properties: | ||
11 | - dmas : Two or more DMA channel specifiers following the | ||
12 | convention outlined in bindings/dma/dma.txt | ||
13 | - dma-names : Names for the dma channels, if present. There must | ||
14 | be at least one channel named "tx" for transmit | ||
15 | and named "rx" for receive. | ||
16 | |||
17 | Since it's also possible to also use the of_serial.c driver all | ||
18 | parameters from 8250.txt also apply but are optional. | ||
19 | |||
20 | Example: | ||
21 | uart0: serial@40081000 { | ||
22 | compatible = "nxp,lpc1850-uart", "ns16550a"; | ||
23 | reg = <0x40081000 0x1000>; | ||
24 | reg-shift = <2>; | ||
25 | interrupts = <24>; | ||
26 | clocks = <&ccu2 CLK_APB0_UART0>, <&ccu1 CLK_CPU_UART0>; | ||
27 | clock-names = "uartclk", "reg"; | ||
28 | }; | ||
diff --git a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt index 246c795668dc..fbfe53635a3a 100644 --- a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt +++ b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt | |||
@@ -1,4 +1,5 @@ | |||
1 | * NXP SC16IS7xx advanced Universal Asynchronous Receiver-Transmitter (UART) | 1 | * NXP SC16IS7xx advanced Universal Asynchronous Receiver-Transmitter (UART) |
2 | * i2c as bus | ||
2 | 3 | ||
3 | Required properties: | 4 | Required properties: |
4 | - compatible: Should be one of the following: | 5 | - compatible: Should be one of the following: |
@@ -31,3 +32,39 @@ Example: | |||
31 | gpio-controller; | 32 | gpio-controller; |
32 | #gpio-cells = <2>; | 33 | #gpio-cells = <2>; |
33 | }; | 34 | }; |
35 | |||
36 | * spi as bus | ||
37 | |||
38 | Required properties: | ||
39 | - compatible: Should be one of the following: | ||
40 | - "nxp,sc16is740" for NXP SC16IS740, | ||
41 | - "nxp,sc16is741" for NXP SC16IS741, | ||
42 | - "nxp,sc16is750" for NXP SC16IS750, | ||
43 | - "nxp,sc16is752" for NXP SC16IS752, | ||
44 | - "nxp,sc16is760" for NXP SC16IS760, | ||
45 | - "nxp,sc16is762" for NXP SC16IS762. | ||
46 | - reg: SPI chip select number. | ||
47 | - interrupt-parent: The phandle for the interrupt controller that | ||
48 | services interrupts for this IC. | ||
49 | - interrupts: Specifies the interrupt source of the parent interrupt | ||
50 | controller. The format of the interrupt specifier depends on the | ||
51 | parent interrupt controller. | ||
52 | - clocks: phandle to the IC source clock. | ||
53 | |||
54 | Optional properties: | ||
55 | - gpio-controller: Marks the device node as a GPIO controller. | ||
56 | - #gpio-cells: Should be two. The first cell is the GPIO number and | ||
57 | the second cell is used to specify the GPIO polarity: | ||
58 | 0 = active high, | ||
59 | 1 = active low. | ||
60 | |||
61 | Example: | ||
62 | sc16is750: sc16is750@0 { | ||
63 | compatible = "nxp,sc16is750"; | ||
64 | reg = <0>; | ||
65 | clocks = <&clk20m>; | ||
66 | interrupt-parent = <&gpio3>; | ||
67 | interrupts = <7 IRQ_TYPE_EDGE_FALLING>; | ||
68 | gpio-controller; | ||
69 | #gpio-cells = <2>; | ||
70 | }; | ||
diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 7534d46e9ad8..e84b13a8eda3 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | |||
@@ -45,6 +45,11 @@ Required properties: | |||
45 | Note: Each enabled SCIx UART should have an alias correctly numbered in the | 45 | Note: Each enabled SCIx UART should have an alias correctly numbered in the |
46 | "aliases" node. | 46 | "aliases" node. |
47 | 47 | ||
48 | Optional properties: | ||
49 | - dmas: Must contain a list of two references to DMA specifiers, one for | ||
50 | transmission, and one for reception. | ||
51 | - dma-names: Must contain a list of two DMA names, "tx" and "rx". | ||
52 | |||
48 | Example: | 53 | Example: |
49 | aliases { | 54 | aliases { |
50 | serial0 = &scifa0; | 55 | serial0 = &scifa0; |
@@ -57,4 +62,6 @@ Example: | |||
57 | interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; | 62 | interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; |
58 | clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; | 63 | clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; |
59 | clock-names = "sci_ick"; | 64 | clock-names = "sci_ick"; |
65 | dmas = <&dmac0 0x21>, <&dmac0 0x22>; | ||
66 | dma-names = "tx", "rx"; | ||
60 | }; | 67 | }; |
diff --git a/Documentation/devicetree/bindings/serial/sirf-uart.txt b/Documentation/devicetree/bindings/serial/sirf-uart.txt index f0c39261c5d4..67e2a0aeb042 100644 --- a/Documentation/devicetree/bindings/serial/sirf-uart.txt +++ b/Documentation/devicetree/bindings/serial/sirf-uart.txt | |||
@@ -2,8 +2,7 @@ | |||
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible : Should be "sirf,prima2-uart", "sirf, prima2-usp-uart", | 4 | - compatible : Should be "sirf,prima2-uart", "sirf, prima2-usp-uart", |
5 | "sirf,atlas7-uart" or "sirf,atlas7-bt-uart" which means | 5 | "sirf,atlas7-uart" or "sirf,atlas7-usp-uart". |
6 | uart located in BT module and used for BT. | ||
7 | - reg : Offset and length of the register set for the device | 6 | - reg : Offset and length of the register set for the device |
8 | - interrupts : Should contain uart interrupt | 7 | - interrupts : Should contain uart interrupt |
9 | - fifosize : Should define hardware rx/tx fifo size | 8 | - fifosize : Should define hardware rx/tx fifo size |
@@ -33,15 +32,3 @@ usp@b0090000 { | |||
33 | rts-gpios = <&gpio 15 0>; | 32 | rts-gpios = <&gpio 15 0>; |
34 | cts-gpios = <&gpio 46 0>; | 33 | cts-gpios = <&gpio 46 0>; |
35 | }; | 34 | }; |
36 | |||
37 | for uart use in BT module, | ||
38 | uart6: uart@11000000 { | ||
39 | cell-index = <6>; | ||
40 | compatible = "sirf,atlas7-bt-uart", "sirf,atlas7-uart"; | ||
41 | reg = <0x11000000 0x1000>; | ||
42 | interrupts = <0 100 0>; | ||
43 | clocks = <&clks 138>, <&clks 140>, <&clks 141>; | ||
44 | clock-names = "uart", "general", "noc"; | ||
45 | fifosize = <128>; | ||
46 | status = "disabled"; | ||
47 | } | ||
diff --git a/Documentation/devicetree/bindings/serial/uniphier-uart.txt b/Documentation/devicetree/bindings/serial/uniphier-uart.txt new file mode 100644 index 000000000000..0b3892a7a528 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/uniphier-uart.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | UniPhier UART controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be "socionext,uniphier-uart". | ||
5 | - reg: offset and length of the register set for the device. | ||
6 | - interrupts: a single interrupt specifier. | ||
7 | - clocks: phandle to the input clock. | ||
8 | |||
9 | Optional properties: | ||
10 | - fifo-size: the RX/TX FIFO size. Defaults to 64 if not specified. | ||
11 | |||
12 | Example: | ||
13 | aliases { | ||
14 | serial0 = &serial0; | ||
15 | }; | ||
16 | |||
17 | serial0: serial@54006800 { | ||
18 | compatible = "socionext,uniphier-uart"; | ||
19 | reg = <0x54006800 0x40>; | ||
20 | interrupts = <0 33 4>; | ||
21 | clocks = <&uart_clk>; | ||
22 | fifo-size = <64>; | ||
23 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 1e18efe3a4ed..8bb54c95cece 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -972,14 +972,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
972 | uart[8250],io,<addr>[,options] | 972 | uart[8250],io,<addr>[,options] |
973 | uart[8250],mmio,<addr>[,options] | 973 | uart[8250],mmio,<addr>[,options] |
974 | uart[8250],mmio32,<addr>[,options] | 974 | uart[8250],mmio32,<addr>[,options] |
975 | uart[8250],mmio32be,<addr>[,options] | ||
975 | uart[8250],0x<addr>[,options] | 976 | uart[8250],0x<addr>[,options] |
976 | Start an early, polled-mode console on the 8250/16550 | 977 | Start an early, polled-mode console on the 8250/16550 |
977 | UART at the specified I/O port or MMIO address. | 978 | UART at the specified I/O port or MMIO address. |
978 | MMIO inter-register address stride is either 8-bit | 979 | MMIO inter-register address stride is either 8-bit |
979 | (mmio) or 32-bit (mmio32). | 980 | (mmio) or 32-bit (mmio32 or mmio32be). |
980 | If none of [io|mmio|mmio32], <addr> is assumed to be | 981 | If none of [io|mmio|mmio32|mmio32be], <addr> is assumed |
981 | equivalent to 'mmio'. 'options' are specified in the | 982 | to be equivalent to 'mmio'. 'options' are specified |
982 | same format described for "console=ttyS<n>"; if | 983 | in the same format described for "console=ttyS<n>"; if |
983 | unspecified, the h/w is not initialized. | 984 | unspecified, the h/w is not initialized. |
984 | 985 | ||
985 | pl011,<addr> | 986 | pl011,<addr> |
diff --git a/Documentation/serial/serial-rs485.txt b/Documentation/serial/serial-rs485.txt index 39dac95422a3..2253b8b45a74 100644 --- a/Documentation/serial/serial-rs485.txt +++ b/Documentation/serial/serial-rs485.txt | |||
@@ -33,50 +33,10 @@ | |||
33 | the values given by the device tree. | 33 | the values given by the device tree. |
34 | 34 | ||
35 | Any driver for devices capable of working both as RS232 and RS485 should | 35 | Any driver for devices capable of working both as RS232 and RS485 should |
36 | provide at least the following ioctls: | 36 | implement the rs485_config callback in the uart_port structure. The |
37 | 37 | serial_core calls rs485_config to do the device specific part in response | |
38 | - TIOCSRS485 (typically associated with number 0x542F). This ioctl is used | 38 | to TIOCSRS485 and TIOCGRS485 ioctls (see below). The rs485_config callback |
39 | to enable/disable RS485 mode from user-space | 39 | receives a pointer to struct serial_rs485. |
40 | |||
41 | - TIOCGRS485 (typically associated with number 0x542E). This ioctl is used | ||
42 | to get RS485 mode from kernel-space (i.e., driver) to user-space. | ||
43 | |||
44 | In other words, the serial driver should contain a code similar to the next | ||
45 | one: | ||
46 | |||
47 | static struct uart_ops atmel_pops = { | ||
48 | /* ... */ | ||
49 | .ioctl = handle_ioctl, | ||
50 | }; | ||
51 | |||
52 | static int handle_ioctl(struct uart_port *port, | ||
53 | unsigned int cmd, | ||
54 | unsigned long arg) | ||
55 | { | ||
56 | struct serial_rs485 rs485conf; | ||
57 | |||
58 | switch (cmd) { | ||
59 | case TIOCSRS485: | ||
60 | if (copy_from_user(&rs485conf, | ||
61 | (struct serial_rs485 *) arg, | ||
62 | sizeof(rs485conf))) | ||
63 | return -EFAULT; | ||
64 | |||
65 | /* ... */ | ||
66 | break; | ||
67 | |||
68 | case TIOCGRS485: | ||
69 | if (copy_to_user((struct serial_rs485 *) arg, | ||
70 | ..., | ||
71 | sizeof(rs485conf))) | ||
72 | return -EFAULT; | ||
73 | /* ... */ | ||
74 | break; | ||
75 | |||
76 | /* ... */ | ||
77 | } | ||
78 | } | ||
79 | |||
80 | 40 | ||
81 | 4. USAGE FROM USER-LEVEL | 41 | 4. USAGE FROM USER-LEVEL |
82 | 42 | ||
@@ -85,7 +45,7 @@ | |||
85 | 45 | ||
86 | #include <linux/serial.h> | 46 | #include <linux/serial.h> |
87 | 47 | ||
88 | /* Driver-specific ioctls: */ | 48 | /* RS485 ioctls: */ |
89 | #define TIOCGRS485 0x542E | 49 | #define TIOCGRS485 0x542E |
90 | #define TIOCSRS485 0x542F | 50 | #define TIOCSRS485 0x542F |
91 | 51 | ||
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt index dbe6623fed1c..973c8ad3f959 100644 --- a/Documentation/serial/tty.txt +++ b/Documentation/serial/tty.txt | |||
@@ -4,9 +4,6 @@ | |||
4 | Your guide to the ancient and twisted locking policies of the tty layer and | 4 | Your guide to the ancient and twisted locking policies of the tty layer and |
5 | the warped logic behind them. Beware all ye who read on. | 5 | the warped logic behind them. Beware all ye who read on. |
6 | 6 | ||
7 | FIXME: still need to work out the full set of BKL assumptions and document | ||
8 | them so they can eventually be killed off. | ||
9 | |||
10 | 7 | ||
11 | Line Discipline | 8 | Line Discipline |
12 | --------------- | 9 | --------------- |
diff --git a/MAINTAINERS b/MAINTAINERS index 35c5d7223b8c..df6007824715 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -10316,6 +10316,7 @@ M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |||
10316 | M: Jiri Slaby <jslaby@suse.cz> | 10316 | M: Jiri Slaby <jslaby@suse.cz> |
10317 | S: Supported | 10317 | S: Supported |
10318 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git | 10318 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git |
10319 | F: Documentation/serial/ | ||
10319 | F: drivers/tty/ | 10320 | F: drivers/tty/ |
10320 | F: drivers/tty/serial/serial_core.c | 10321 | F: drivers/tty/serial/serial_core.c |
10321 | F: include/linux/serial_core.h | 10322 | F: include/linux/serial_core.h |
diff --git a/arch/alpha/include/asm/serial.h b/arch/alpha/include/asm/serial.h index 9d263e8d8ccc..22909b83f473 100644 --- a/arch/alpha/include/asm/serial.h +++ b/arch/alpha/include/asm/serial.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #define BASE_BAUD ( 1843200 / 16 ) | 13 | #define BASE_BAUD ( 1843200 / 16 ) |
14 | 14 | ||
15 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 15 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
16 | #ifdef CONFIG_SERIAL_DETECT_IRQ | 16 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
17 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) | 17 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) |
18 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) | 18 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) |
19 | #else | 19 | #else |
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 5662a872689b..873dbfcc7dc9 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c | |||
@@ -1350,6 +1350,9 @@ void edma_stop(unsigned channel) | |||
1350 | edma_shadow0_write_array(ctlr, SH_SECR, j, mask); | 1350 | edma_shadow0_write_array(ctlr, SH_SECR, j, mask); |
1351 | edma_write_array(ctlr, EDMA_EMCR, j, mask); | 1351 | edma_write_array(ctlr, EDMA_EMCR, j, mask); |
1352 | 1352 | ||
1353 | /* clear possibly pending completion interrupt */ | ||
1354 | edma_shadow0_write_array(ctlr, SH_ICR, j, mask); | ||
1355 | |||
1353 | pr_debug("EDMA: EER%d %08x\n", j, | 1356 | pr_debug("EDMA: EER%d %08x\n", j, |
1354 | edma_shadow0_read_array(ctlr, SH_EER, j)); | 1357 | edma_shadow0_read_array(ctlr, SH_EER, j)); |
1355 | 1358 | ||
diff --git a/arch/blackfin/include/asm/bfin_serial.h b/arch/blackfin/include/asm/bfin_serial.h index d00d732784b1..b550ada7321b 100644 --- a/arch/blackfin/include/asm/bfin_serial.h +++ b/arch/blackfin/include/asm/bfin_serial.h | |||
@@ -22,9 +22,9 @@ | |||
22 | defined(CONFIG_BFIN_UART2_CTSRTS) || \ | 22 | defined(CONFIG_BFIN_UART2_CTSRTS) || \ |
23 | defined(CONFIG_BFIN_UART3_CTSRTS) | 23 | defined(CONFIG_BFIN_UART3_CTSRTS) |
24 | # if defined(BFIN_UART_BF54X_STYLE) || defined(BFIN_UART_BF60X_STYLE) | 24 | # if defined(BFIN_UART_BF54X_STYLE) || defined(BFIN_UART_BF60X_STYLE) |
25 | # define CONFIG_SERIAL_BFIN_HARD_CTSRTS | 25 | # define SERIAL_BFIN_HARD_CTSRTS |
26 | # else | 26 | # else |
27 | # define CONFIG_SERIAL_BFIN_CTSRTS | 27 | # define SERIAL_BFIN_CTSRTS |
28 | # endif | 28 | # endif |
29 | #endif | 29 | #endif |
30 | 30 | ||
@@ -50,8 +50,8 @@ struct bfin_serial_port { | |||
50 | #elif ANOMALY_05000363 | 50 | #elif ANOMALY_05000363 |
51 | unsigned int anomaly_threshold; | 51 | unsigned int anomaly_threshold; |
52 | #endif | 52 | #endif |
53 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | 53 | #if defined(SERIAL_BFIN_CTSRTS) || \ |
54 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | 54 | defined(SERIAL_BFIN_HARD_CTSRTS) |
55 | int cts_pin; | 55 | int cts_pin; |
56 | int rts_pin; | 56 | int rts_pin; |
57 | #endif | 57 | #endif |
diff --git a/arch/m68k/include/asm/serial.h b/arch/m68k/include/asm/serial.h index 7267536adbcc..06d0cb19b4e1 100644 --- a/arch/m68k/include/asm/serial.h +++ b/arch/m68k/include/asm/serial.h | |||
@@ -17,7 +17,7 @@ | |||
17 | #define BASE_BAUD ( 1843200 / 16 ) | 17 | #define BASE_BAUD ( 1843200 / 16 ) |
18 | 18 | ||
19 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 19 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
20 | #ifdef CONFIG_SERIAL_DETECT_IRQ | 20 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
21 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) | 21 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) |
22 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) | 22 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) |
23 | #else | 23 | #else |
diff --git a/arch/mn10300/include/asm/serial.h b/arch/mn10300/include/asm/serial.h index 23a799293599..c1990218f18c 100644 --- a/arch/mn10300/include/asm/serial.h +++ b/arch/mn10300/include/asm/serial.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #define _ASM_SERIAL_H | 13 | #define _ASM_SERIAL_H |
14 | 14 | ||
15 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 15 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
16 | #ifdef CONFIG_SERIAL_DETECT_IRQ | 16 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
17 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) | 17 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) |
18 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) | 18 | #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) |
19 | #else | 19 | #else |
@@ -21,7 +21,7 @@ | |||
21 | #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF | 21 | #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #ifdef CONFIG_SERIAL_MANY_PORTS | 24 | #ifdef CONFIG_SERIAL_8250_MANY_PORTS |
25 | #define FOURPORT_FLAGS ASYNC_FOURPORT | 25 | #define FOURPORT_FLAGS ASYNC_FOURPORT |
26 | #define ACCENT_FLAGS 0 | 26 | #define ACCENT_FLAGS 0 |
27 | #define BOCA_FLAGS 0 | 27 | #define BOCA_FLAGS 0 |
diff --git a/arch/x86/include/asm/serial.h b/arch/x86/include/asm/serial.h index 8378b8c9109c..bb658211edad 100644 --- a/arch/x86/include/asm/serial.h +++ b/arch/x86/include/asm/serial.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #define BASE_BAUD (1843200/16) | 11 | #define BASE_BAUD (1843200/16) |
12 | 12 | ||
13 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 13 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
14 | #ifdef CONFIG_SERIAL_DETECT_IRQ | 14 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
15 | # define STD_COMX_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ) | 15 | # define STD_COMX_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ) |
16 | # define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | 0 | UPF_AUTO_IRQ) | 16 | # define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | 0 | UPF_AUTO_IRQ) |
17 | #else | 17 | #else |
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index bf09db7ca9ee..88853af69489 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c | |||
@@ -300,8 +300,7 @@ static int edma_dma_pause(struct dma_chan *chan) | |||
300 | { | 300 | { |
301 | struct edma_chan *echan = to_edma_chan(chan); | 301 | struct edma_chan *echan = to_edma_chan(chan); |
302 | 302 | ||
303 | /* Pause/Resume only allowed with cyclic mode */ | 303 | if (!echan->edesc) |
304 | if (!echan->edesc || !echan->edesc->cyclic) | ||
305 | return -EINVAL; | 304 | return -EINVAL; |
306 | 305 | ||
307 | edma_pause(echan->ch_num); | 306 | edma_pause(echan->ch_num); |
@@ -312,10 +311,6 @@ static int edma_dma_resume(struct dma_chan *chan) | |||
312 | { | 311 | { |
313 | struct edma_chan *echan = to_edma_chan(chan); | 312 | struct edma_chan *echan = to_edma_chan(chan); |
314 | 313 | ||
315 | /* Pause/Resume only allowed with cyclic mode */ | ||
316 | if (!echan->edesc->cyclic) | ||
317 | return -EINVAL; | ||
318 | |||
319 | edma_resume(echan->ch_num); | 314 | edma_resume(echan->ch_num); |
320 | return 0; | 315 | return 0; |
321 | } | 316 | } |
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 69175b825346..9c927d35c1f5 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -167,7 +167,6 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u | |||
167 | { | 167 | { |
168 | struct serport *serport = (struct serport*) tty->disc_data; | 168 | struct serport *serport = (struct serport*) tty->disc_data; |
169 | struct serio *serio; | 169 | struct serio *serio; |
170 | char name[64]; | ||
171 | 170 | ||
172 | if (test_and_set_bit(SERPORT_BUSY, &serport->flags)) | 171 | if (test_and_set_bit(SERPORT_BUSY, &serport->flags)) |
173 | return -EBUSY; | 172 | return -EBUSY; |
@@ -177,7 +176,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u | |||
177 | return -ENOMEM; | 176 | return -ENOMEM; |
178 | 177 | ||
179 | strlcpy(serio->name, "Serial port", sizeof(serio->name)); | 178 | strlcpy(serio->name, "Serial port", sizeof(serio->name)); |
180 | snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name)); | 179 | snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty)); |
181 | serio->id = serport->id; | 180 | serio->id = serport->id; |
182 | serio->id.type = SERIO_RS232; | 181 | serio->id.type = SERIO_RS232; |
183 | serio->write = serport_serio_write; | 182 | serio->write = serport_serio_write; |
@@ -187,7 +186,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u | |||
187 | serio->dev.parent = tty->dev; | 186 | serio->dev.parent = tty->dev; |
188 | 187 | ||
189 | serio_register_port(serport->serio); | 188 | serio_register_port(serport->serio); |
190 | printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name)); | 189 | printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty)); |
191 | 190 | ||
192 | wait_event_interruptible(serport->wait, test_bit(SERPORT_DEAD, &serport->flags)); | 191 | wait_event_interruptible(serport->wait, test_bit(SERPORT_DEAD, &serport->flags)); |
193 | serio_unregister_port(serport->serio); | 192 | serio_unregister_port(serport->serio); |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index b2d760055952..e53d9a512c6d 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -966,9 +966,7 @@ static void rs_throttle(struct tty_struct * tty) | |||
966 | struct serial_state *info = tty->driver_data; | 966 | struct serial_state *info = tty->driver_data; |
967 | unsigned long flags; | 967 | unsigned long flags; |
968 | #ifdef SERIAL_DEBUG_THROTTLE | 968 | #ifdef SERIAL_DEBUG_THROTTLE |
969 | char buf[64]; | 969 | printk("throttle %s: %d....\n", tty_name(tty), |
970 | |||
971 | printk("throttle %s: %d....\n", tty_name(tty, buf), | ||
972 | tty->ldisc.chars_in_buffer(tty)); | 970 | tty->ldisc.chars_in_buffer(tty)); |
973 | #endif | 971 | #endif |
974 | 972 | ||
@@ -991,9 +989,7 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
991 | struct serial_state *info = tty->driver_data; | 989 | struct serial_state *info = tty->driver_data; |
992 | unsigned long flags; | 990 | unsigned long flags; |
993 | #ifdef SERIAL_DEBUG_THROTTLE | 991 | #ifdef SERIAL_DEBUG_THROTTLE |
994 | char buf[64]; | 992 | printk("unthrottle %s: %d....\n", tty_name(tty), |
995 | |||
996 | printk("unthrottle %s: %d....\n", tty_name(tty, buf), | ||
997 | tty->ldisc.chars_in_buffer(tty)); | 993 | tty->ldisc.chars_in_buffer(tty)); |
998 | #endif | 994 | #endif |
999 | 995 | ||
@@ -1786,7 +1782,8 @@ static int __exit amiga_serial_remove(struct platform_device *pdev) | |||
1786 | struct serial_state *state = platform_get_drvdata(pdev); | 1782 | struct serial_state *state = platform_get_drvdata(pdev); |
1787 | 1783 | ||
1788 | /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ | 1784 | /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ |
1789 | if ((error = tty_unregister_driver(serial_driver))) | 1785 | error = tty_unregister_driver(serial_driver); |
1786 | if (error) | ||
1790 | printk("SERIAL: failed to unregister serial driver (%d)\n", | 1787 | printk("SERIAL: failed to unregister serial driver (%d)\n", |
1791 | error); | 1788 | error); |
1792 | put_tty_driver(serial_driver); | 1789 | put_tty_driver(serial_driver); |
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index fd66f57390d0..87f6578c6f4a 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -2861,9 +2861,7 @@ static void cy_throttle(struct tty_struct *tty) | |||
2861 | unsigned long flags; | 2861 | unsigned long flags; |
2862 | 2862 | ||
2863 | #ifdef CY_DEBUG_THROTTLE | 2863 | #ifdef CY_DEBUG_THROTTLE |
2864 | char buf[64]; | 2864 | printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty), |
2865 | |||
2866 | printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf), | ||
2867 | tty->ldisc.chars_in_buffer(tty), info->line); | 2865 | tty->ldisc.chars_in_buffer(tty), info->line); |
2868 | #endif | 2866 | #endif |
2869 | 2867 | ||
@@ -2902,10 +2900,8 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
2902 | unsigned long flags; | 2900 | unsigned long flags; |
2903 | 2901 | ||
2904 | #ifdef CY_DEBUG_THROTTLE | 2902 | #ifdef CY_DEBUG_THROTTLE |
2905 | char buf[64]; | ||
2906 | |||
2907 | printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", | 2903 | printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", |
2908 | tty_name(tty, buf), tty_chars_in_buffer(tty), info->line); | 2904 | tty_name(tty), tty_chars_in_buffer(tty), info->line); |
2909 | #endif | 2905 | #endif |
2910 | 2906 | ||
2911 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) | 2907 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) |
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index 8902f9b4df71..2509d057b99c 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig | |||
@@ -42,13 +42,6 @@ config HVC_RTAS | |||
42 | help | 42 | help |
43 | IBM Console device driver which makes use of RTAS | 43 | IBM Console device driver which makes use of RTAS |
44 | 44 | ||
45 | config HVC_BEAT | ||
46 | bool "Toshiba's Beat Hypervisor Console support" | ||
47 | depends on PPC_CELLEB | ||
48 | select HVC_DRIVER | ||
49 | help | ||
50 | Toshiba's Cell Reference Set Beat Console device driver | ||
51 | |||
52 | config HVC_IUCV | 45 | config HVC_IUCV |
53 | bool "z/VM IUCV Hypervisor console support (VM only)" | 46 | bool "z/VM IUCV Hypervisor console support (VM only)" |
54 | depends on S390 | 47 | depends on S390 |
diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile index 4ca3723b0a3a..6a2702be76d1 100644 --- a/drivers/tty/hvc/Makefile +++ b/drivers/tty/hvc/Makefile | |||
@@ -4,7 +4,6 @@ obj-$(CONFIG_HVC_OLD_HVSI) += hvsi.o | |||
4 | obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o | 4 | obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o |
5 | obj-$(CONFIG_HVC_TILE) += hvc_tile.o | 5 | obj-$(CONFIG_HVC_TILE) += hvc_tile.o |
6 | obj-$(CONFIG_HVC_DCC) += hvc_dcc.o | 6 | obj-$(CONFIG_HVC_DCC) += hvc_dcc.o |
7 | obj-$(CONFIG_HVC_BEAT) += hvc_beat.o | ||
8 | obj-$(CONFIG_HVC_DRIVER) += hvc_console.o | 7 | obj-$(CONFIG_HVC_DRIVER) += hvc_console.o |
9 | obj-$(CONFIG_HVC_IRQ) += hvc_irq.o | 8 | obj-$(CONFIG_HVC_IRQ) += hvc_irq.o |
10 | obj-$(CONFIG_HVC_XEN) += hvc_xen.o | 9 | obj-$(CONFIG_HVC_XEN) += hvc_xen.o |
diff --git a/drivers/tty/hvc/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c deleted file mode 100644 index 1560d235449e..000000000000 --- a/drivers/tty/hvc/hvc_beat.c +++ /dev/null | |||
@@ -1,134 +0,0 @@ | |||
1 | /* | ||
2 | * Beat hypervisor console driver | ||
3 | * | ||
4 | * (C) Copyright 2006 TOSHIBA CORPORATION | ||
5 | * | ||
6 | * This code is based on drivers/char/hvc_rtas.c: | ||
7 | * (C) Copyright IBM Corporation 2001-2005 | ||
8 | * (C) Copyright Red Hat, Inc. 2005 | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/string.h> | ||
29 | #include <linux/console.h> | ||
30 | #include <asm/prom.h> | ||
31 | #include <asm/hvconsole.h> | ||
32 | #include <asm/firmware.h> | ||
33 | |||
34 | #include "hvc_console.h" | ||
35 | |||
36 | extern int64_t beat_get_term_char(uint64_t, uint64_t *, uint64_t *, uint64_t *); | ||
37 | extern int64_t beat_put_term_char(uint64_t, uint64_t, uint64_t, uint64_t); | ||
38 | |||
39 | struct hvc_struct *hvc_beat_dev = NULL; | ||
40 | |||
41 | /* bug: only one queue is available regardless of vtermno */ | ||
42 | static int hvc_beat_get_chars(uint32_t vtermno, char *buf, int cnt) | ||
43 | { | ||
44 | static unsigned char q[sizeof(unsigned long) * 2] | ||
45 | __attribute__((aligned(sizeof(unsigned long)))); | ||
46 | static int qlen = 0; | ||
47 | u64 got; | ||
48 | |||
49 | again: | ||
50 | if (qlen) { | ||
51 | if (qlen > cnt) { | ||
52 | memcpy(buf, q, cnt); | ||
53 | qlen -= cnt; | ||
54 | memmove(q + cnt, q, qlen); | ||
55 | return cnt; | ||
56 | } else { /* qlen <= cnt */ | ||
57 | int r; | ||
58 | |||
59 | memcpy(buf, q, qlen); | ||
60 | r = qlen; | ||
61 | qlen = 0; | ||
62 | return r; | ||
63 | } | ||
64 | } | ||
65 | if (beat_get_term_char(vtermno, &got, | ||
66 | ((u64 *)q), ((u64 *)q) + 1) == 0) { | ||
67 | qlen = got; | ||
68 | goto again; | ||
69 | } | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int hvc_beat_put_chars(uint32_t vtermno, const char *buf, int cnt) | ||
74 | { | ||
75 | unsigned long kb[2]; | ||
76 | int rest, nlen; | ||
77 | |||
78 | for (rest = cnt; rest > 0; rest -= nlen) { | ||
79 | nlen = (rest > 16) ? 16 : rest; | ||
80 | memcpy(kb, buf, nlen); | ||
81 | beat_put_term_char(vtermno, nlen, kb[0], kb[1]); | ||
82 | buf += nlen; | ||
83 | } | ||
84 | return cnt; | ||
85 | } | ||
86 | |||
87 | static const struct hv_ops hvc_beat_get_put_ops = { | ||
88 | .get_chars = hvc_beat_get_chars, | ||
89 | .put_chars = hvc_beat_put_chars, | ||
90 | }; | ||
91 | |||
92 | static int hvc_beat_useit = 1; | ||
93 | |||
94 | static int hvc_beat_config(char *p) | ||
95 | { | ||
96 | hvc_beat_useit = simple_strtoul(p, NULL, 0); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int __init hvc_beat_console_init(void) | ||
101 | { | ||
102 | if (hvc_beat_useit && of_machine_is_compatible("Beat")) { | ||
103 | hvc_instantiate(0, 0, &hvc_beat_get_put_ops); | ||
104 | } | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | /* temp */ | ||
109 | static int __init hvc_beat_init(void) | ||
110 | { | ||
111 | struct hvc_struct *hp; | ||
112 | |||
113 | if (!firmware_has_feature(FW_FEATURE_BEAT)) | ||
114 | return -ENODEV; | ||
115 | |||
116 | hp = hvc_alloc(0, 0, &hvc_beat_get_put_ops, 16); | ||
117 | if (IS_ERR(hp)) | ||
118 | return PTR_ERR(hp); | ||
119 | hvc_beat_dev = hp; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static void __exit hvc_beat_exit(void) | ||
124 | { | ||
125 | if (hvc_beat_dev) | ||
126 | hvc_remove(hvc_beat_dev); | ||
127 | } | ||
128 | |||
129 | module_init(hvc_beat_init); | ||
130 | module_exit(hvc_beat_exit); | ||
131 | |||
132 | __setup("hvc_beat=", hvc_beat_config); | ||
133 | |||
134 | console_initcall(hvc_beat_console_init); | ||
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 4fcec1d793a7..4e9c4cc9e1b5 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
@@ -319,7 +319,8 @@ static int hvc_install(struct tty_driver *driver, struct tty_struct *tty) | |||
319 | int rc; | 319 | int rc; |
320 | 320 | ||
321 | /* Auto increments kref reference if found. */ | 321 | /* Auto increments kref reference if found. */ |
322 | if (!(hp = hvc_get_by_index(tty->index))) | 322 | hp = hvc_get_by_index(tty->index); |
323 | if (!hp) | ||
323 | return -ENODEV; | 324 | return -ENODEV; |
324 | 325 | ||
325 | tty->driver_data = hp; | 326 | tty->driver_data = hp; |
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 81ff7e1bfb1a..f7ff97c0ad34 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
@@ -1044,8 +1044,8 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address, | |||
1044 | * It is possible that the vty-server was removed between the time that | 1044 | * It is possible that the vty-server was removed between the time that |
1045 | * the conn was registered and now. | 1045 | * the conn was registered and now. |
1046 | */ | 1046 | */ |
1047 | if (!(rc = request_irq(irq, &hvcs_handle_interrupt, | 1047 | rc = request_irq(irq, &hvcs_handle_interrupt, 0, "ibmhvcs", hvcsd); |
1048 | 0, "ibmhvcs", hvcsd))) { | 1048 | if (!rc) { |
1049 | /* | 1049 | /* |
1050 | * It is possible the vty-server was removed after the irq was | 1050 | * It is possible the vty-server was removed after the irq was |
1051 | * requested but before we have time to enable interrupts. | 1051 | * requested but before we have time to enable interrupts. |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 2c34c3249972..382d3fcba6cc 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -161,7 +161,7 @@ struct gsm_dlci { | |||
161 | struct net_device *net; /* network interface, if created */ | 161 | struct net_device *net; /* network interface, if created */ |
162 | }; | 162 | }; |
163 | 163 | ||
164 | /* DLCI 0, 62/63 are special or reseved see gsmtty_open */ | 164 | /* DLCI 0, 62/63 are special or reserved see gsmtty_open */ |
165 | 165 | ||
166 | #define NUM_DLCI 64 | 166 | #define NUM_DLCI 64 |
167 | 167 | ||
@@ -2274,7 +2274,6 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2274 | const unsigned char *dp; | 2274 | const unsigned char *dp; |
2275 | char *f; | 2275 | char *f; |
2276 | int i; | 2276 | int i; |
2277 | char buf[64]; | ||
2278 | char flags = TTY_NORMAL; | 2277 | char flags = TTY_NORMAL; |
2279 | 2278 | ||
2280 | if (debug & 4) | 2279 | if (debug & 4) |
@@ -2296,7 +2295,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2296 | break; | 2295 | break; |
2297 | default: | 2296 | default: |
2298 | WARN_ONCE(1, "%s: unknown flag %d\n", | 2297 | WARN_ONCE(1, "%s: unknown flag %d\n", |
2299 | tty_name(tty, buf), flags); | 2298 | tty_name(tty), flags); |
2300 | break; | 2299 | break; |
2301 | } | 2300 | } |
2302 | } | 2301 | } |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 396344cb011f..c9c27f69e101 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -1190,13 +1190,12 @@ static void n_tty_receive_break(struct tty_struct *tty) | |||
1190 | static void n_tty_receive_overrun(struct tty_struct *tty) | 1190 | static void n_tty_receive_overrun(struct tty_struct *tty) |
1191 | { | 1191 | { |
1192 | struct n_tty_data *ldata = tty->disc_data; | 1192 | struct n_tty_data *ldata = tty->disc_data; |
1193 | char buf[64]; | ||
1194 | 1193 | ||
1195 | ldata->num_overrun++; | 1194 | ldata->num_overrun++; |
1196 | if (time_after(jiffies, ldata->overrun_time + HZ) || | 1195 | if (time_after(jiffies, ldata->overrun_time + HZ) || |
1197 | time_after(ldata->overrun_time, jiffies)) { | 1196 | time_after(ldata->overrun_time, jiffies)) { |
1198 | printk(KERN_WARNING "%s: %d input overrun(s)\n", | 1197 | printk(KERN_WARNING "%s: %d input overrun(s)\n", |
1199 | tty_name(tty, buf), | 1198 | tty_name(tty), |
1200 | ldata->num_overrun); | 1199 | ldata->num_overrun); |
1201 | ldata->overrun_time = jiffies; | 1200 | ldata->overrun_time = jiffies; |
1202 | ldata->num_overrun = 0; | 1201 | ldata->num_overrun = 0; |
@@ -1471,8 +1470,6 @@ static void n_tty_receive_char_closing(struct tty_struct *tty, unsigned char c) | |||
1471 | static void | 1470 | static void |
1472 | n_tty_receive_char_flagged(struct tty_struct *tty, unsigned char c, char flag) | 1471 | n_tty_receive_char_flagged(struct tty_struct *tty, unsigned char c, char flag) |
1473 | { | 1472 | { |
1474 | char buf[64]; | ||
1475 | |||
1476 | switch (flag) { | 1473 | switch (flag) { |
1477 | case TTY_BREAK: | 1474 | case TTY_BREAK: |
1478 | n_tty_receive_break(tty); | 1475 | n_tty_receive_break(tty); |
@@ -1486,7 +1483,7 @@ n_tty_receive_char_flagged(struct tty_struct *tty, unsigned char c, char flag) | |||
1486 | break; | 1483 | break; |
1487 | default: | 1484 | default: |
1488 | printk(KERN_ERR "%s: unknown flag %d\n", | 1485 | printk(KERN_ERR "%s: unknown flag %d\n", |
1489 | tty_name(tty, buf), flag); | 1486 | tty_name(tty), flag); |
1490 | break; | 1487 | break; |
1491 | } | 1488 | } |
1492 | } | 1489 | } |
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 74885af8c7bd..80f9de907563 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -140,8 +140,8 @@ static int debug; | |||
140 | #define R_FCR 0x0000 /* Flow Control Register */ | 140 | #define R_FCR 0x0000 /* Flow Control Register */ |
141 | #define R_IER 0x0004 /* Interrupt Enable Register */ | 141 | #define R_IER 0x0004 /* Interrupt Enable Register */ |
142 | 142 | ||
143 | #define CONFIG_MAGIC 0xEFEFFEFE | 143 | #define NOZOMI_CONFIG_MAGIC 0xEFEFFEFE |
144 | #define TOGGLE_VALID 0x0000 | 144 | #define TOGGLE_VALID 0x0000 |
145 | 145 | ||
146 | /* Definition of interrupt tokens */ | 146 | /* Definition of interrupt tokens */ |
147 | #define MDM_DL1 0x0001 | 147 | #define MDM_DL1 0x0001 |
@@ -660,9 +660,9 @@ static int nozomi_read_config_table(struct nozomi *dc) | |||
660 | read_mem32((u32 *) &dc->config_table, dc->base_addr + 0, | 660 | read_mem32((u32 *) &dc->config_table, dc->base_addr + 0, |
661 | sizeof(struct config_table)); | 661 | sizeof(struct config_table)); |
662 | 662 | ||
663 | if (dc->config_table.signature != CONFIG_MAGIC) { | 663 | if (dc->config_table.signature != NOZOMI_CONFIG_MAGIC) { |
664 | dev_err(&dc->pdev->dev, "ConfigTable Bad! 0x%08X != 0x%08X\n", | 664 | dev_err(&dc->pdev->dev, "ConfigTable Bad! 0x%08X != 0x%08X\n", |
665 | dc->config_table.signature, CONFIG_MAGIC); | 665 | dc->config_table.signature, NOZOMI_CONFIG_MAGIC); |
666 | return 0; | 666 | return 0; |
667 | } | 667 | } |
668 | 668 | ||
diff --git a/drivers/tty/rocket.h b/drivers/tty/rocket.h index ec863f35f1a9..c11a9392f219 100644 --- a/drivers/tty/rocket.h +++ b/drivers/tty/rocket.h | |||
@@ -44,7 +44,7 @@ struct rocket_version { | |||
44 | #define ROCKET_HUP_NOTIFY 0x00000004 | 44 | #define ROCKET_HUP_NOTIFY 0x00000004 |
45 | #define ROCKET_SPLIT_TERMIOS 0x00000008 | 45 | #define ROCKET_SPLIT_TERMIOS 0x00000008 |
46 | #define ROCKET_SPD_MASK 0x00000070 | 46 | #define ROCKET_SPD_MASK 0x00000070 |
47 | #define ROCKET_SPD_HI 0x00000010 /* Use 56000 instead of 38400 bps */ | 47 | #define ROCKET_SPD_HI 0x00000010 /* Use 57600 instead of 38400 bps */ |
48 | #define ROCKET_SPD_VHI 0x00000020 /* Use 115200 instead of 38400 bps */ | 48 | #define ROCKET_SPD_VHI 0x00000020 /* Use 115200 instead of 38400 bps */ |
49 | #define ROCKET_SPD_SHI 0x00000030 /* Use 230400 instead of 38400 bps */ | 49 | #define ROCKET_SPD_SHI 0x00000030 /* Use 230400 instead of 38400 bps */ |
50 | #define ROCKET_SPD_WARP 0x00000040 /* Use 460800 instead of 38400 bps */ | 50 | #define ROCKET_SPD_WARP 0x00000040 /* Use 460800 instead of 38400 bps */ |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 5dc9c4bfa66e..748c18f8c8cd 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
@@ -508,7 +508,8 @@ static void change_speed(struct m68k_serial *info, struct tty_struct *tty) | |||
508 | int i; | 508 | int i; |
509 | 509 | ||
510 | cflag = tty->termios.c_cflag; | 510 | cflag = tty->termios.c_cflag; |
511 | if (!(port = info->port)) | 511 | port = info->port; |
512 | if (!port) | ||
512 | return; | 513 | return; |
513 | 514 | ||
514 | ustcnt = uart->ustcnt; | 515 | ustcnt = uart->ustcnt; |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 4506e405c8f3..37fff12dd4d0 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -85,19 +85,6 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ | |||
85 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | 85 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
86 | 86 | ||
87 | 87 | ||
88 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ | ||
89 | #define CONFIG_SERIAL_DETECT_IRQ 1 | ||
90 | #endif | ||
91 | #ifdef CONFIG_SERIAL_8250_MANY_PORTS | ||
92 | #define CONFIG_SERIAL_MANY_PORTS 1 | ||
93 | #endif | ||
94 | |||
95 | /* | ||
96 | * HUB6 is always on. This will be removed once the header | ||
97 | * files have been cleaned. | ||
98 | */ | ||
99 | #define CONFIG_HUB6 1 | ||
100 | |||
101 | #include <asm/serial.h> | 88 | #include <asm/serial.h> |
102 | /* | 89 | /* |
103 | * SERIAL_PORT_DFNS tells us about built-in ports that have no | 90 | * SERIAL_PORT_DFNS tells us about built-in ports that have no |
@@ -2019,8 +2006,9 @@ EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); | |||
2019 | static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | 2006 | static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) |
2020 | { | 2007 | { |
2021 | if (port->set_mctrl) | 2008 | if (port->set_mctrl) |
2022 | return port->set_mctrl(port, mctrl); | 2009 | port->set_mctrl(port, mctrl); |
2023 | return serial8250_do_set_mctrl(port, mctrl); | 2010 | else |
2011 | serial8250_do_set_mctrl(port, mctrl); | ||
2024 | } | 2012 | } |
2025 | 2013 | ||
2026 | static void serial8250_break_ctl(struct uart_port *port, int break_state) | 2014 | static void serial8250_break_ctl(struct uart_port *port, int break_state) |
@@ -3548,6 +3536,9 @@ static struct console univ8250_console = { | |||
3548 | 3536 | ||
3549 | static int __init univ8250_console_init(void) | 3537 | static int __init univ8250_console_init(void) |
3550 | { | 3538 | { |
3539 | if (nr_uarts == 0) | ||
3540 | return -ENODEV; | ||
3541 | |||
3551 | serial8250_isa_init_ports(); | 3542 | serial8250_isa_init_ports(); |
3552 | register_console(&univ8250_console); | 3543 | register_console(&univ8250_console); |
3553 | return 0; | 3544 | return 0; |
@@ -3578,7 +3569,7 @@ int __init early_serial_setup(struct uart_port *port) | |||
3578 | { | 3569 | { |
3579 | struct uart_port *p; | 3570 | struct uart_port *p; |
3580 | 3571 | ||
3581 | if (port->line >= ARRAY_SIZE(serial8250_ports)) | 3572 | if (port->line >= ARRAY_SIZE(serial8250_ports) || nr_uarts == 0) |
3582 | return -ENODEV; | 3573 | return -ENODEV; |
3583 | 3574 | ||
3584 | serial8250_isa_init_ports(); | 3575 | serial8250_isa_init_ports(); |
@@ -3850,7 +3841,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3850 | uart->port.mapbase = up->port.mapbase; | 3841 | uart->port.mapbase = up->port.mapbase; |
3851 | uart->port.mapsize = up->port.mapsize; | 3842 | uart->port.mapsize = up->port.mapsize; |
3852 | uart->port.private_data = up->port.private_data; | 3843 | uart->port.private_data = up->port.private_data; |
3853 | uart->port.fifosize = up->port.fifosize; | ||
3854 | uart->tx_loadsz = up->tx_loadsz; | 3844 | uart->tx_loadsz = up->tx_loadsz; |
3855 | uart->capabilities = up->capabilities; | 3845 | uart->capabilities = up->capabilities; |
3856 | uart->port.throttle = up->port.throttle; | 3846 | uart->port.throttle = up->port.throttle; |
@@ -3945,6 +3935,9 @@ static int __init serial8250_init(void) | |||
3945 | { | 3935 | { |
3946 | int ret; | 3936 | int ret; |
3947 | 3937 | ||
3938 | if (nr_uarts == 0) | ||
3939 | return -ENODEV; | ||
3940 | |||
3948 | serial8250_isa_init_ports(); | 3941 | serial8250_isa_init_ports(); |
3949 | 3942 | ||
3950 | printk(KERN_INFO "Serial: 8250/16550 driver, " | 3943 | printk(KERN_INFO "Serial: 8250/16550 driver, " |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 176f18f2e3ab..d48b50641e9a 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -377,6 +377,16 @@ static int dw8250_probe_of(struct uart_port *p, | |||
377 | return 0; | 377 | return 0; |
378 | } | 378 | } |
379 | 379 | ||
380 | static bool dw8250_idma_filter(struct dma_chan *chan, void *param) | ||
381 | { | ||
382 | struct device *dev = param; | ||
383 | |||
384 | if (dev != chan->device->dev->parent) | ||
385 | return false; | ||
386 | |||
387 | return true; | ||
388 | } | ||
389 | |||
380 | static int dw8250_probe_acpi(struct uart_8250_port *up, | 390 | static int dw8250_probe_acpi(struct uart_8250_port *up, |
381 | struct dw8250_data *data) | 391 | struct dw8250_data *data) |
382 | { | 392 | { |
@@ -389,8 +399,15 @@ static int dw8250_probe_acpi(struct uart_8250_port *up, | |||
389 | p->serial_out = dw8250_serial_out32; | 399 | p->serial_out = dw8250_serial_out32; |
390 | p->regshift = 2; | 400 | p->regshift = 2; |
391 | 401 | ||
392 | up->dma = &data->dma; | 402 | /* Platforms with iDMA */ |
403 | if (platform_get_resource_byname(to_platform_device(up->port.dev), | ||
404 | IORESOURCE_MEM, "lpss_priv")) { | ||
405 | data->dma.rx_param = up->port.dev->parent; | ||
406 | data->dma.tx_param = up->port.dev->parent; | ||
407 | data->dma.fn = dw8250_idma_filter; | ||
408 | } | ||
393 | 409 | ||
410 | up->dma = &data->dma; | ||
394 | up->dma->rxconf.src_maxburst = p->fifosize / 4; | 411 | up->dma->rxconf.src_maxburst = p->fifosize / 4; |
395 | up->dma->txconf.dst_maxburst = p->fifosize / 4; | 412 | up->dma->txconf.dst_maxburst = p->fifosize / 4; |
396 | 413 | ||
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 6c0fd8b9d1c3..771dda29a0f8 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c | |||
@@ -131,7 +131,7 @@ static void __init init_port(struct earlycon_device *device) | |||
131 | serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); | 131 | serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); |
132 | } | 132 | } |
133 | 133 | ||
134 | static int __init early_serial8250_setup(struct earlycon_device *device, | 134 | int __init early_serial8250_setup(struct earlycon_device *device, |
135 | const char *options) | 135 | const char *options) |
136 | { | 136 | { |
137 | if (!(device->port.membase || device->port.iobase)) | 137 | if (!(device->port.membase || device->port.iobase)) |
diff --git a/drivers/tty/serial/8250/8250_lpc18xx.c b/drivers/tty/serial/8250/8250_lpc18xx.c new file mode 100644 index 000000000000..99cd478851ff --- /dev/null +++ b/drivers/tty/serial/8250/8250_lpc18xx.c | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | * Serial port driver for NXP LPC18xx/43xx UART | ||
3 | * | ||
4 | * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> | ||
5 | * | ||
6 | * Based on 8250_mtk.c: | ||
7 | * Copyright (c) 2014 MundoReader S.L. | ||
8 | * Matthias Brugger <matthias.bgg@gmail.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/clk.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | #include "8250.h" | ||
23 | |||
24 | /* Additional LPC18xx/43xx 8250 registers and bits */ | ||
25 | #define LPC18XX_UART_RS485CTRL (0x04c / sizeof(u32)) | ||
26 | #define LPC18XX_UART_RS485CTRL_NMMEN BIT(0) | ||
27 | #define LPC18XX_UART_RS485CTRL_DCTRL BIT(4) | ||
28 | #define LPC18XX_UART_RS485CTRL_OINV BIT(5) | ||
29 | #define LPC18XX_UART_RS485DLY (0x054 / sizeof(u32)) | ||
30 | #define LPC18XX_UART_RS485DLY_MAX 255 | ||
31 | |||
32 | struct lpc18xx_uart_data { | ||
33 | struct uart_8250_dma dma; | ||
34 | struct clk *clk_uart; | ||
35 | struct clk *clk_reg; | ||
36 | int line; | ||
37 | }; | ||
38 | |||
39 | static int lpc18xx_rs485_config(struct uart_port *port, | ||
40 | struct serial_rs485 *rs485) | ||
41 | { | ||
42 | struct uart_8250_port *up = up_to_u8250p(port); | ||
43 | u32 rs485_ctrl_reg = 0; | ||
44 | u32 rs485_dly_reg = 0; | ||
45 | unsigned baud_clk; | ||
46 | |||
47 | if (rs485->flags & SER_RS485_ENABLED) | ||
48 | memset(rs485->padding, 0, sizeof(rs485->padding)); | ||
49 | else | ||
50 | memset(rs485, 0, sizeof(*rs485)); | ||
51 | |||
52 | rs485->flags &= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | | ||
53 | SER_RS485_RTS_AFTER_SEND; | ||
54 | |||
55 | if (rs485->flags & SER_RS485_ENABLED) { | ||
56 | rs485_ctrl_reg |= LPC18XX_UART_RS485CTRL_NMMEN | | ||
57 | LPC18XX_UART_RS485CTRL_DCTRL; | ||
58 | |||
59 | if (rs485->flags & SER_RS485_RTS_ON_SEND) { | ||
60 | rs485_ctrl_reg |= LPC18XX_UART_RS485CTRL_OINV; | ||
61 | rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; | ||
62 | } else { | ||
63 | rs485->flags |= SER_RS485_RTS_AFTER_SEND; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | if (rs485->delay_rts_after_send) { | ||
68 | baud_clk = port->uartclk / up->dl_read(up); | ||
69 | rs485_dly_reg = DIV_ROUND_UP(rs485->delay_rts_after_send | ||
70 | * baud_clk, MSEC_PER_SEC); | ||
71 | |||
72 | if (rs485_dly_reg > LPC18XX_UART_RS485DLY_MAX) | ||
73 | rs485_dly_reg = LPC18XX_UART_RS485DLY_MAX; | ||
74 | |||
75 | /* Calculate the resulting delay in ms */ | ||
76 | rs485->delay_rts_after_send = (rs485_dly_reg * MSEC_PER_SEC) | ||
77 | / baud_clk; | ||
78 | } | ||
79 | |||
80 | /* Delay RTS before send not supported */ | ||
81 | rs485->delay_rts_before_send = 0; | ||
82 | |||
83 | serial_out(up, LPC18XX_UART_RS485CTRL, rs485_ctrl_reg); | ||
84 | serial_out(up, LPC18XX_UART_RS485DLY, rs485_dly_reg); | ||
85 | |||
86 | port->rs485 = *rs485; | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static void lpc18xx_uart_serial_out(struct uart_port *p, int offset, int value) | ||
92 | { | ||
93 | /* | ||
94 | * For DMA mode one must ensure that the UART_FCR_DMA_SELECT | ||
95 | * bit is set when FIFO is enabled. Even if DMA is not used | ||
96 | * setting this bit doesn't seem to affect anything. | ||
97 | */ | ||
98 | if (offset == UART_FCR && (value & UART_FCR_ENABLE_FIFO)) | ||
99 | value |= UART_FCR_DMA_SELECT; | ||
100 | |||
101 | offset = offset << p->regshift; | ||
102 | writel(value, p->membase + offset); | ||
103 | } | ||
104 | |||
105 | static int lpc18xx_serial_probe(struct platform_device *pdev) | ||
106 | { | ||
107 | struct lpc18xx_uart_data *data; | ||
108 | struct uart_8250_port uart; | ||
109 | struct resource *res; | ||
110 | int irq, ret; | ||
111 | |||
112 | irq = platform_get_irq(pdev, 0); | ||
113 | if (irq < 0) { | ||
114 | dev_err(&pdev->dev, "irq not found"); | ||
115 | return irq; | ||
116 | } | ||
117 | |||
118 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
119 | if (!res) { | ||
120 | dev_err(&pdev->dev, "memory resource not found"); | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | memset(&uart, 0, sizeof(uart)); | ||
125 | |||
126 | uart.port.membase = devm_ioremap(&pdev->dev, res->start, | ||
127 | resource_size(res)); | ||
128 | if (!uart.port.membase) | ||
129 | return -ENOMEM; | ||
130 | |||
131 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
132 | if (!data) | ||
133 | return -ENOMEM; | ||
134 | |||
135 | data->clk_uart = devm_clk_get(&pdev->dev, "uartclk"); | ||
136 | if (IS_ERR(data->clk_uart)) { | ||
137 | dev_err(&pdev->dev, "uart clock not found\n"); | ||
138 | return PTR_ERR(data->clk_uart); | ||
139 | } | ||
140 | |||
141 | data->clk_reg = devm_clk_get(&pdev->dev, "reg"); | ||
142 | if (IS_ERR(data->clk_reg)) { | ||
143 | dev_err(&pdev->dev, "reg clock not found\n"); | ||
144 | return PTR_ERR(data->clk_reg); | ||
145 | } | ||
146 | |||
147 | ret = clk_prepare_enable(data->clk_reg); | ||
148 | if (ret) { | ||
149 | dev_err(&pdev->dev, "unable to enable reg clock\n"); | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | ret = clk_prepare_enable(data->clk_uart); | ||
154 | if (ret) { | ||
155 | dev_err(&pdev->dev, "unable to enable uart clock\n"); | ||
156 | goto dis_clk_reg; | ||
157 | } | ||
158 | |||
159 | ret = of_alias_get_id(pdev->dev.of_node, "serial"); | ||
160 | if (ret >= 0) | ||
161 | uart.port.line = ret; | ||
162 | |||
163 | data->dma.rx_param = data; | ||
164 | data->dma.tx_param = data; | ||
165 | |||
166 | spin_lock_init(&uart.port.lock); | ||
167 | uart.port.dev = &pdev->dev; | ||
168 | uart.port.irq = irq; | ||
169 | uart.port.iotype = UPIO_MEM32; | ||
170 | uart.port.mapbase = res->start; | ||
171 | uart.port.regshift = 2; | ||
172 | uart.port.type = PORT_16550A; | ||
173 | uart.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_SKIP_TEST; | ||
174 | uart.port.uartclk = clk_get_rate(data->clk_uart); | ||
175 | uart.port.private_data = data; | ||
176 | uart.port.rs485_config = lpc18xx_rs485_config; | ||
177 | uart.port.serial_out = lpc18xx_uart_serial_out; | ||
178 | |||
179 | uart.dma = &data->dma; | ||
180 | uart.dma->rxconf.src_maxburst = 1; | ||
181 | uart.dma->txconf.dst_maxburst = 1; | ||
182 | |||
183 | ret = serial8250_register_8250_port(&uart); | ||
184 | if (ret < 0) { | ||
185 | dev_err(&pdev->dev, "unable to register 8250 port\n"); | ||
186 | goto dis_uart_clk; | ||
187 | } | ||
188 | |||
189 | data->line = ret; | ||
190 | platform_set_drvdata(pdev, data); | ||
191 | |||
192 | return 0; | ||
193 | |||
194 | dis_uart_clk: | ||
195 | clk_disable_unprepare(data->clk_uart); | ||
196 | dis_clk_reg: | ||
197 | clk_disable_unprepare(data->clk_reg); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | static int lpc18xx_serial_remove(struct platform_device *pdev) | ||
202 | { | ||
203 | struct lpc18xx_uart_data *data = platform_get_drvdata(pdev); | ||
204 | |||
205 | serial8250_unregister_port(data->line); | ||
206 | clk_disable_unprepare(data->clk_uart); | ||
207 | clk_disable_unprepare(data->clk_reg); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static const struct of_device_id lpc18xx_serial_match[] = { | ||
213 | { .compatible = "nxp,lpc1850-uart" }, | ||
214 | { }, | ||
215 | }; | ||
216 | MODULE_DEVICE_TABLE(of, lpc18xx_serial_match); | ||
217 | |||
218 | static struct platform_driver lpc18xx_serial_driver = { | ||
219 | .probe = lpc18xx_serial_probe, | ||
220 | .remove = lpc18xx_serial_remove, | ||
221 | .driver = { | ||
222 | .name = "lpc18xx-uart", | ||
223 | .of_match_table = lpc18xx_serial_match, | ||
224 | }, | ||
225 | }; | ||
226 | module_platform_driver(lpc18xx_serial_driver); | ||
227 | |||
228 | MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>"); | ||
229 | MODULE_DESCRIPTION("Serial port driver NXP LPC18xx/43xx devices"); | ||
230 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 7a11fac775c4..78883ca64ddd 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c | |||
@@ -34,6 +34,7 @@ | |||
34 | struct mtk8250_data { | 34 | struct mtk8250_data { |
35 | int line; | 35 | int line; |
36 | struct clk *uart_clk; | 36 | struct clk *uart_clk; |
37 | struct clk *bus_clk; | ||
37 | }; | 38 | }; |
38 | 39 | ||
39 | static void | 40 | static void |
@@ -115,6 +116,36 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, | |||
115 | tty_termios_encode_baud_rate(termios, baud, baud); | 116 | tty_termios_encode_baud_rate(termios, baud, baud); |
116 | } | 117 | } |
117 | 118 | ||
119 | static int mtk8250_runtime_suspend(struct device *dev) | ||
120 | { | ||
121 | struct mtk8250_data *data = dev_get_drvdata(dev); | ||
122 | |||
123 | clk_disable_unprepare(data->uart_clk); | ||
124 | clk_disable_unprepare(data->bus_clk); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int mtk8250_runtime_resume(struct device *dev) | ||
130 | { | ||
131 | struct mtk8250_data *data = dev_get_drvdata(dev); | ||
132 | int err; | ||
133 | |||
134 | err = clk_prepare_enable(data->uart_clk); | ||
135 | if (err) { | ||
136 | dev_warn(dev, "Can't enable clock\n"); | ||
137 | return err; | ||
138 | } | ||
139 | |||
140 | err = clk_prepare_enable(data->bus_clk); | ||
141 | if (err) { | ||
142 | dev_warn(dev, "Can't enable bus clock\n"); | ||
143 | return err; | ||
144 | } | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
118 | static void | 149 | static void |
119 | mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) | 150 | mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) |
120 | { | 151 | { |
@@ -130,22 +161,24 @@ mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) | |||
130 | static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, | 161 | static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, |
131 | struct mtk8250_data *data) | 162 | struct mtk8250_data *data) |
132 | { | 163 | { |
133 | int err; | 164 | data->uart_clk = devm_clk_get(&pdev->dev, "baud"); |
134 | struct device_node *np = pdev->dev.of_node; | ||
135 | |||
136 | data->uart_clk = of_clk_get(np, 0); | ||
137 | if (IS_ERR(data->uart_clk)) { | 165 | if (IS_ERR(data->uart_clk)) { |
138 | dev_warn(&pdev->dev, "Can't get timer clock\n"); | 166 | /* |
139 | return PTR_ERR(data->uart_clk); | 167 | * For compatibility with older device trees try unnamed |
168 | * clk when no baud clk can be found. | ||
169 | */ | ||
170 | data->uart_clk = devm_clk_get(&pdev->dev, NULL); | ||
171 | if (IS_ERR(data->uart_clk)) { | ||
172 | dev_warn(&pdev->dev, "Can't get uart clock\n"); | ||
173 | return PTR_ERR(data->uart_clk); | ||
174 | } | ||
175 | |||
176 | return 0; | ||
140 | } | 177 | } |
141 | 178 | ||
142 | err = clk_prepare_enable(data->uart_clk); | 179 | data->bus_clk = devm_clk_get(&pdev->dev, "bus"); |
143 | if (err) { | 180 | if (IS_ERR(data->bus_clk)) |
144 | dev_warn(&pdev->dev, "Can't prepare clock\n"); | 181 | return PTR_ERR(data->bus_clk); |
145 | clk_put(data->uart_clk); | ||
146 | return err; | ||
147 | } | ||
148 | p->uartclk = clk_get_rate(data->uart_clk); | ||
149 | 182 | ||
150 | return 0; | 183 | return 0; |
151 | } | 184 | } |
@@ -190,19 +223,24 @@ static int mtk8250_probe(struct platform_device *pdev) | |||
190 | uart.port.regshift = 2; | 223 | uart.port.regshift = 2; |
191 | uart.port.private_data = data; | 224 | uart.port.private_data = data; |
192 | uart.port.set_termios = mtk8250_set_termios; | 225 | uart.port.set_termios = mtk8250_set_termios; |
226 | uart.port.uartclk = clk_get_rate(data->uart_clk); | ||
193 | 227 | ||
194 | /* Disable Rate Fix function */ | 228 | /* Disable Rate Fix function */ |
195 | writel(0x0, uart.port.membase + | 229 | writel(0x0, uart.port.membase + |
196 | (MTK_UART_RATE_FIX << uart.port.regshift)); | 230 | (MTK_UART_RATE_FIX << uart.port.regshift)); |
197 | 231 | ||
198 | data->line = serial8250_register_8250_port(&uart); | ||
199 | if (data->line < 0) | ||
200 | return data->line; | ||
201 | |||
202 | platform_set_drvdata(pdev, data); | 232 | platform_set_drvdata(pdev, data); |
203 | 233 | ||
204 | pm_runtime_set_active(&pdev->dev); | ||
205 | pm_runtime_enable(&pdev->dev); | 234 | pm_runtime_enable(&pdev->dev); |
235 | if (!pm_runtime_enabled(&pdev->dev)) { | ||
236 | err = mtk8250_runtime_resume(&pdev->dev); | ||
237 | if (err) | ||
238 | return err; | ||
239 | } | ||
240 | |||
241 | data->line = serial8250_register_8250_port(&uart); | ||
242 | if (data->line < 0) | ||
243 | return data->line; | ||
206 | 244 | ||
207 | return 0; | 245 | return 0; |
208 | } | 246 | } |
@@ -214,13 +252,13 @@ static int mtk8250_remove(struct platform_device *pdev) | |||
214 | pm_runtime_get_sync(&pdev->dev); | 252 | pm_runtime_get_sync(&pdev->dev); |
215 | 253 | ||
216 | serial8250_unregister_port(data->line); | 254 | serial8250_unregister_port(data->line); |
217 | if (!IS_ERR(data->uart_clk)) { | ||
218 | clk_disable_unprepare(data->uart_clk); | ||
219 | clk_put(data->uart_clk); | ||
220 | } | ||
221 | 255 | ||
222 | pm_runtime_disable(&pdev->dev); | 256 | pm_runtime_disable(&pdev->dev); |
223 | pm_runtime_put_noidle(&pdev->dev); | 257 | pm_runtime_put_noidle(&pdev->dev); |
258 | |||
259 | if (!pm_runtime_status_suspended(&pdev->dev)) | ||
260 | mtk8250_runtime_suspend(&pdev->dev); | ||
261 | |||
224 | return 0; | 262 | return 0; |
225 | } | 263 | } |
226 | 264 | ||
@@ -244,28 +282,6 @@ static int mtk8250_resume(struct device *dev) | |||
244 | } | 282 | } |
245 | #endif /* CONFIG_PM_SLEEP */ | 283 | #endif /* CONFIG_PM_SLEEP */ |
246 | 284 | ||
247 | #ifdef CONFIG_PM | ||
248 | static int mtk8250_runtime_suspend(struct device *dev) | ||
249 | { | ||
250 | struct mtk8250_data *data = dev_get_drvdata(dev); | ||
251 | |||
252 | if (!IS_ERR(data->uart_clk)) | ||
253 | clk_disable_unprepare(data->uart_clk); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int mtk8250_runtime_resume(struct device *dev) | ||
259 | { | ||
260 | struct mtk8250_data *data = dev_get_drvdata(dev); | ||
261 | |||
262 | if (!IS_ERR(data->uart_clk)) | ||
263 | clk_prepare_enable(data->uart_clk); | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | #endif | ||
268 | |||
269 | static const struct dev_pm_ops mtk8250_pm_ops = { | 285 | static const struct dev_pm_ops mtk8250_pm_ops = { |
270 | SET_SYSTEM_SLEEP_PM_OPS(mtk8250_suspend, mtk8250_resume) | 286 | SET_SYSTEM_SLEEP_PM_OPS(mtk8250_suspend, mtk8250_resume) |
271 | SET_RUNTIME_PM_OPS(mtk8250_runtime_suspend, mtk8250_runtime_resume, | 287 | SET_RUNTIME_PM_OPS(mtk8250_runtime_suspend, mtk8250_runtime_resume, |
@@ -289,6 +305,21 @@ static struct platform_driver mtk8250_platform_driver = { | |||
289 | }; | 305 | }; |
290 | module_platform_driver(mtk8250_platform_driver); | 306 | module_platform_driver(mtk8250_platform_driver); |
291 | 307 | ||
308 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
309 | static int __init early_mtk8250_setup(struct earlycon_device *device, | ||
310 | const char *options) | ||
311 | { | ||
312 | if (!device->port.membase) | ||
313 | return -ENODEV; | ||
314 | |||
315 | device->port.iotype = UPIO_MEM32; | ||
316 | |||
317 | return early_serial8250_setup(device, NULL); | ||
318 | } | ||
319 | |||
320 | OF_EARLYCON_DECLARE(mtk8250, "mediatek,mt6577-uart", early_mtk8250_setup); | ||
321 | #endif | ||
322 | |||
292 | MODULE_AUTHOR("Matthias Brugger"); | 323 | MODULE_AUTHOR("Matthias Brugger"); |
293 | MODULE_LICENSE("GPL"); | 324 | MODULE_LICENSE("GPL"); |
294 | MODULE_DESCRIPTION("Mediatek 8250 serial port driver"); | 325 | MODULE_DESCRIPTION("Mediatek 8250 serial port driver"); |
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index dce1a23706e8..978204333c94 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c | |||
@@ -98,6 +98,7 @@ struct omap8250_priv { | |||
98 | struct pm_qos_request pm_qos_request; | 98 | struct pm_qos_request pm_qos_request; |
99 | struct work_struct qos_work; | 99 | struct work_struct qos_work; |
100 | struct uart_8250_dma omap8250_dma; | 100 | struct uart_8250_dma omap8250_dma; |
101 | spinlock_t rx_dma_lock; | ||
101 | }; | 102 | }; |
102 | 103 | ||
103 | static u32 uart_read(struct uart_8250_port *up, u32 reg) | 104 | static u32 uart_read(struct uart_8250_port *up, u32 reg) |
@@ -726,14 +727,21 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir); | |||
726 | 727 | ||
727 | static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) | 728 | static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) |
728 | { | 729 | { |
730 | struct omap8250_priv *priv = p->port.private_data; | ||
729 | struct uart_8250_dma *dma = p->dma; | 731 | struct uart_8250_dma *dma = p->dma; |
730 | struct tty_port *tty_port = &p->port.state->port; | 732 | struct tty_port *tty_port = &p->port.state->port; |
731 | struct dma_tx_state state; | 733 | struct dma_tx_state state; |
732 | int count; | 734 | int count; |
735 | unsigned long flags; | ||
733 | 736 | ||
734 | dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, | 737 | dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, |
735 | dma->rx_size, DMA_FROM_DEVICE); | 738 | dma->rx_size, DMA_FROM_DEVICE); |
736 | 739 | ||
740 | spin_lock_irqsave(&priv->rx_dma_lock, flags); | ||
741 | |||
742 | if (!dma->rx_running) | ||
743 | goto unlock; | ||
744 | |||
737 | dma->rx_running = 0; | 745 | dma->rx_running = 0; |
738 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | 746 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
739 | dmaengine_terminate_all(dma->rxchan); | 747 | dmaengine_terminate_all(dma->rxchan); |
@@ -742,6 +750,9 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) | |||
742 | 750 | ||
743 | tty_insert_flip_string(tty_port, dma->rx_buf, count); | 751 | tty_insert_flip_string(tty_port, dma->rx_buf, count); |
744 | p->port.icount.rx += count; | 752 | p->port.icount.rx += count; |
753 | unlock: | ||
754 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); | ||
755 | |||
745 | if (!error) | 756 | if (!error) |
746 | omap_8250_rx_dma(p, 0); | 757 | omap_8250_rx_dma(p, 0); |
747 | 758 | ||
@@ -753,28 +764,45 @@ static void __dma_rx_complete(void *param) | |||
753 | __dma_rx_do_complete(param, false); | 764 | __dma_rx_do_complete(param, false); |
754 | } | 765 | } |
755 | 766 | ||
767 | static void omap_8250_rx_dma_flush(struct uart_8250_port *p) | ||
768 | { | ||
769 | struct omap8250_priv *priv = p->port.private_data; | ||
770 | struct uart_8250_dma *dma = p->dma; | ||
771 | unsigned long flags; | ||
772 | |||
773 | spin_lock_irqsave(&priv->rx_dma_lock, flags); | ||
774 | |||
775 | if (!dma->rx_running) { | ||
776 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); | ||
777 | return; | ||
778 | } | ||
779 | |||
780 | dmaengine_pause(dma->rxchan); | ||
781 | |||
782 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); | ||
783 | |||
784 | __dma_rx_do_complete(p, true); | ||
785 | } | ||
786 | |||
756 | static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | 787 | static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) |
757 | { | 788 | { |
789 | struct omap8250_priv *priv = p->port.private_data; | ||
758 | struct uart_8250_dma *dma = p->dma; | 790 | struct uart_8250_dma *dma = p->dma; |
791 | int err = 0; | ||
759 | struct dma_async_tx_descriptor *desc; | 792 | struct dma_async_tx_descriptor *desc; |
793 | unsigned long flags; | ||
760 | 794 | ||
761 | switch (iir & 0x3f) { | 795 | switch (iir & 0x3f) { |
762 | case UART_IIR_RLSI: | 796 | case UART_IIR_RLSI: |
763 | /* 8250_core handles errors and break interrupts */ | 797 | /* 8250_core handles errors and break interrupts */ |
764 | if (dma->rx_running) { | 798 | omap_8250_rx_dma_flush(p); |
765 | dmaengine_pause(dma->rxchan); | ||
766 | __dma_rx_do_complete(p, true); | ||
767 | } | ||
768 | return -EIO; | 799 | return -EIO; |
769 | case UART_IIR_RX_TIMEOUT: | 800 | case UART_IIR_RX_TIMEOUT: |
770 | /* | 801 | /* |
771 | * If RCVR FIFO trigger level was not reached, complete the | 802 | * If RCVR FIFO trigger level was not reached, complete the |
772 | * transfer and let 8250_core copy the remaining data. | 803 | * transfer and let 8250_core copy the remaining data. |
773 | */ | 804 | */ |
774 | if (dma->rx_running) { | 805 | omap_8250_rx_dma_flush(p); |
775 | dmaengine_pause(dma->rxchan); | ||
776 | __dma_rx_do_complete(p, true); | ||
777 | } | ||
778 | return -ETIMEDOUT; | 806 | return -ETIMEDOUT; |
779 | case UART_IIR_RDI: | 807 | case UART_IIR_RDI: |
780 | /* | 808 | /* |
@@ -786,24 +814,25 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |||
786 | * the DMA won't do anything soon so we have to cancel the DMA | 814 | * the DMA won't do anything soon so we have to cancel the DMA |
787 | * transfer and purge the FIFO manually. | 815 | * transfer and purge the FIFO manually. |
788 | */ | 816 | */ |
789 | if (dma->rx_running) { | 817 | omap_8250_rx_dma_flush(p); |
790 | dmaengine_pause(dma->rxchan); | ||
791 | __dma_rx_do_complete(p, true); | ||
792 | } | ||
793 | return -ETIMEDOUT; | 818 | return -ETIMEDOUT; |
794 | 819 | ||
795 | default: | 820 | default: |
796 | break; | 821 | break; |
797 | } | 822 | } |
798 | 823 | ||
824 | spin_lock_irqsave(&priv->rx_dma_lock, flags); | ||
825 | |||
799 | if (dma->rx_running) | 826 | if (dma->rx_running) |
800 | return 0; | 827 | goto out; |
801 | 828 | ||
802 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, | 829 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, |
803 | dma->rx_size, DMA_DEV_TO_MEM, | 830 | dma->rx_size, DMA_DEV_TO_MEM, |
804 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 831 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
805 | if (!desc) | 832 | if (!desc) { |
806 | return -EBUSY; | 833 | err = -EBUSY; |
834 | goto out; | ||
835 | } | ||
807 | 836 | ||
808 | dma->rx_running = 1; | 837 | dma->rx_running = 1; |
809 | desc->callback = __dma_rx_complete; | 838 | desc->callback = __dma_rx_complete; |
@@ -815,7 +844,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |||
815 | dma->rx_size, DMA_FROM_DEVICE); | 844 | dma->rx_size, DMA_FROM_DEVICE); |
816 | 845 | ||
817 | dma_async_issue_pending(dma->rxchan); | 846 | dma_async_issue_pending(dma->rxchan); |
818 | return 0; | 847 | out: |
848 | spin_unlock_irqrestore(&priv->rx_dma_lock, flags); | ||
849 | return err; | ||
819 | } | 850 | } |
820 | 851 | ||
821 | static int omap_8250_tx_dma(struct uart_8250_port *p); | 852 | static int omap_8250_tx_dma(struct uart_8250_port *p); |
@@ -1129,6 +1160,8 @@ static int omap8250_probe(struct platform_device *pdev) | |||
1129 | priv->latency); | 1160 | priv->latency); |
1130 | INIT_WORK(&priv->qos_work, omap8250_uart_qos_work); | 1161 | INIT_WORK(&priv->qos_work, omap8250_uart_qos_work); |
1131 | 1162 | ||
1163 | spin_lock_init(&priv->rx_dma_lock); | ||
1164 | |||
1132 | device_init_wakeup(&pdev->dev, true); | 1165 | device_init_wakeup(&pdev->dev, true); |
1133 | pm_runtime_use_autosuspend(&pdev->dev); | 1166 | pm_runtime_use_autosuspend(&pdev->dev); |
1134 | pm_runtime_set_autosuspend_delay(&pdev->dev, -1); | 1167 | pm_runtime_set_autosuspend_delay(&pdev->dev, -1); |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 46bcebba54b2..e55f18b93fe7 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1823,6 +1823,9 @@ static int pci_eg20t_init(struct pci_dev *dev) | |||
1823 | #endif | 1823 | #endif |
1824 | } | 1824 | } |
1825 | 1825 | ||
1826 | #define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 | ||
1827 | #define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 | ||
1828 | |||
1826 | static int | 1829 | static int |
1827 | pci_xr17c154_setup(struct serial_private *priv, | 1830 | pci_xr17c154_setup(struct serial_private *priv, |
1828 | const struct pciserial_board *board, | 1831 | const struct pciserial_board *board, |
@@ -1832,6 +1835,15 @@ pci_xr17c154_setup(struct serial_private *priv, | |||
1832 | return pci_default_setup(priv, board, port, idx); | 1835 | return pci_default_setup(priv, board, port, idx); |
1833 | } | 1836 | } |
1834 | 1837 | ||
1838 | static inline int | ||
1839 | xr17v35x_has_slave(struct serial_private *priv) | ||
1840 | { | ||
1841 | const int dev_id = priv->dev->device; | ||
1842 | |||
1843 | return ((dev_id == PCI_DEVICE_ID_EXAR_XR17V4358) || | ||
1844 | (dev_id == PCI_DEVICE_ID_EXAR_XR17V8358)); | ||
1845 | } | ||
1846 | |||
1835 | static int | 1847 | static int |
1836 | pci_xr17v35x_setup(struct serial_private *priv, | 1848 | pci_xr17v35x_setup(struct serial_private *priv, |
1837 | const struct pciserial_board *board, | 1849 | const struct pciserial_board *board, |
@@ -1846,6 +1858,13 @@ pci_xr17v35x_setup(struct serial_private *priv, | |||
1846 | port->port.flags |= UPF_EXAR_EFR; | 1858 | port->port.flags |= UPF_EXAR_EFR; |
1847 | 1859 | ||
1848 | /* | 1860 | /* |
1861 | * Setup the uart clock for the devices on expansion slot to | ||
1862 | * half the clock speed of the main chip (which is 125MHz) | ||
1863 | */ | ||
1864 | if (xr17v35x_has_slave(priv) && idx >= 8) | ||
1865 | port->port.uartclk = (7812500 * 16 / 2); | ||
1866 | |||
1867 | /* | ||
1849 | * Setup Multipurpose Input/Output pins. | 1868 | * Setup Multipurpose Input/Output pins. |
1850 | */ | 1869 | */ |
1851 | if (idx == 0) { | 1870 | if (idx == 0) { |
@@ -1998,8 +2017,6 @@ pci_wch_ch38x_setup(struct serial_private *priv, | |||
1998 | #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 | 2017 | #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 |
1999 | #define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 | 2018 | #define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 |
2000 | 2019 | ||
2001 | #define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 | ||
2002 | |||
2003 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 2020 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
2004 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 2021 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
2005 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 | 2022 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 |
@@ -2524,6 +2541,13 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
2524 | }, | 2541 | }, |
2525 | { | 2542 | { |
2526 | .vendor = PCI_VENDOR_ID_EXAR, | 2543 | .vendor = PCI_VENDOR_ID_EXAR, |
2544 | .device = PCI_DEVICE_ID_EXAR_XR17V4358, | ||
2545 | .subvendor = PCI_ANY_ID, | ||
2546 | .subdevice = PCI_ANY_ID, | ||
2547 | .setup = pci_xr17v35x_setup, | ||
2548 | }, | ||
2549 | { | ||
2550 | .vendor = PCI_VENDOR_ID_EXAR, | ||
2527 | .device = PCI_DEVICE_ID_EXAR_XR17V8358, | 2551 | .device = PCI_DEVICE_ID_EXAR_XR17V8358, |
2528 | .subvendor = PCI_ANY_ID, | 2552 | .subvendor = PCI_ANY_ID, |
2529 | .subdevice = PCI_ANY_ID, | 2553 | .subdevice = PCI_ANY_ID, |
@@ -3008,6 +3032,7 @@ enum pci_board_num_t { | |||
3008 | pbn_exar_XR17V352, | 3032 | pbn_exar_XR17V352, |
3009 | pbn_exar_XR17V354, | 3033 | pbn_exar_XR17V354, |
3010 | pbn_exar_XR17V358, | 3034 | pbn_exar_XR17V358, |
3035 | pbn_exar_XR17V4358, | ||
3011 | pbn_exar_XR17V8358, | 3036 | pbn_exar_XR17V8358, |
3012 | pbn_exar_ibm_saturn, | 3037 | pbn_exar_ibm_saturn, |
3013 | pbn_pasemi_1682M, | 3038 | pbn_pasemi_1682M, |
@@ -3695,6 +3720,14 @@ static struct pciserial_board pci_boards[] = { | |||
3695 | .reg_shift = 0, | 3720 | .reg_shift = 0, |
3696 | .first_offset = 0, | 3721 | .first_offset = 0, |
3697 | }, | 3722 | }, |
3723 | [pbn_exar_XR17V4358] = { | ||
3724 | .flags = FL_BASE0, | ||
3725 | .num_ports = 12, | ||
3726 | .base_baud = 7812500, | ||
3727 | .uart_offset = 0x400, | ||
3728 | .reg_shift = 0, | ||
3729 | .first_offset = 0, | ||
3730 | }, | ||
3698 | [pbn_exar_XR17V8358] = { | 3731 | [pbn_exar_XR17V8358] = { |
3699 | .flags = FL_BASE0, | 3732 | .flags = FL_BASE0, |
3700 | .num_ports = 16, | 3733 | .num_ports = 16, |
@@ -5112,6 +5145,10 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
5112 | PCI_ANY_ID, PCI_ANY_ID, | 5145 | PCI_ANY_ID, PCI_ANY_ID, |
5113 | 0, | 5146 | 0, |
5114 | 0, pbn_exar_XR17V358 }, | 5147 | 0, pbn_exar_XR17V358 }, |
5148 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V4358, | ||
5149 | PCI_ANY_ID, PCI_ANY_ID, | ||
5150 | 0, | ||
5151 | 0, pbn_exar_XR17V4358 }, | ||
5115 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V8358, | 5152 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V8358, |
5116 | PCI_ANY_ID, PCI_ANY_ID, | 5153 | PCI_ANY_ID, PCI_ANY_ID, |
5117 | 0, | 5154 | 0, |
diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c new file mode 100644 index 000000000000..7d79425c2b09 --- /dev/null +++ b/drivers/tty/serial/8250/8250_uniphier.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
21 | #include "8250.h" | ||
22 | |||
23 | /* Most (but not all) of UniPhier UART devices have 64-depth FIFO. */ | ||
24 | #define UNIPHIER_UART_DEFAULT_FIFO_SIZE 64 | ||
25 | |||
26 | #define UNIPHIER_UART_CHAR_FCR 3 /* Character / FIFO Control Register */ | ||
27 | #define UNIPHIER_UART_LCR_MCR 4 /* Line/Modem Control Register */ | ||
28 | #define UNIPHIER_UART_LCR_SHIFT 8 | ||
29 | #define UNIPHIER_UART_DLR 9 /* Divisor Latch Register */ | ||
30 | |||
31 | struct uniphier8250_priv { | ||
32 | int line; | ||
33 | struct clk *clk; | ||
34 | spinlock_t atomic_write_lock; | ||
35 | }; | ||
36 | |||
37 | /* | ||
38 | * The register map is slightly different from that of 8250. | ||
39 | * IO callbacks must be overridden for correct access to FCR, LCR, and MCR. | ||
40 | */ | ||
41 | static unsigned int uniphier_serial_in(struct uart_port *p, int offset) | ||
42 | { | ||
43 | unsigned int valshift = 0; | ||
44 | |||
45 | switch (offset) { | ||
46 | case UART_LCR: | ||
47 | valshift = UNIPHIER_UART_LCR_SHIFT; | ||
48 | /* fall through */ | ||
49 | case UART_MCR: | ||
50 | offset = UNIPHIER_UART_LCR_MCR; | ||
51 | break; | ||
52 | default: | ||
53 | break; | ||
54 | } | ||
55 | |||
56 | offset <<= p->regshift; | ||
57 | |||
58 | /* | ||
59 | * The return value must be masked with 0xff because LCR and MCR reside | ||
60 | * in the same register that must be accessed by 32-bit write/read. | ||
61 | * 8 or 16 bit access to this hardware result in unexpected behavior. | ||
62 | */ | ||
63 | return (readl(p->membase + offset) >> valshift) & 0xff; | ||
64 | } | ||
65 | |||
66 | static void uniphier_serial_out(struct uart_port *p, int offset, int value) | ||
67 | { | ||
68 | unsigned int valshift = 0; | ||
69 | bool normal = false; | ||
70 | |||
71 | switch (offset) { | ||
72 | case UART_FCR: | ||
73 | offset = UNIPHIER_UART_CHAR_FCR; | ||
74 | break; | ||
75 | case UART_LCR: | ||
76 | valshift = UNIPHIER_UART_LCR_SHIFT; | ||
77 | /* Divisor latch access bit does not exist. */ | ||
78 | value &= ~(UART_LCR_DLAB << valshift); | ||
79 | /* fall through */ | ||
80 | case UART_MCR: | ||
81 | offset = UNIPHIER_UART_LCR_MCR; | ||
82 | break; | ||
83 | default: | ||
84 | normal = true; | ||
85 | break; | ||
86 | } | ||
87 | |||
88 | offset <<= p->regshift; | ||
89 | |||
90 | if (normal) { | ||
91 | writel(value, p->membase + offset); | ||
92 | } else { | ||
93 | /* | ||
94 | * Special case: two registers share the same address that | ||
95 | * must be 32-bit accessed. As this is not longer atomic safe, | ||
96 | * take a lock just in case. | ||
97 | */ | ||
98 | struct uniphier8250_priv *priv = p->private_data; | ||
99 | unsigned long flags; | ||
100 | u32 tmp; | ||
101 | |||
102 | spin_lock_irqsave(&priv->atomic_write_lock, flags); | ||
103 | tmp = readl(p->membase + offset); | ||
104 | tmp &= ~(0xff << valshift); | ||
105 | tmp |= value << valshift; | ||
106 | writel(tmp, p->membase + offset); | ||
107 | spin_unlock_irqrestore(&priv->atomic_write_lock, flags); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * This hardware does not have the divisor latch access bit. | ||
113 | * The divisor latch register exists at different address. | ||
114 | * Override dl_read/write callbacks. | ||
115 | */ | ||
116 | static int uniphier_serial_dl_read(struct uart_8250_port *up) | ||
117 | { | ||
118 | return readl(up->port.membase + UNIPHIER_UART_DLR); | ||
119 | } | ||
120 | |||
121 | static void uniphier_serial_dl_write(struct uart_8250_port *up, int value) | ||
122 | { | ||
123 | writel(value, up->port.membase + UNIPHIER_UART_DLR); | ||
124 | } | ||
125 | |||
126 | static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port, | ||
127 | struct uniphier8250_priv *priv) | ||
128 | { | ||
129 | int ret; | ||
130 | u32 prop; | ||
131 | struct device_node *np = dev->of_node; | ||
132 | |||
133 | ret = of_alias_get_id(np, "serial"); | ||
134 | if (ret < 0) { | ||
135 | dev_err(dev, "failed to get alias id\n"); | ||
136 | return ret; | ||
137 | } | ||
138 | port->line = priv->line = ret; | ||
139 | |||
140 | /* Get clk rate through clk driver */ | ||
141 | priv->clk = devm_clk_get(dev, NULL); | ||
142 | if (IS_ERR(priv->clk)) { | ||
143 | dev_err(dev, "failed to get clock\n"); | ||
144 | return PTR_ERR(priv->clk); | ||
145 | } | ||
146 | |||
147 | ret = clk_prepare_enable(priv->clk); | ||
148 | if (ret < 0) | ||
149 | return ret; | ||
150 | |||
151 | port->uartclk = clk_get_rate(priv->clk); | ||
152 | |||
153 | /* Check for fifo size */ | ||
154 | if (of_property_read_u32(np, "fifo-size", &prop) == 0) | ||
155 | port->fifosize = prop; | ||
156 | else | ||
157 | port->fifosize = UNIPHIER_UART_DEFAULT_FIFO_SIZE; | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int uniphier_uart_probe(struct platform_device *pdev) | ||
163 | { | ||
164 | struct device *dev = &pdev->dev; | ||
165 | struct uart_8250_port up; | ||
166 | struct uniphier8250_priv *priv; | ||
167 | struct resource *regs; | ||
168 | void __iomem *membase; | ||
169 | int irq; | ||
170 | int ret; | ||
171 | |||
172 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
173 | if (!regs) { | ||
174 | dev_err(dev, "failed to get memory resource"); | ||
175 | return -EINVAL; | ||
176 | } | ||
177 | |||
178 | membase = devm_ioremap(dev, regs->start, resource_size(regs)); | ||
179 | if (!membase) | ||
180 | return -ENOMEM; | ||
181 | |||
182 | irq = platform_get_irq(pdev, 0); | ||
183 | if (irq < 0) { | ||
184 | dev_err(dev, "failed to get IRQ number"); | ||
185 | return irq; | ||
186 | } | ||
187 | |||
188 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
189 | if (!priv) | ||
190 | return -ENOMEM; | ||
191 | |||
192 | memset(&up, 0, sizeof(up)); | ||
193 | |||
194 | ret = uniphier_of_serial_setup(dev, &up.port, priv); | ||
195 | if (ret < 0) | ||
196 | return ret; | ||
197 | |||
198 | spin_lock_init(&priv->atomic_write_lock); | ||
199 | |||
200 | up.port.dev = dev; | ||
201 | up.port.private_data = priv; | ||
202 | up.port.mapbase = regs->start; | ||
203 | up.port.mapsize = resource_size(regs); | ||
204 | up.port.membase = membase; | ||
205 | up.port.irq = irq; | ||
206 | |||
207 | up.port.type = PORT_16550A; | ||
208 | up.port.iotype = UPIO_MEM32; | ||
209 | up.port.regshift = 2; | ||
210 | up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE; | ||
211 | up.capabilities = UART_CAP_FIFO; | ||
212 | |||
213 | up.port.serial_in = uniphier_serial_in; | ||
214 | up.port.serial_out = uniphier_serial_out; | ||
215 | up.dl_read = uniphier_serial_dl_read; | ||
216 | up.dl_write = uniphier_serial_dl_write; | ||
217 | |||
218 | ret = serial8250_register_8250_port(&up); | ||
219 | if (ret < 0) { | ||
220 | dev_err(dev, "failed to register 8250 port\n"); | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | platform_set_drvdata(pdev, priv); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int uniphier_uart_remove(struct platform_device *pdev) | ||
230 | { | ||
231 | struct uniphier8250_priv *priv = platform_get_drvdata(pdev); | ||
232 | |||
233 | serial8250_unregister_port(priv->line); | ||
234 | clk_disable_unprepare(priv->clk); | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static const struct of_device_id uniphier_uart_match[] = { | ||
240 | { .compatible = "socionext,uniphier-uart" }, | ||
241 | { /* sentinel */ } | ||
242 | }; | ||
243 | MODULE_DEVICE_TABLE(of, uniphier_uart_match); | ||
244 | |||
245 | static struct platform_driver uniphier_uart_platform_driver = { | ||
246 | .probe = uniphier_uart_probe, | ||
247 | .remove = uniphier_uart_remove, | ||
248 | .driver = { | ||
249 | .name = "uniphier-uart", | ||
250 | .of_match_table = uniphier_uart_match, | ||
251 | }, | ||
252 | }; | ||
253 | module_platform_driver(uniphier_uart_platform_driver); | ||
254 | |||
255 | MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); | ||
256 | MODULE_DESCRIPTION("UniPhier UART driver"); | ||
257 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c35070356528..a74a8e4717d4 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -336,9 +336,24 @@ config SERIAL_8250_FINTEK | |||
336 | LPC to 4 UART. This device has some RS485 functionality not available | 336 | LPC to 4 UART. This device has some RS485 functionality not available |
337 | through the PNP driver. If unsure, say N. | 337 | through the PNP driver. If unsure, say N. |
338 | 338 | ||
339 | config SERIAL_8250_LPC18XX | ||
340 | bool "NXP LPC18xx/43xx serial port support" | ||
341 | depends on SERIAL_8250 && OF && (ARCH_LPC18XX || COMPILE_TEST) | ||
342 | default ARCH_LPC18XX | ||
343 | help | ||
344 | If you have a LPC18xx/43xx based board and want to use the | ||
345 | serial port, say Y to this option. If unsure, say Y. | ||
346 | |||
339 | config SERIAL_8250_MT6577 | 347 | config SERIAL_8250_MT6577 |
340 | bool "Mediatek serial port support" | 348 | bool "Mediatek serial port support" |
341 | depends on SERIAL_8250 && ARCH_MEDIATEK | 349 | depends on SERIAL_8250 && ARCH_MEDIATEK |
342 | help | 350 | help |
343 | If you have a Mediatek based board and want to use the | 351 | If you have a Mediatek based board and want to use the |
344 | serial port, say Y to this option. If unsure, say N. | 352 | serial port, say Y to this option. If unsure, say N. |
353 | |||
354 | config SERIAL_8250_UNIPHIER | ||
355 | tristate "Support for UniPhier on-chip UART" | ||
356 | depends on SERIAL_8250 && ARCH_UNIPHIER | ||
357 | help | ||
358 | If you have a UniPhier based board and want to use the on-chip | ||
359 | serial ports, say Y to this option. If unsure, say N. | ||
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 31e7cdc6865c..6fa22ffad63d 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile | |||
@@ -22,4 +22,6 @@ obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o | |||
22 | obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o | 22 | obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o |
23 | obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o | 23 | obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o |
24 | obj-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o | 24 | obj-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o |
25 | obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o | ||
25 | obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o | 26 | obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o |
27 | obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o | ||
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index dea1eff6a92c..76e65b714471 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -241,7 +241,6 @@ config SERIAL_SAMSUNG | |||
241 | tristate "Samsung SoC serial support" | 241 | tristate "Samsung SoC serial support" |
242 | depends on PLAT_SAMSUNG || ARCH_EXYNOS | 242 | depends on PLAT_SAMSUNG || ARCH_EXYNOS |
243 | select SERIAL_CORE | 243 | select SERIAL_CORE |
244 | select SERIAL_EARLYCON | ||
245 | help | 244 | help |
246 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, | 245 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, |
247 | providing /dev/ttySAC0, 1 and 2 (note, some machines may not | 246 | providing /dev/ttySAC0, 1 and 2 (note, some machines may not |
@@ -277,6 +276,7 @@ config SERIAL_SAMSUNG_CONSOLE | |||
277 | bool "Support for console on Samsung SoC serial port" | 276 | bool "Support for console on Samsung SoC serial port" |
278 | depends on SERIAL_SAMSUNG=y | 277 | depends on SERIAL_SAMSUNG=y |
279 | select SERIAL_CORE_CONSOLE | 278 | select SERIAL_CORE_CONSOLE |
279 | select SERIAL_EARLYCON | ||
280 | help | 280 | help |
281 | Allow selection of the S3C24XX on-board serial ports for use as | 281 | Allow selection of the S3C24XX on-board serial ports for use as |
282 | an virtual console. | 282 | an virtual console. |
@@ -1179,15 +1179,42 @@ config SERIAL_SCCNXP_CONSOLE | |||
1179 | help | 1179 | help |
1180 | Support for console on SCCNXP serial ports. | 1180 | Support for console on SCCNXP serial ports. |
1181 | 1181 | ||
1182 | config SERIAL_SC16IS7XX_CORE | ||
1183 | tristate | ||
1184 | |||
1182 | config SERIAL_SC16IS7XX | 1185 | config SERIAL_SC16IS7XX |
1183 | tristate "SC16IS7xx serial support" | 1186 | tristate "SC16IS7xx serial support" |
1184 | depends on I2C | 1187 | select SERIAL_CORE |
1185 | select SERIAL_CORE | 1188 | depends on I2C || SPI_MASTER |
1186 | select REGMAP_I2C if I2C | 1189 | help |
1187 | help | 1190 | This selects support for SC16IS7xx serial ports. |
1188 | This selects support for SC16IS7xx serial ports. | 1191 | Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752, |
1189 | Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752, | 1192 | SC16IS760 and SC16IS762. Select supported buses using options below. |
1190 | SC16IS760 and SC16IS762. | 1193 | |
1194 | config SERIAL_SC16IS7XX_I2C | ||
1195 | bool "SC16IS7xx for I2C interface" | ||
1196 | depends on SERIAL_SC16IS7XX | ||
1197 | depends on I2C | ||
1198 | select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX | ||
1199 | select REGMAP_I2C if I2C | ||
1200 | default y | ||
1201 | help | ||
1202 | Enable SC16IS7xx driver on I2C bus, | ||
1203 | If required say y, and say n to i2c if not required, | ||
1204 | Enabled by default to support oldconfig. | ||
1205 | You must select at least one bus for the driver to be built. | ||
1206 | |||
1207 | config SERIAL_SC16IS7XX_SPI | ||
1208 | bool "SC16IS7xx for spi interface" | ||
1209 | depends on SERIAL_SC16IS7XX | ||
1210 | depends on SPI_MASTER | ||
1211 | select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX | ||
1212 | select REGMAP_SPI if SPI_MASTER | ||
1213 | help | ||
1214 | Enable SC16IS7xx driver on SPI bus, | ||
1215 | If required say y, and say n to spi if not required, | ||
1216 | This is additional support to exsisting driver. | ||
1217 | You must select at least one bus for the driver to be built. | ||
1191 | 1218 | ||
1192 | config SERIAL_BFIN_SPORT | 1219 | config SERIAL_BFIN_SPORT |
1193 | tristate "Blackfin SPORT emulate UART" | 1220 | tristate "Blackfin SPORT emulate UART" |
@@ -1349,7 +1376,7 @@ config SERIAL_ALTERA_UART_CONSOLE | |||
1349 | 1376 | ||
1350 | config SERIAL_IFX6X60 | 1377 | config SERIAL_IFX6X60 |
1351 | tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)" | 1378 | tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)" |
1352 | depends on GPIOLIB && SPI | 1379 | depends on GPIOLIB && SPI && HAS_DMA |
1353 | help | 1380 | help |
1354 | Support for the IFX6x60 modem devices on Intel MID platforms. | 1381 | Support for the IFX6x60 modem devices on Intel MID platforms. |
1355 | 1382 | ||
@@ -1378,14 +1405,6 @@ config SERIAL_PCH_UART_CONSOLE | |||
1378 | (the system console is the device which receives all kernel messages and | 1405 | (the system console is the device which receives all kernel messages and |
1379 | warnings and which allows logins in single user mode). | 1406 | warnings and which allows logins in single user mode). |
1380 | 1407 | ||
1381 | config SERIAL_MSM_SMD | ||
1382 | bool "Enable tty device interface for some SMD ports" | ||
1383 | default n | ||
1384 | depends on MSM_SMD | ||
1385 | help | ||
1386 | Enables userspace clients to read and write to some streaming SMD | ||
1387 | ports via tty device interface for MSM chipset. | ||
1388 | |||
1389 | config SERIAL_MXS_AUART | 1408 | config SERIAL_MXS_AUART |
1390 | depends on ARCH_MXS | 1409 | depends on ARCH_MXS |
1391 | tristate "MXS AUART support" | 1410 | tristate "MXS AUART support" |
@@ -1589,6 +1608,23 @@ config SERIAL_SPRD_CONSOLE | |||
1589 | with "earlycon" on the kernel command line. The console is | 1608 | with "earlycon" on the kernel command line. The console is |
1590 | enabled when early_param is processed. | 1609 | enabled when early_param is processed. |
1591 | 1610 | ||
1611 | config SERIAL_STM32 | ||
1612 | tristate "STMicroelectronics STM32 serial port support" | ||
1613 | select SERIAL_CORE | ||
1614 | depends on ARM || COMPILE_TEST | ||
1615 | help | ||
1616 | This driver is for the on-chip Serial Controller on | ||
1617 | STMicroelectronics STM32 MCUs. | ||
1618 | USART supports Rx & Tx functionality. | ||
1619 | It support all industry standard baud rates. | ||
1620 | |||
1621 | If unsure, say N. | ||
1622 | |||
1623 | config SERIAL_STM32_CONSOLE | ||
1624 | bool "Support for console on STM32" | ||
1625 | depends on SERIAL_STM32=y | ||
1626 | select SERIAL_CORE_CONSOLE | ||
1627 | |||
1592 | endmenu | 1628 | endmenu |
1593 | 1629 | ||
1594 | config SERIAL_MCTRL_GPIO | 1630 | config SERIAL_MCTRL_GPIO |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index c3ac3d930b33..5ab41119b3dc 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -53,7 +53,7 @@ obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o | |||
53 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o | 53 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o |
54 | obj-$(CONFIG_SERIAL_ETRAXFS) += etraxfs-uart.o | 54 | obj-$(CONFIG_SERIAL_ETRAXFS) += etraxfs-uart.o |
55 | obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o | 55 | obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o |
56 | obj-$(CONFIG_SERIAL_SC16IS7XX) += sc16is7xx.o | 56 | obj-$(CONFIG_SERIAL_SC16IS7XX_CORE) += sc16is7xx.o |
57 | obj-$(CONFIG_SERIAL_JSM) += jsm/ | 57 | obj-$(CONFIG_SERIAL_JSM) += jsm/ |
58 | obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o | 58 | obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o |
59 | obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o | 59 | obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o |
@@ -79,7 +79,6 @@ obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o | |||
79 | obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o | 79 | obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o |
80 | obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o | 80 | obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o |
81 | obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o | 81 | obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o |
82 | obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o | ||
83 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o | 82 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o |
84 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | 83 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o |
85 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | 84 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o |
@@ -93,6 +92,7 @@ obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o | |||
93 | obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o | 92 | obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o |
94 | obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o | 93 | obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o |
95 | obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o | 94 | obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o |
95 | obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o | ||
96 | 96 | ||
97 | # GPIOLIB helpers for modem control lines | 97 | # GPIOLIB helpers for modem control lines |
98 | 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/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 0fefdd8931a2..32df2a0cb060 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c | |||
@@ -387,7 +387,7 @@ console_initcall(altera_jtaguart_console_init); | |||
387 | 387 | ||
388 | #define ALTERA_JTAGUART_CONSOLE NULL | 388 | #define ALTERA_JTAGUART_CONSOLE NULL |
389 | 389 | ||
390 | #endif /* CONFIG_ALTERA_JTAGUART_CONSOLE */ | 390 | #endif /* CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE */ |
391 | 391 | ||
392 | static struct uart_driver altera_jtaguart_driver = { | 392 | static struct uart_driver altera_jtaguart_driver = { |
393 | .owner = THIS_MODULE, | 393 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index b2859fe07e14..fd87a6f574e3 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -493,7 +493,7 @@ console_initcall(altera_uart_console_init); | |||
493 | 493 | ||
494 | #define ALTERA_UART_CONSOLE NULL | 494 | #define ALTERA_UART_CONSOLE NULL |
495 | 495 | ||
496 | #endif /* CONFIG_ALTERA_UART_CONSOLE */ | 496 | #endif /* CONFIG_SERIAL_ALTERA_UART_CONSOLE */ |
497 | 497 | ||
498 | /* | 498 | /* |
499 | * Define the altera_uart UART driver structure. | 499 | * Define the altera_uart UART driver structure. |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 763eb20fe321..50cf5b10ceed 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -58,7 +58,7 @@ | |||
58 | #include <linux/pinctrl/consumer.h> | 58 | #include <linux/pinctrl/consumer.h> |
59 | #include <linux/sizes.h> | 59 | #include <linux/sizes.h> |
60 | #include <linux/io.h> | 60 | #include <linux/io.h> |
61 | #include <linux/workqueue.h> | 61 | #include <linux/acpi.h> |
62 | 62 | ||
63 | #define UART_NR 14 | 63 | #define UART_NR 14 |
64 | 64 | ||
@@ -79,6 +79,8 @@ struct vendor_data { | |||
79 | bool oversampling; | 79 | bool oversampling; |
80 | bool dma_threshold; | 80 | bool dma_threshold; |
81 | bool cts_event_workaround; | 81 | bool cts_event_workaround; |
82 | bool always_enabled; | ||
83 | bool fixed_options; | ||
82 | 84 | ||
83 | unsigned int (*get_fifosize)(struct amba_device *dev); | 85 | unsigned int (*get_fifosize)(struct amba_device *dev); |
84 | }; | 86 | }; |
@@ -95,9 +97,19 @@ static struct vendor_data vendor_arm = { | |||
95 | .oversampling = false, | 97 | .oversampling = false, |
96 | .dma_threshold = false, | 98 | .dma_threshold = false, |
97 | .cts_event_workaround = false, | 99 | .cts_event_workaround = false, |
100 | .always_enabled = false, | ||
101 | .fixed_options = false, | ||
98 | .get_fifosize = get_fifosize_arm, | 102 | .get_fifosize = get_fifosize_arm, |
99 | }; | 103 | }; |
100 | 104 | ||
105 | static struct vendor_data vendor_sbsa = { | ||
106 | .oversampling = false, | ||
107 | .dma_threshold = false, | ||
108 | .cts_event_workaround = false, | ||
109 | .always_enabled = true, | ||
110 | .fixed_options = true, | ||
111 | }; | ||
112 | |||
101 | static unsigned int get_fifosize_st(struct amba_device *dev) | 113 | static unsigned int get_fifosize_st(struct amba_device *dev) |
102 | { | 114 | { |
103 | return 64; | 115 | return 64; |
@@ -110,6 +122,8 @@ static struct vendor_data vendor_st = { | |||
110 | .oversampling = true, | 122 | .oversampling = true, |
111 | .dma_threshold = true, | 123 | .dma_threshold = true, |
112 | .cts_event_workaround = true, | 124 | .cts_event_workaround = true, |
125 | .always_enabled = false, | ||
126 | .fixed_options = false, | ||
113 | .get_fifosize = get_fifosize_st, | 127 | .get_fifosize = get_fifosize_st, |
114 | }; | 128 | }; |
115 | 129 | ||
@@ -157,9 +171,8 @@ struct uart_amba_port { | |||
157 | unsigned int lcrh_tx; /* vendor-specific */ | 171 | unsigned int lcrh_tx; /* vendor-specific */ |
158 | unsigned int lcrh_rx; /* vendor-specific */ | 172 | unsigned int lcrh_rx; /* vendor-specific */ |
159 | unsigned int old_cr; /* state during shutdown */ | 173 | unsigned int old_cr; /* state during shutdown */ |
160 | struct delayed_work tx_softirq_work; | ||
161 | bool autorts; | 174 | bool autorts; |
162 | unsigned int tx_irq_seen; /* 0=none, 1=1, 2=2 or more */ | 175 | unsigned int fixed_baud; /* vendor-set fixed baud rate */ |
163 | char type[12]; | 176 | char type[12]; |
164 | #ifdef CONFIG_DMA_ENGINE | 177 | #ifdef CONFIG_DMA_ENGINE |
165 | /* DMA stuff */ | 178 | /* DMA stuff */ |
@@ -1172,15 +1185,14 @@ static void pl011_stop_tx(struct uart_port *port) | |||
1172 | pl011_dma_tx_stop(uap); | 1185 | pl011_dma_tx_stop(uap); |
1173 | } | 1186 | } |
1174 | 1187 | ||
1175 | static bool pl011_tx_chars(struct uart_amba_port *uap); | 1188 | static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); |
1176 | 1189 | ||
1177 | /* Start TX with programmed I/O only (no DMA) */ | 1190 | /* Start TX with programmed I/O only (no DMA) */ |
1178 | static void pl011_start_tx_pio(struct uart_amba_port *uap) | 1191 | static void pl011_start_tx_pio(struct uart_amba_port *uap) |
1179 | { | 1192 | { |
1180 | uap->im |= UART011_TXIM; | 1193 | uap->im |= UART011_TXIM; |
1181 | writew(uap->im, uap->port.membase + UART011_IMSC); | 1194 | writew(uap->im, uap->port.membase + UART011_IMSC); |
1182 | if (!uap->tx_irq_seen) | 1195 | pl011_tx_chars(uap, false); |
1183 | pl011_tx_chars(uap); | ||
1184 | } | 1196 | } |
1185 | 1197 | ||
1186 | static void pl011_start_tx(struct uart_port *port) | 1198 | static void pl011_start_tx(struct uart_port *port) |
@@ -1247,15 +1259,11 @@ __acquires(&uap->port.lock) | |||
1247 | spin_lock(&uap->port.lock); | 1259 | spin_lock(&uap->port.lock); |
1248 | } | 1260 | } |
1249 | 1261 | ||
1250 | /* | 1262 | static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, |
1251 | * Transmit a character | 1263 | bool from_irq) |
1252 | * | ||
1253 | * Returns true if the character was successfully queued to the FIFO. | ||
1254 | * Returns false otherwise. | ||
1255 | */ | ||
1256 | static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) | ||
1257 | { | 1264 | { |
1258 | if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) | 1265 | if (unlikely(!from_irq) && |
1266 | readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) | ||
1259 | return false; /* unable to transmit character */ | 1267 | return false; /* unable to transmit character */ |
1260 | 1268 | ||
1261 | writew(c, uap->port.membase + UART01x_DR); | 1269 | writew(c, uap->port.membase + UART01x_DR); |
@@ -1264,70 +1272,41 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) | |||
1264 | return true; | 1272 | return true; |
1265 | } | 1273 | } |
1266 | 1274 | ||
1267 | static bool pl011_tx_chars(struct uart_amba_port *uap) | 1275 | static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) |
1268 | { | 1276 | { |
1269 | struct circ_buf *xmit = &uap->port.state->xmit; | 1277 | struct circ_buf *xmit = &uap->port.state->xmit; |
1270 | int count; | 1278 | int count = uap->fifosize >> 1; |
1271 | |||
1272 | if (unlikely(uap->tx_irq_seen < 2)) | ||
1273 | /* | ||
1274 | * Initial FIFO fill level unknown: we must check TXFF | ||
1275 | * after each write, so just try to fill up the FIFO. | ||
1276 | */ | ||
1277 | count = uap->fifosize; | ||
1278 | else /* tx_irq_seen >= 2 */ | ||
1279 | /* | ||
1280 | * FIFO initially at least half-empty, so we can simply | ||
1281 | * write half the FIFO without polling TXFF. | ||
1282 | |||
1283 | * Note: the *first* TX IRQ can still race with | ||
1284 | * pl011_start_tx_pio(), which can result in the FIFO | ||
1285 | * being fuller than expected in that case. | ||
1286 | */ | ||
1287 | count = uap->fifosize >> 1; | ||
1288 | |||
1289 | /* | ||
1290 | * If the FIFO is full we're guaranteed a TX IRQ at some later point, | ||
1291 | * and can't transmit immediately in any case: | ||
1292 | */ | ||
1293 | if (unlikely(uap->tx_irq_seen < 2 && | ||
1294 | readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)) | ||
1295 | return false; | ||
1296 | 1279 | ||
1297 | if (uap->port.x_char) { | 1280 | if (uap->port.x_char) { |
1298 | if (!pl011_tx_char(uap, uap->port.x_char)) | 1281 | if (!pl011_tx_char(uap, uap->port.x_char, from_irq)) |
1299 | goto done; | 1282 | return; |
1300 | uap->port.x_char = 0; | 1283 | uap->port.x_char = 0; |
1301 | --count; | 1284 | --count; |
1302 | } | 1285 | } |
1303 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { | 1286 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { |
1304 | pl011_stop_tx(&uap->port); | 1287 | pl011_stop_tx(&uap->port); |
1305 | goto done; | 1288 | return; |
1306 | } | 1289 | } |
1307 | 1290 | ||
1308 | /* If we are using DMA mode, try to send some characters. */ | 1291 | /* If we are using DMA mode, try to send some characters. */ |
1309 | if (pl011_dma_tx_irq(uap)) | 1292 | if (pl011_dma_tx_irq(uap)) |
1310 | goto done; | 1293 | return; |
1311 | 1294 | ||
1312 | while (count-- > 0 && pl011_tx_char(uap, xmit->buf[xmit->tail])) { | 1295 | do { |
1313 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 1296 | if (likely(from_irq) && count-- == 0) |
1314 | if (uart_circ_empty(xmit)) | ||
1315 | break; | 1297 | break; |
1316 | } | 1298 | |
1299 | if (!pl011_tx_char(uap, xmit->buf[xmit->tail], from_irq)) | ||
1300 | break; | ||
1301 | |||
1302 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
1303 | } while (!uart_circ_empty(xmit)); | ||
1317 | 1304 | ||
1318 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 1305 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
1319 | uart_write_wakeup(&uap->port); | 1306 | uart_write_wakeup(&uap->port); |
1320 | 1307 | ||
1321 | if (uart_circ_empty(xmit)) { | 1308 | if (uart_circ_empty(xmit)) |
1322 | pl011_stop_tx(&uap->port); | 1309 | pl011_stop_tx(&uap->port); |
1323 | goto done; | ||
1324 | } | ||
1325 | |||
1326 | if (unlikely(!uap->tx_irq_seen)) | ||
1327 | schedule_delayed_work(&uap->tx_softirq_work, uap->port.timeout); | ||
1328 | |||
1329 | done: | ||
1330 | return false; | ||
1331 | } | 1310 | } |
1332 | 1311 | ||
1333 | static void pl011_modem_status(struct uart_amba_port *uap) | 1312 | static void pl011_modem_status(struct uart_amba_port *uap) |
@@ -1354,26 +1333,23 @@ static void pl011_modem_status(struct uart_amba_port *uap) | |||
1354 | wake_up_interruptible(&uap->port.state->port.delta_msr_wait); | 1333 | wake_up_interruptible(&uap->port.state->port.delta_msr_wait); |
1355 | } | 1334 | } |
1356 | 1335 | ||
1357 | static void pl011_tx_softirq(struct work_struct *work) | 1336 | static void check_apply_cts_event_workaround(struct uart_amba_port *uap) |
1358 | { | 1337 | { |
1359 | struct delayed_work *dwork = to_delayed_work(work); | 1338 | unsigned int dummy_read; |
1360 | struct uart_amba_port *uap = | ||
1361 | container_of(dwork, struct uart_amba_port, tx_softirq_work); | ||
1362 | |||
1363 | spin_lock(&uap->port.lock); | ||
1364 | while (pl011_tx_chars(uap)) ; | ||
1365 | spin_unlock(&uap->port.lock); | ||
1366 | } | ||
1367 | 1339 | ||
1368 | static void pl011_tx_irq_seen(struct uart_amba_port *uap) | 1340 | if (!uap->vendor->cts_event_workaround) |
1369 | { | ||
1370 | if (likely(uap->tx_irq_seen > 1)) | ||
1371 | return; | 1341 | return; |
1372 | 1342 | ||
1373 | uap->tx_irq_seen++; | 1343 | /* workaround to make sure that all bits are unlocked.. */ |
1374 | if (uap->tx_irq_seen < 2) | 1344 | writew(0x00, uap->port.membase + UART011_ICR); |
1375 | /* first TX IRQ */ | 1345 | |
1376 | cancel_delayed_work(&uap->tx_softirq_work); | 1346 | /* |
1347 | * WA: introduce 26ns(1 uart clk) delay before W1C; | ||
1348 | * single apb access will incur 2 pclk(133.12Mhz) delay, | ||
1349 | * so add 2 dummy reads | ||
1350 | */ | ||
1351 | dummy_read = readw(uap->port.membase + UART011_ICR); | ||
1352 | dummy_read = readw(uap->port.membase + UART011_ICR); | ||
1377 | } | 1353 | } |
1378 | 1354 | ||
1379 | static irqreturn_t pl011_int(int irq, void *dev_id) | 1355 | static irqreturn_t pl011_int(int irq, void *dev_id) |
@@ -1381,25 +1357,15 @@ static irqreturn_t pl011_int(int irq, void *dev_id) | |||
1381 | struct uart_amba_port *uap = dev_id; | 1357 | struct uart_amba_port *uap = dev_id; |
1382 | unsigned long flags; | 1358 | unsigned long flags; |
1383 | unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; | 1359 | unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; |
1360 | u16 imsc; | ||
1384 | int handled = 0; | 1361 | int handled = 0; |
1385 | unsigned int dummy_read; | ||
1386 | 1362 | ||
1387 | spin_lock_irqsave(&uap->port.lock, flags); | 1363 | spin_lock_irqsave(&uap->port.lock, flags); |
1388 | status = readw(uap->port.membase + UART011_MIS); | 1364 | imsc = readw(uap->port.membase + UART011_IMSC); |
1365 | status = readw(uap->port.membase + UART011_RIS) & imsc; | ||
1389 | if (status) { | 1366 | if (status) { |
1390 | do { | 1367 | do { |
1391 | if (uap->vendor->cts_event_workaround) { | 1368 | check_apply_cts_event_workaround(uap); |
1392 | /* workaround to make sure that all bits are unlocked.. */ | ||
1393 | writew(0x00, uap->port.membase + UART011_ICR); | ||
1394 | |||
1395 | /* | ||
1396 | * WA: introduce 26ns(1 uart clk) delay before W1C; | ||
1397 | * single apb access will incur 2 pclk(133.12Mhz) delay, | ||
1398 | * so add 2 dummy reads | ||
1399 | */ | ||
1400 | dummy_read = readw(uap->port.membase + UART011_ICR); | ||
1401 | dummy_read = readw(uap->port.membase + UART011_ICR); | ||
1402 | } | ||
1403 | 1369 | ||
1404 | writew(status & ~(UART011_TXIS|UART011_RTIS| | 1370 | writew(status & ~(UART011_TXIS|UART011_RTIS| |
1405 | UART011_RXIS), | 1371 | UART011_RXIS), |
@@ -1414,15 +1380,13 @@ static irqreturn_t pl011_int(int irq, void *dev_id) | |||
1414 | if (status & (UART011_DSRMIS|UART011_DCDMIS| | 1380 | if (status & (UART011_DSRMIS|UART011_DCDMIS| |
1415 | UART011_CTSMIS|UART011_RIMIS)) | 1381 | UART011_CTSMIS|UART011_RIMIS)) |
1416 | pl011_modem_status(uap); | 1382 | pl011_modem_status(uap); |
1417 | if (status & UART011_TXIS) { | 1383 | if (status & UART011_TXIS) |
1418 | pl011_tx_irq_seen(uap); | 1384 | pl011_tx_chars(uap, true); |
1419 | pl011_tx_chars(uap); | ||
1420 | } | ||
1421 | 1385 | ||
1422 | if (pass_counter-- == 0) | 1386 | if (pass_counter-- == 0) |
1423 | break; | 1387 | break; |
1424 | 1388 | ||
1425 | status = readw(uap->port.membase + UART011_MIS); | 1389 | status = readw(uap->port.membase + UART011_RIS) & imsc; |
1426 | } while (status != 0); | 1390 | } while (status != 0); |
1427 | handled = 1; | 1391 | handled = 1; |
1428 | } | 1392 | } |
@@ -1617,6 +1581,32 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) | |||
1617 | } | 1581 | } |
1618 | } | 1582 | } |
1619 | 1583 | ||
1584 | static int pl011_allocate_irq(struct uart_amba_port *uap) | ||
1585 | { | ||
1586 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
1587 | |||
1588 | return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); | ||
1589 | } | ||
1590 | |||
1591 | /* | ||
1592 | * Enable interrupts, only timeouts when using DMA | ||
1593 | * if initial RX DMA job failed, start in interrupt mode | ||
1594 | * as well. | ||
1595 | */ | ||
1596 | static void pl011_enable_interrupts(struct uart_amba_port *uap) | ||
1597 | { | ||
1598 | spin_lock_irq(&uap->port.lock); | ||
1599 | |||
1600 | /* Clear out any spuriously appearing RX interrupts */ | ||
1601 | writew(UART011_RTIS | UART011_RXIS, | ||
1602 | uap->port.membase + UART011_ICR); | ||
1603 | uap->im = UART011_RTIM; | ||
1604 | if (!pl011_dma_rx_running(uap)) | ||
1605 | uap->im |= UART011_RXIM; | ||
1606 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
1607 | spin_unlock_irq(&uap->port.lock); | ||
1608 | } | ||
1609 | |||
1620 | static int pl011_startup(struct uart_port *port) | 1610 | static int pl011_startup(struct uart_port *port) |
1621 | { | 1611 | { |
1622 | struct uart_amba_port *uap = | 1612 | struct uart_amba_port *uap = |
@@ -1628,20 +1618,12 @@ static int pl011_startup(struct uart_port *port) | |||
1628 | if (retval) | 1618 | if (retval) |
1629 | goto clk_dis; | 1619 | goto clk_dis; |
1630 | 1620 | ||
1631 | writew(uap->im, uap->port.membase + UART011_IMSC); | 1621 | retval = pl011_allocate_irq(uap); |
1632 | |||
1633 | /* | ||
1634 | * Allocate the IRQ | ||
1635 | */ | ||
1636 | retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); | ||
1637 | if (retval) | 1622 | if (retval) |
1638 | goto clk_dis; | 1623 | goto clk_dis; |
1639 | 1624 | ||
1640 | writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); | 1625 | writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); |
1641 | 1626 | ||
1642 | /* Assume that TX IRQ doesn't work until we see one: */ | ||
1643 | uap->tx_irq_seen = 0; | ||
1644 | |||
1645 | spin_lock_irq(&uap->port.lock); | 1627 | spin_lock_irq(&uap->port.lock); |
1646 | 1628 | ||
1647 | /* restore RTS and DTR */ | 1629 | /* restore RTS and DTR */ |
@@ -1659,20 +1641,7 @@ static int pl011_startup(struct uart_port *port) | |||
1659 | /* Startup DMA */ | 1641 | /* Startup DMA */ |
1660 | pl011_dma_startup(uap); | 1642 | pl011_dma_startup(uap); |
1661 | 1643 | ||
1662 | /* | 1644 | pl011_enable_interrupts(uap); |
1663 | * Finally, enable interrupts, only timeouts when using DMA | ||
1664 | * if initial RX DMA job failed, start in interrupt mode | ||
1665 | * as well. | ||
1666 | */ | ||
1667 | spin_lock_irq(&uap->port.lock); | ||
1668 | /* Clear out any spuriously appearing RX interrupts */ | ||
1669 | writew(UART011_RTIS | UART011_RXIS, | ||
1670 | uap->port.membase + UART011_ICR); | ||
1671 | uap->im = UART011_RTIM; | ||
1672 | if (!pl011_dma_rx_running(uap)) | ||
1673 | uap->im |= UART011_RXIM; | ||
1674 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
1675 | spin_unlock_irq(&uap->port.lock); | ||
1676 | 1645 | ||
1677 | return 0; | 1646 | return 0; |
1678 | 1647 | ||
@@ -1681,6 +1650,28 @@ static int pl011_startup(struct uart_port *port) | |||
1681 | return retval; | 1650 | return retval; |
1682 | } | 1651 | } |
1683 | 1652 | ||
1653 | static int sbsa_uart_startup(struct uart_port *port) | ||
1654 | { | ||
1655 | struct uart_amba_port *uap = | ||
1656 | container_of(port, struct uart_amba_port, port); | ||
1657 | int retval; | ||
1658 | |||
1659 | retval = pl011_hwinit(port); | ||
1660 | if (retval) | ||
1661 | return retval; | ||
1662 | |||
1663 | retval = pl011_allocate_irq(uap); | ||
1664 | if (retval) | ||
1665 | return retval; | ||
1666 | |||
1667 | /* The SBSA UART does not support any modem status lines. */ | ||
1668 | uap->old_status = 0; | ||
1669 | |||
1670 | pl011_enable_interrupts(uap); | ||
1671 | |||
1672 | return 0; | ||
1673 | } | ||
1674 | |||
1684 | static void pl011_shutdown_channel(struct uart_amba_port *uap, | 1675 | static void pl011_shutdown_channel(struct uart_amba_port *uap, |
1685 | unsigned int lcrh) | 1676 | unsigned int lcrh) |
1686 | { | 1677 | { |
@@ -1691,36 +1682,15 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap, | |||
1691 | writew(val, uap->port.membase + lcrh); | 1682 | writew(val, uap->port.membase + lcrh); |
1692 | } | 1683 | } |
1693 | 1684 | ||
1694 | static void pl011_shutdown(struct uart_port *port) | 1685 | /* |
1686 | * disable the port. It should not disable RTS and DTR. | ||
1687 | * Also RTS and DTR state should be preserved to restore | ||
1688 | * it during startup(). | ||
1689 | */ | ||
1690 | static void pl011_disable_uart(struct uart_amba_port *uap) | ||
1695 | { | 1691 | { |
1696 | struct uart_amba_port *uap = | ||
1697 | container_of(port, struct uart_amba_port, port); | ||
1698 | unsigned int cr; | 1692 | unsigned int cr; |
1699 | 1693 | ||
1700 | cancel_delayed_work_sync(&uap->tx_softirq_work); | ||
1701 | |||
1702 | /* | ||
1703 | * disable all interrupts | ||
1704 | */ | ||
1705 | spin_lock_irq(&uap->port.lock); | ||
1706 | uap->im = 0; | ||
1707 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
1708 | writew(0xffff, uap->port.membase + UART011_ICR); | ||
1709 | spin_unlock_irq(&uap->port.lock); | ||
1710 | |||
1711 | pl011_dma_shutdown(uap); | ||
1712 | |||
1713 | /* | ||
1714 | * Free the interrupt | ||
1715 | */ | ||
1716 | free_irq(uap->port.irq, uap); | ||
1717 | |||
1718 | /* | ||
1719 | * disable the port | ||
1720 | * disable the port. It should not disable RTS and DTR. | ||
1721 | * Also RTS and DTR state should be preserved to restore | ||
1722 | * it during startup(). | ||
1723 | */ | ||
1724 | uap->autorts = false; | 1694 | uap->autorts = false; |
1725 | spin_lock_irq(&uap->port.lock); | 1695 | spin_lock_irq(&uap->port.lock); |
1726 | cr = readw(uap->port.membase + UART011_CR); | 1696 | cr = readw(uap->port.membase + UART011_CR); |
@@ -1736,6 +1706,32 @@ static void pl011_shutdown(struct uart_port *port) | |||
1736 | pl011_shutdown_channel(uap, uap->lcrh_rx); | 1706 | pl011_shutdown_channel(uap, uap->lcrh_rx); |
1737 | if (uap->lcrh_rx != uap->lcrh_tx) | 1707 | if (uap->lcrh_rx != uap->lcrh_tx) |
1738 | pl011_shutdown_channel(uap, uap->lcrh_tx); | 1708 | pl011_shutdown_channel(uap, uap->lcrh_tx); |
1709 | } | ||
1710 | |||
1711 | static void pl011_disable_interrupts(struct uart_amba_port *uap) | ||
1712 | { | ||
1713 | spin_lock_irq(&uap->port.lock); | ||
1714 | |||
1715 | /* mask all interrupts and clear all pending ones */ | ||
1716 | uap->im = 0; | ||
1717 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
1718 | writew(0xffff, uap->port.membase + UART011_ICR); | ||
1719 | |||
1720 | spin_unlock_irq(&uap->port.lock); | ||
1721 | } | ||
1722 | |||
1723 | static void pl011_shutdown(struct uart_port *port) | ||
1724 | { | ||
1725 | struct uart_amba_port *uap = | ||
1726 | container_of(port, struct uart_amba_port, port); | ||
1727 | |||
1728 | pl011_disable_interrupts(uap); | ||
1729 | |||
1730 | pl011_dma_shutdown(uap); | ||
1731 | |||
1732 | free_irq(uap->port.irq, uap); | ||
1733 | |||
1734 | pl011_disable_uart(uap); | ||
1739 | 1735 | ||
1740 | /* | 1736 | /* |
1741 | * Shut down the clock producer | 1737 | * Shut down the clock producer |
@@ -1756,6 +1752,51 @@ static void pl011_shutdown(struct uart_port *port) | |||
1756 | uap->port.ops->flush_buffer(port); | 1752 | uap->port.ops->flush_buffer(port); |
1757 | } | 1753 | } |
1758 | 1754 | ||
1755 | static void sbsa_uart_shutdown(struct uart_port *port) | ||
1756 | { | ||
1757 | struct uart_amba_port *uap = | ||
1758 | container_of(port, struct uart_amba_port, port); | ||
1759 | |||
1760 | pl011_disable_interrupts(uap); | ||
1761 | |||
1762 | free_irq(uap->port.irq, uap); | ||
1763 | |||
1764 | if (uap->port.ops->flush_buffer) | ||
1765 | uap->port.ops->flush_buffer(port); | ||
1766 | } | ||
1767 | |||
1768 | static void | ||
1769 | pl011_setup_status_masks(struct uart_port *port, struct ktermios *termios) | ||
1770 | { | ||
1771 | port->read_status_mask = UART011_DR_OE | 255; | ||
1772 | if (termios->c_iflag & INPCK) | ||
1773 | port->read_status_mask |= UART011_DR_FE | UART011_DR_PE; | ||
1774 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) | ||
1775 | port->read_status_mask |= UART011_DR_BE; | ||
1776 | |||
1777 | /* | ||
1778 | * Characters to ignore | ||
1779 | */ | ||
1780 | port->ignore_status_mask = 0; | ||
1781 | if (termios->c_iflag & IGNPAR) | ||
1782 | port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE; | ||
1783 | if (termios->c_iflag & IGNBRK) { | ||
1784 | port->ignore_status_mask |= UART011_DR_BE; | ||
1785 | /* | ||
1786 | * If we're ignoring parity and break indicators, | ||
1787 | * ignore overruns too (for real raw support). | ||
1788 | */ | ||
1789 | if (termios->c_iflag & IGNPAR) | ||
1790 | port->ignore_status_mask |= UART011_DR_OE; | ||
1791 | } | ||
1792 | |||
1793 | /* | ||
1794 | * Ignore all characters if CREAD is not set. | ||
1795 | */ | ||
1796 | if ((termios->c_cflag & CREAD) == 0) | ||
1797 | port->ignore_status_mask |= UART_DUMMY_DR_RX; | ||
1798 | } | ||
1799 | |||
1759 | static void | 1800 | static void |
1760 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, | 1801 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, |
1761 | struct ktermios *old) | 1802 | struct ktermios *old) |
@@ -1820,33 +1861,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1820 | */ | 1861 | */ |
1821 | uart_update_timeout(port, termios->c_cflag, baud); | 1862 | uart_update_timeout(port, termios->c_cflag, baud); |
1822 | 1863 | ||
1823 | port->read_status_mask = UART011_DR_OE | 255; | 1864 | pl011_setup_status_masks(port, termios); |
1824 | if (termios->c_iflag & INPCK) | ||
1825 | port->read_status_mask |= UART011_DR_FE | UART011_DR_PE; | ||
1826 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) | ||
1827 | port->read_status_mask |= UART011_DR_BE; | ||
1828 | |||
1829 | /* | ||
1830 | * Characters to ignore | ||
1831 | */ | ||
1832 | port->ignore_status_mask = 0; | ||
1833 | if (termios->c_iflag & IGNPAR) | ||
1834 | port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE; | ||
1835 | if (termios->c_iflag & IGNBRK) { | ||
1836 | port->ignore_status_mask |= UART011_DR_BE; | ||
1837 | /* | ||
1838 | * If we're ignoring parity and break indicators, | ||
1839 | * ignore overruns too (for real raw support). | ||
1840 | */ | ||
1841 | if (termios->c_iflag & IGNPAR) | ||
1842 | port->ignore_status_mask |= UART011_DR_OE; | ||
1843 | } | ||
1844 | |||
1845 | /* | ||
1846 | * Ignore all characters if CREAD is not set. | ||
1847 | */ | ||
1848 | if ((termios->c_cflag & CREAD) == 0) | ||
1849 | port->ignore_status_mask |= UART_DUMMY_DR_RX; | ||
1850 | 1865 | ||
1851 | if (UART_ENABLE_MS(port, termios->c_cflag)) | 1866 | if (UART_ENABLE_MS(port, termios->c_cflag)) |
1852 | pl011_enable_ms(port); | 1867 | pl011_enable_ms(port); |
@@ -1901,6 +1916,27 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1901 | spin_unlock_irqrestore(&port->lock, flags); | 1916 | spin_unlock_irqrestore(&port->lock, flags); |
1902 | } | 1917 | } |
1903 | 1918 | ||
1919 | static void | ||
1920 | sbsa_uart_set_termios(struct uart_port *port, struct ktermios *termios, | ||
1921 | struct ktermios *old) | ||
1922 | { | ||
1923 | struct uart_amba_port *uap = | ||
1924 | container_of(port, struct uart_amba_port, port); | ||
1925 | unsigned long flags; | ||
1926 | |||
1927 | tty_termios_encode_baud_rate(termios, uap->fixed_baud, uap->fixed_baud); | ||
1928 | |||
1929 | /* The SBSA UART only supports 8n1 without hardware flow control. */ | ||
1930 | termios->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD); | ||
1931 | termios->c_cflag &= ~(CMSPAR | CRTSCTS); | ||
1932 | termios->c_cflag |= CS8 | CLOCAL; | ||
1933 | |||
1934 | spin_lock_irqsave(&port->lock, flags); | ||
1935 | uart_update_timeout(port, CS8, uap->fixed_baud); | ||
1936 | pl011_setup_status_masks(port, termios); | ||
1937 | spin_unlock_irqrestore(&port->lock, flags); | ||
1938 | } | ||
1939 | |||
1904 | static const char *pl011_type(struct uart_port *port) | 1940 | static const char *pl011_type(struct uart_port *port) |
1905 | { | 1941 | { |
1906 | struct uart_amba_port *uap = | 1942 | struct uart_amba_port *uap = |
@@ -1976,6 +2012,37 @@ static struct uart_ops amba_pl011_pops = { | |||
1976 | #endif | 2012 | #endif |
1977 | }; | 2013 | }; |
1978 | 2014 | ||
2015 | static void sbsa_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
2016 | { | ||
2017 | } | ||
2018 | |||
2019 | static unsigned int sbsa_uart_get_mctrl(struct uart_port *port) | ||
2020 | { | ||
2021 | return 0; | ||
2022 | } | ||
2023 | |||
2024 | static const struct uart_ops sbsa_uart_pops = { | ||
2025 | .tx_empty = pl011_tx_empty, | ||
2026 | .set_mctrl = sbsa_uart_set_mctrl, | ||
2027 | .get_mctrl = sbsa_uart_get_mctrl, | ||
2028 | .stop_tx = pl011_stop_tx, | ||
2029 | .start_tx = pl011_start_tx, | ||
2030 | .stop_rx = pl011_stop_rx, | ||
2031 | .startup = sbsa_uart_startup, | ||
2032 | .shutdown = sbsa_uart_shutdown, | ||
2033 | .set_termios = sbsa_uart_set_termios, | ||
2034 | .type = pl011_type, | ||
2035 | .release_port = pl011_release_port, | ||
2036 | .request_port = pl011_request_port, | ||
2037 | .config_port = pl011_config_port, | ||
2038 | .verify_port = pl011_verify_port, | ||
2039 | #ifdef CONFIG_CONSOLE_POLL | ||
2040 | .poll_init = pl011_hwinit, | ||
2041 | .poll_get_char = pl011_get_poll_char, | ||
2042 | .poll_put_char = pl011_put_poll_char, | ||
2043 | #endif | ||
2044 | }; | ||
2045 | |||
1979 | static struct uart_amba_port *amba_ports[UART_NR]; | 2046 | static struct uart_amba_port *amba_ports[UART_NR]; |
1980 | 2047 | ||
1981 | #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE | 2048 | #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE |
@@ -1994,7 +2061,7 @@ static void | |||
1994 | pl011_console_write(struct console *co, const char *s, unsigned int count) | 2061 | pl011_console_write(struct console *co, const char *s, unsigned int count) |
1995 | { | 2062 | { |
1996 | struct uart_amba_port *uap = amba_ports[co->index]; | 2063 | struct uart_amba_port *uap = amba_ports[co->index]; |
1997 | unsigned int status, old_cr, new_cr; | 2064 | unsigned int status, old_cr = 0, new_cr; |
1998 | unsigned long flags; | 2065 | unsigned long flags; |
1999 | int locked = 1; | 2066 | int locked = 1; |
2000 | 2067 | ||
@@ -2011,10 +2078,12 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) | |||
2011 | /* | 2078 | /* |
2012 | * First save the CR then disable the interrupts | 2079 | * First save the CR then disable the interrupts |
2013 | */ | 2080 | */ |
2014 | old_cr = readw(uap->port.membase + UART011_CR); | 2081 | if (!uap->vendor->always_enabled) { |
2015 | new_cr = old_cr & ~UART011_CR_CTSEN; | 2082 | old_cr = readw(uap->port.membase + UART011_CR); |
2016 | new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; | 2083 | new_cr = old_cr & ~UART011_CR_CTSEN; |
2017 | writew(new_cr, uap->port.membase + UART011_CR); | 2084 | new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; |
2085 | writew(new_cr, uap->port.membase + UART011_CR); | ||
2086 | } | ||
2018 | 2087 | ||
2019 | uart_console_write(&uap->port, s, count, pl011_console_putchar); | 2088 | uart_console_write(&uap->port, s, count, pl011_console_putchar); |
2020 | 2089 | ||
@@ -2025,7 +2094,8 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) | |||
2025 | do { | 2094 | do { |
2026 | status = readw(uap->port.membase + UART01x_FR); | 2095 | status = readw(uap->port.membase + UART01x_FR); |
2027 | } while (status & UART01x_FR_BUSY); | 2096 | } while (status & UART01x_FR_BUSY); |
2028 | writew(old_cr, uap->port.membase + UART011_CR); | 2097 | if (!uap->vendor->always_enabled) |
2098 | writew(old_cr, uap->port.membase + UART011_CR); | ||
2029 | 2099 | ||
2030 | if (locked) | 2100 | if (locked) |
2031 | spin_unlock(&uap->port.lock); | 2101 | spin_unlock(&uap->port.lock); |
@@ -2106,10 +2176,15 @@ static int __init pl011_console_setup(struct console *co, char *options) | |||
2106 | 2176 | ||
2107 | uap->port.uartclk = clk_get_rate(uap->clk); | 2177 | uap->port.uartclk = clk_get_rate(uap->clk); |
2108 | 2178 | ||
2109 | if (options) | 2179 | if (uap->vendor->fixed_options) { |
2110 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 2180 | baud = uap->fixed_baud; |
2111 | else | 2181 | } else { |
2112 | pl011_console_get_options(uap, &baud, &parity, &bits); | 2182 | if (options) |
2183 | uart_parse_options(options, | ||
2184 | &baud, &parity, &bits, &flow); | ||
2185 | else | ||
2186 | pl011_console_get_options(uap, &baud, &parity, &bits); | ||
2187 | } | ||
2113 | 2188 | ||
2114 | return uart_set_options(&uap->port, co, baud, parity, bits, flow); | 2189 | return uart_set_options(&uap->port, co, baud, parity, bits, flow); |
2115 | } | 2190 | } |
@@ -2201,97 +2276,126 @@ static int pl011_probe_dt_alias(int index, struct device *dev) | |||
2201 | return ret; | 2276 | return ret; |
2202 | } | 2277 | } |
2203 | 2278 | ||
2204 | static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | 2279 | /* unregisters the driver also if no more ports are left */ |
2280 | static void pl011_unregister_port(struct uart_amba_port *uap) | ||
2205 | { | 2281 | { |
2206 | struct uart_amba_port *uap; | 2282 | int i; |
2207 | struct vendor_data *vendor = id->data; | 2283 | bool busy = false; |
2208 | void __iomem *base; | 2284 | |
2209 | int i, ret; | 2285 | for (i = 0; i < ARRAY_SIZE(amba_ports); i++) { |
2286 | if (amba_ports[i] == uap) | ||
2287 | amba_ports[i] = NULL; | ||
2288 | else if (amba_ports[i]) | ||
2289 | busy = true; | ||
2290 | } | ||
2291 | pl011_dma_remove(uap); | ||
2292 | if (!busy) | ||
2293 | uart_unregister_driver(&amba_reg); | ||
2294 | } | ||
2295 | |||
2296 | static int pl011_find_free_port(void) | ||
2297 | { | ||
2298 | int i; | ||
2210 | 2299 | ||
2211 | for (i = 0; i < ARRAY_SIZE(amba_ports); i++) | 2300 | for (i = 0; i < ARRAY_SIZE(amba_ports); i++) |
2212 | if (amba_ports[i] == NULL) | 2301 | if (amba_ports[i] == NULL) |
2213 | break; | 2302 | return i; |
2214 | |||
2215 | if (i == ARRAY_SIZE(amba_ports)) | ||
2216 | return -EBUSY; | ||
2217 | 2303 | ||
2218 | uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port), | 2304 | return -EBUSY; |
2219 | GFP_KERNEL); | 2305 | } |
2220 | if (uap == NULL) | ||
2221 | return -ENOMEM; | ||
2222 | 2306 | ||
2223 | i = pl011_probe_dt_alias(i, &dev->dev); | 2307 | static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, |
2308 | struct resource *mmiobase, int index) | ||
2309 | { | ||
2310 | void __iomem *base; | ||
2224 | 2311 | ||
2225 | base = devm_ioremap(&dev->dev, dev->res.start, | 2312 | base = devm_ioremap_resource(dev, mmiobase); |
2226 | resource_size(&dev->res)); | ||
2227 | if (!base) | 2313 | if (!base) |
2228 | return -ENOMEM; | 2314 | return -ENOMEM; |
2229 | 2315 | ||
2230 | uap->clk = devm_clk_get(&dev->dev, NULL); | 2316 | index = pl011_probe_dt_alias(index, dev); |
2231 | if (IS_ERR(uap->clk)) | ||
2232 | return PTR_ERR(uap->clk); | ||
2233 | 2317 | ||
2234 | uap->vendor = vendor; | ||
2235 | uap->lcrh_rx = vendor->lcrh_rx; | ||
2236 | uap->lcrh_tx = vendor->lcrh_tx; | ||
2237 | uap->old_cr = 0; | 2318 | uap->old_cr = 0; |
2238 | uap->fifosize = vendor->get_fifosize(dev); | 2319 | uap->port.dev = dev; |
2239 | uap->port.dev = &dev->dev; | 2320 | uap->port.mapbase = mmiobase->start; |
2240 | uap->port.mapbase = dev->res.start; | ||
2241 | uap->port.membase = base; | 2321 | uap->port.membase = base; |
2242 | uap->port.iotype = UPIO_MEM; | 2322 | uap->port.iotype = UPIO_MEM; |
2243 | uap->port.irq = dev->irq[0]; | ||
2244 | uap->port.fifosize = uap->fifosize; | 2323 | uap->port.fifosize = uap->fifosize; |
2245 | uap->port.ops = &amba_pl011_pops; | ||
2246 | uap->port.flags = UPF_BOOT_AUTOCONF; | 2324 | uap->port.flags = UPF_BOOT_AUTOCONF; |
2247 | uap->port.line = i; | 2325 | uap->port.line = index; |
2248 | INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq); | ||
2249 | 2326 | ||
2250 | /* Ensure interrupts from this UART are masked and cleared */ | 2327 | amba_ports[index] = uap; |
2251 | writew(0, uap->port.membase + UART011_IMSC); | ||
2252 | writew(0xffff, uap->port.membase + UART011_ICR); | ||
2253 | 2328 | ||
2254 | snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); | 2329 | return 0; |
2330 | } | ||
2255 | 2331 | ||
2256 | amba_ports[i] = uap; | 2332 | static int pl011_register_port(struct uart_amba_port *uap) |
2333 | { | ||
2334 | int ret; | ||
2257 | 2335 | ||
2258 | amba_set_drvdata(dev, uap); | 2336 | /* Ensure interrupts from this UART are masked and cleared */ |
2337 | writew(0, uap->port.membase + UART011_IMSC); | ||
2338 | writew(0xffff, uap->port.membase + UART011_ICR); | ||
2259 | 2339 | ||
2260 | if (!amba_reg.state) { | 2340 | if (!amba_reg.state) { |
2261 | ret = uart_register_driver(&amba_reg); | 2341 | ret = uart_register_driver(&amba_reg); |
2262 | if (ret < 0) { | 2342 | if (ret < 0) { |
2263 | dev_err(&dev->dev, | 2343 | dev_err(uap->port.dev, |
2264 | "Failed to register AMBA-PL011 driver\n"); | 2344 | "Failed to register AMBA-PL011 driver\n"); |
2265 | return ret; | 2345 | return ret; |
2266 | } | 2346 | } |
2267 | } | 2347 | } |
2268 | 2348 | ||
2269 | ret = uart_add_one_port(&amba_reg, &uap->port); | 2349 | ret = uart_add_one_port(&amba_reg, &uap->port); |
2270 | if (ret) { | 2350 | if (ret) |
2271 | amba_ports[i] = NULL; | 2351 | pl011_unregister_port(uap); |
2272 | uart_unregister_driver(&amba_reg); | ||
2273 | } | ||
2274 | 2352 | ||
2275 | return ret; | 2353 | return ret; |
2276 | } | 2354 | } |
2277 | 2355 | ||
2356 | static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | ||
2357 | { | ||
2358 | struct uart_amba_port *uap; | ||
2359 | struct vendor_data *vendor = id->data; | ||
2360 | int portnr, ret; | ||
2361 | |||
2362 | portnr = pl011_find_free_port(); | ||
2363 | if (portnr < 0) | ||
2364 | return portnr; | ||
2365 | |||
2366 | uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port), | ||
2367 | GFP_KERNEL); | ||
2368 | if (!uap) | ||
2369 | return -ENOMEM; | ||
2370 | |||
2371 | uap->clk = devm_clk_get(&dev->dev, NULL); | ||
2372 | if (IS_ERR(uap->clk)) | ||
2373 | return PTR_ERR(uap->clk); | ||
2374 | |||
2375 | uap->vendor = vendor; | ||
2376 | uap->lcrh_rx = vendor->lcrh_rx; | ||
2377 | uap->lcrh_tx = vendor->lcrh_tx; | ||
2378 | uap->fifosize = vendor->get_fifosize(dev); | ||
2379 | uap->port.irq = dev->irq[0]; | ||
2380 | uap->port.ops = &amba_pl011_pops; | ||
2381 | |||
2382 | snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); | ||
2383 | |||
2384 | ret = pl011_setup_port(&dev->dev, uap, &dev->res, portnr); | ||
2385 | if (ret) | ||
2386 | return ret; | ||
2387 | |||
2388 | amba_set_drvdata(dev, uap); | ||
2389 | |||
2390 | return pl011_register_port(uap); | ||
2391 | } | ||
2392 | |||
2278 | static int pl011_remove(struct amba_device *dev) | 2393 | static int pl011_remove(struct amba_device *dev) |
2279 | { | 2394 | { |
2280 | struct uart_amba_port *uap = amba_get_drvdata(dev); | 2395 | struct uart_amba_port *uap = amba_get_drvdata(dev); |
2281 | bool busy = false; | ||
2282 | int i; | ||
2283 | 2396 | ||
2284 | uart_remove_one_port(&amba_reg, &uap->port); | 2397 | uart_remove_one_port(&amba_reg, &uap->port); |
2285 | 2398 | pl011_unregister_port(uap); | |
2286 | for (i = 0; i < ARRAY_SIZE(amba_ports); i++) | ||
2287 | if (amba_ports[i] == uap) | ||
2288 | amba_ports[i] = NULL; | ||
2289 | else if (amba_ports[i]) | ||
2290 | busy = true; | ||
2291 | |||
2292 | pl011_dma_remove(uap); | ||
2293 | if (!busy) | ||
2294 | uart_unregister_driver(&amba_reg); | ||
2295 | return 0; | 2399 | return 0; |
2296 | } | 2400 | } |
2297 | 2401 | ||
@@ -2319,6 +2423,86 @@ static int pl011_resume(struct device *dev) | |||
2319 | 2423 | ||
2320 | static SIMPLE_DEV_PM_OPS(pl011_dev_pm_ops, pl011_suspend, pl011_resume); | 2424 | static SIMPLE_DEV_PM_OPS(pl011_dev_pm_ops, pl011_suspend, pl011_resume); |
2321 | 2425 | ||
2426 | static int sbsa_uart_probe(struct platform_device *pdev) | ||
2427 | { | ||
2428 | struct uart_amba_port *uap; | ||
2429 | struct resource *r; | ||
2430 | int portnr, ret; | ||
2431 | int baudrate; | ||
2432 | |||
2433 | /* | ||
2434 | * Check the mandatory baud rate parameter in the DT node early | ||
2435 | * so that we can easily exit with the error. | ||
2436 | */ | ||
2437 | if (pdev->dev.of_node) { | ||
2438 | struct device_node *np = pdev->dev.of_node; | ||
2439 | |||
2440 | ret = of_property_read_u32(np, "current-speed", &baudrate); | ||
2441 | if (ret) | ||
2442 | return ret; | ||
2443 | } else { | ||
2444 | baudrate = 115200; | ||
2445 | } | ||
2446 | |||
2447 | portnr = pl011_find_free_port(); | ||
2448 | if (portnr < 0) | ||
2449 | return portnr; | ||
2450 | |||
2451 | uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port), | ||
2452 | GFP_KERNEL); | ||
2453 | if (!uap) | ||
2454 | return -ENOMEM; | ||
2455 | |||
2456 | uap->vendor = &vendor_sbsa; | ||
2457 | uap->fifosize = 32; | ||
2458 | uap->port.irq = platform_get_irq(pdev, 0); | ||
2459 | uap->port.ops = &sbsa_uart_pops; | ||
2460 | uap->fixed_baud = baudrate; | ||
2461 | |||
2462 | snprintf(uap->type, sizeof(uap->type), "SBSA"); | ||
2463 | |||
2464 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2465 | |||
2466 | ret = pl011_setup_port(&pdev->dev, uap, r, portnr); | ||
2467 | if (ret) | ||
2468 | return ret; | ||
2469 | |||
2470 | platform_set_drvdata(pdev, uap); | ||
2471 | |||
2472 | return pl011_register_port(uap); | ||
2473 | } | ||
2474 | |||
2475 | static int sbsa_uart_remove(struct platform_device *pdev) | ||
2476 | { | ||
2477 | struct uart_amba_port *uap = platform_get_drvdata(pdev); | ||
2478 | |||
2479 | uart_remove_one_port(&amba_reg, &uap->port); | ||
2480 | pl011_unregister_port(uap); | ||
2481 | return 0; | ||
2482 | } | ||
2483 | |||
2484 | static const struct of_device_id sbsa_uart_of_match[] = { | ||
2485 | { .compatible = "arm,sbsa-uart", }, | ||
2486 | {}, | ||
2487 | }; | ||
2488 | MODULE_DEVICE_TABLE(of, sbsa_uart_of_match); | ||
2489 | |||
2490 | static const struct acpi_device_id sbsa_uart_acpi_match[] = { | ||
2491 | { "ARMH0011", 0 }, | ||
2492 | {}, | ||
2493 | }; | ||
2494 | MODULE_DEVICE_TABLE(acpi, sbsa_uart_acpi_match); | ||
2495 | |||
2496 | static struct platform_driver arm_sbsa_uart_platform_driver = { | ||
2497 | .probe = sbsa_uart_probe, | ||
2498 | .remove = sbsa_uart_remove, | ||
2499 | .driver = { | ||
2500 | .name = "sbsa-uart", | ||
2501 | .of_match_table = of_match_ptr(sbsa_uart_of_match), | ||
2502 | .acpi_match_table = ACPI_PTR(sbsa_uart_acpi_match), | ||
2503 | }, | ||
2504 | }; | ||
2505 | |||
2322 | static struct amba_id pl011_ids[] = { | 2506 | static struct amba_id pl011_ids[] = { |
2323 | { | 2507 | { |
2324 | .id = 0x00041011, | 2508 | .id = 0x00041011, |
@@ -2349,11 +2533,14 @@ static int __init pl011_init(void) | |||
2349 | { | 2533 | { |
2350 | printk(KERN_INFO "Serial: AMBA PL011 UART driver\n"); | 2534 | printk(KERN_INFO "Serial: AMBA PL011 UART driver\n"); |
2351 | 2535 | ||
2536 | if (platform_driver_register(&arm_sbsa_uart_platform_driver)) | ||
2537 | pr_warn("could not register SBSA UART platform driver\n"); | ||
2352 | return amba_driver_register(&pl011_driver); | 2538 | return amba_driver_register(&pl011_driver); |
2353 | } | 2539 | } |
2354 | 2540 | ||
2355 | static void __exit pl011_exit(void) | 2541 | static void __exit pl011_exit(void) |
2356 | { | 2542 | { |
2543 | platform_driver_unregister(&arm_sbsa_uart_platform_driver); | ||
2357 | amba_driver_unregister(&pl011_driver); | 2544 | amba_driver_unregister(&pl011_driver); |
2358 | } | 2545 | } |
2359 | 2546 | ||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 27dade29646b..2a8f528153e7 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -165,6 +165,7 @@ struct atmel_uart_port { | |||
165 | struct tasklet_struct tasklet; | 165 | struct tasklet_struct tasklet; |
166 | unsigned int irq_status; | 166 | unsigned int irq_status; |
167 | unsigned int irq_status_prev; | 167 | unsigned int irq_status_prev; |
168 | unsigned int status_change; | ||
168 | 169 | ||
169 | struct circ_buf rx_ring; | 170 | struct circ_buf rx_ring; |
170 | 171 | ||
@@ -315,8 +316,7 @@ static int atmel_config_rs485(struct uart_port *port, | |||
315 | if (rs485conf->flags & SER_RS485_ENABLED) { | 316 | if (rs485conf->flags & SER_RS485_ENABLED) { |
316 | dev_dbg(port->dev, "Setting UART to RS485\n"); | 317 | dev_dbg(port->dev, "Setting UART to RS485\n"); |
317 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | 318 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; |
318 | if ((rs485conf->delay_rts_after_send) > 0) | 319 | UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); |
319 | UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); | ||
320 | mode |= ATMEL_US_USMODE_RS485; | 320 | mode |= ATMEL_US_USMODE_RS485; |
321 | } else { | 321 | } else { |
322 | dev_dbg(port->dev, "Setting UART to RS232\n"); | 322 | dev_dbg(port->dev, "Setting UART to RS232\n"); |
@@ -354,8 +354,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
354 | 354 | ||
355 | /* override mode to RS485 if needed, otherwise keep the current mode */ | 355 | /* override mode to RS485 if needed, otherwise keep the current mode */ |
356 | if (port->rs485.flags & SER_RS485_ENABLED) { | 356 | if (port->rs485.flags & SER_RS485_ENABLED) { |
357 | if ((port->rs485.delay_rts_after_send) > 0) | 357 | UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); |
358 | UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); | ||
359 | mode &= ~ATMEL_US_USMODE; | 358 | mode &= ~ATMEL_US_USMODE; |
360 | mode |= ATMEL_US_USMODE_RS485; | 359 | mode |= ATMEL_US_USMODE_RS485; |
361 | } | 360 | } |
@@ -1177,6 +1176,9 @@ atmel_handle_status(struct uart_port *port, unsigned int pending, | |||
1177 | if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC | 1176 | if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC |
1178 | | ATMEL_US_CTSIC)) { | 1177 | | ATMEL_US_CTSIC)) { |
1179 | atmel_port->irq_status = status; | 1178 | atmel_port->irq_status = status; |
1179 | atmel_port->status_change = atmel_port->irq_status ^ | ||
1180 | atmel_port->irq_status_prev; | ||
1181 | atmel_port->irq_status_prev = status; | ||
1180 | tasklet_schedule(&atmel_port->tasklet); | 1182 | tasklet_schedule(&atmel_port->tasklet); |
1181 | } | 1183 | } |
1182 | } | 1184 | } |
@@ -1523,17 +1525,14 @@ static void atmel_tasklet_func(unsigned long data) | |||
1523 | { | 1525 | { |
1524 | struct uart_port *port = (struct uart_port *)data; | 1526 | struct uart_port *port = (struct uart_port *)data; |
1525 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1527 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
1526 | unsigned int status; | 1528 | unsigned int status = atmel_port->irq_status; |
1527 | unsigned int status_change; | 1529 | unsigned int status_change = atmel_port->status_change; |
1528 | 1530 | ||
1529 | /* The interrupt handler does not take the lock */ | 1531 | /* The interrupt handler does not take the lock */ |
1530 | spin_lock(&port->lock); | 1532 | spin_lock(&port->lock); |
1531 | 1533 | ||
1532 | atmel_port->schedule_tx(port); | 1534 | atmel_port->schedule_tx(port); |
1533 | 1535 | ||
1534 | status = atmel_port->irq_status; | ||
1535 | status_change = status ^ atmel_port->irq_status_prev; | ||
1536 | |||
1537 | if (status_change & (ATMEL_US_RI | ATMEL_US_DSR | 1536 | if (status_change & (ATMEL_US_RI | ATMEL_US_DSR |
1538 | | ATMEL_US_DCD | ATMEL_US_CTS)) { | 1537 | | ATMEL_US_DCD | ATMEL_US_CTS)) { |
1539 | /* TODO: All reads to CSR will clear these interrupts! */ | 1538 | /* TODO: All reads to CSR will clear these interrupts! */ |
@@ -1548,7 +1547,7 @@ static void atmel_tasklet_func(unsigned long data) | |||
1548 | 1547 | ||
1549 | wake_up_interruptible(&port->state->port.delta_msr_wait); | 1548 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
1550 | 1549 | ||
1551 | atmel_port->irq_status_prev = status; | 1550 | atmel_port->status_change = 0; |
1552 | } | 1551 | } |
1553 | 1552 | ||
1554 | atmel_port->schedule_rx(port); | 1553 | atmel_port->schedule_rx(port); |
@@ -2061,8 +2060,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2061 | 2060 | ||
2062 | /* mode */ | 2061 | /* mode */ |
2063 | if (port->rs485.flags & SER_RS485_ENABLED) { | 2062 | if (port->rs485.flags & SER_RS485_ENABLED) { |
2064 | if ((port->rs485.delay_rts_after_send) > 0) | 2063 | UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); |
2065 | UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); | ||
2066 | mode |= ATMEL_US_USMODE_RS485; | 2064 | mode |= ATMEL_US_USMODE_RS485; |
2067 | } else if (termios->c_cflag & CRTSCTS) { | 2065 | } else if (termios->c_cflag & CRTSCTS) { |
2068 | /* RS232 with hardware handshake (RTS/CTS) */ | 2066 | /* RS232 with hardware handshake (RTS/CTS) */ |
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 155781ece050..ae3cf94b146b 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -74,8 +74,8 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart); | |||
74 | 74 | ||
75 | static void bfin_serial_reset_irda(struct uart_port *port); | 75 | static void bfin_serial_reset_irda(struct uart_port *port); |
76 | 76 | ||
77 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | 77 | #if defined(SERIAL_BFIN_CTSRTS) || \ |
78 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | 78 | defined(SERIAL_BFIN_HARD_CTSRTS) |
79 | static unsigned int bfin_serial_get_mctrl(struct uart_port *port) | 79 | static unsigned int bfin_serial_get_mctrl(struct uart_port *port) |
80 | { | 80 | { |
81 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 81 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
@@ -110,7 +110,7 @@ static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) | |||
110 | struct bfin_serial_port *uart = dev_id; | 110 | struct bfin_serial_port *uart = dev_id; |
111 | struct uart_port *uport = &uart->port; | 111 | struct uart_port *uport = &uart->port; |
112 | unsigned int status = bfin_serial_get_mctrl(uport); | 112 | unsigned int status = bfin_serial_get_mctrl(uport); |
113 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 113 | #ifdef SERIAL_BFIN_HARD_CTSRTS |
114 | 114 | ||
115 | UART_CLEAR_SCTS(uart); | 115 | UART_CLEAR_SCTS(uart); |
116 | if (uport->hw_stopped) { | 116 | if (uport->hw_stopped) { |
@@ -700,7 +700,7 @@ static int bfin_serial_startup(struct uart_port *port) | |||
700 | # endif | 700 | # endif |
701 | #endif | 701 | #endif |
702 | 702 | ||
703 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 703 | #ifdef SERIAL_BFIN_CTSRTS |
704 | if (uart->cts_pin >= 0) { | 704 | if (uart->cts_pin >= 0) { |
705 | if (request_irq(gpio_to_irq(uart->cts_pin), | 705 | if (request_irq(gpio_to_irq(uart->cts_pin), |
706 | bfin_serial_mctrl_cts_int, | 706 | bfin_serial_mctrl_cts_int, |
@@ -718,7 +718,7 @@ static int bfin_serial_startup(struct uart_port *port) | |||
718 | gpio_direction_output(uart->rts_pin, 0); | 718 | gpio_direction_output(uart->rts_pin, 0); |
719 | } | 719 | } |
720 | #endif | 720 | #endif |
721 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 721 | #ifdef SERIAL_BFIN_HARD_CTSRTS |
722 | if (uart->cts_pin >= 0) { | 722 | if (uart->cts_pin >= 0) { |
723 | if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int, | 723 | if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int, |
724 | 0, "BFIN_UART_MODEM_STATUS", uart)) { | 724 | 0, "BFIN_UART_MODEM_STATUS", uart)) { |
@@ -766,13 +766,13 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
766 | free_irq(uart->tx_irq, uart); | 766 | free_irq(uart->tx_irq, uart); |
767 | #endif | 767 | #endif |
768 | 768 | ||
769 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 769 | #ifdef SERIAL_BFIN_CTSRTS |
770 | if (uart->cts_pin >= 0) | 770 | if (uart->cts_pin >= 0) |
771 | free_irq(gpio_to_irq(uart->cts_pin), uart); | 771 | free_irq(gpio_to_irq(uart->cts_pin), uart); |
772 | if (uart->rts_pin >= 0) | 772 | if (uart->rts_pin >= 0) |
773 | gpio_free(uart->rts_pin); | 773 | gpio_free(uart->rts_pin); |
774 | #endif | 774 | #endif |
775 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 775 | #ifdef SERIAL_BFIN_HARD_CTSRTS |
776 | if (uart->cts_pin >= 0) | 776 | if (uart->cts_pin >= 0) |
777 | free_irq(uart->status_irq, uart); | 777 | free_irq(uart->status_irq, uart); |
778 | #endif | 778 | #endif |
@@ -788,7 +788,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
788 | unsigned int ier, lcr = 0; | 788 | unsigned int ier, lcr = 0; |
789 | unsigned long timeout; | 789 | unsigned long timeout; |
790 | 790 | ||
791 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 791 | #ifdef SERIAL_BFIN_CTSRTS |
792 | if (old == NULL && uart->cts_pin != -1) | 792 | if (old == NULL && uart->cts_pin != -1) |
793 | termios->c_cflag |= CRTSCTS; | 793 | termios->c_cflag |= CRTSCTS; |
794 | else if (uart->cts_pin == -1) | 794 | else if (uart->cts_pin == -1) |
@@ -1110,8 +1110,8 @@ bfin_serial_console_setup(struct console *co, char *options) | |||
1110 | int baud = 57600; | 1110 | int baud = 57600; |
1111 | int bits = 8; | 1111 | int bits = 8; |
1112 | int parity = 'n'; | 1112 | int parity = 'n'; |
1113 | # if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | 1113 | # if defined(SERIAL_BFIN_CTSRTS) || \ |
1114 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | 1114 | defined(SERIAL_BFIN_HARD_CTSRTS) |
1115 | int flow = 'r'; | 1115 | int flow = 'r'; |
1116 | # else | 1116 | # else |
1117 | int flow = 'n'; | 1117 | int flow = 'n'; |
@@ -1322,8 +1322,8 @@ static int bfin_serial_probe(struct platform_device *pdev) | |||
1322 | init_timer(&(uart->rx_dma_timer)); | 1322 | init_timer(&(uart->rx_dma_timer)); |
1323 | #endif | 1323 | #endif |
1324 | 1324 | ||
1325 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | 1325 | #if defined(SERIAL_BFIN_CTSRTS) || \ |
1326 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | 1326 | defined(SERIAL_BFIN_HARD_CTSRTS) |
1327 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1327 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1328 | if (res == NULL) | 1328 | if (res == NULL) |
1329 | uart->cts_pin = -1; | 1329 | uart->cts_pin = -1; |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 0c1825b0b41d..3e4470af5c50 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -56,10 +56,6 @@ static char *serial_version = "$Revision: 1.25 $"; | |||
56 | #error "RX_TIMEOUT_TICKS == 0 not allowed, use 1" | 56 | #error "RX_TIMEOUT_TICKS == 0 not allowed, use 1" |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #if defined(CONFIG_ETRAX_RS485_ON_PA) && defined(CONFIG_ETRAX_RS485_ON_PORT_G) | ||
60 | #error "Disable either CONFIG_ETRAX_RS485_ON_PA or CONFIG_ETRAX_RS485_ON_PORT_G" | ||
61 | #endif | ||
62 | |||
63 | /* | 59 | /* |
64 | * All of the compatibilty code so we can compile serial.c against | 60 | * All of the compatibilty code so we can compile serial.c against |
65 | * older kernels is hidden in serial_compat.h | 61 | * older kernels is hidden in serial_compat.h |
@@ -455,30 +451,6 @@ static struct e100_serial rs_table[] = { | |||
455 | static struct fast_timer fast_timers[NR_PORTS]; | 451 | static struct fast_timer fast_timers[NR_PORTS]; |
456 | #endif | 452 | #endif |
457 | 453 | ||
458 | #ifdef CONFIG_ETRAX_SERIAL_PROC_ENTRY | ||
459 | #define PROCSTAT(x) x | ||
460 | struct ser_statistics_type { | ||
461 | int overrun_cnt; | ||
462 | int early_errors_cnt; | ||
463 | int ser_ints_ok_cnt; | ||
464 | int errors_cnt; | ||
465 | unsigned long int processing_flip; | ||
466 | unsigned long processing_flip_still_room; | ||
467 | unsigned long int timeout_flush_cnt; | ||
468 | int rx_dma_ints; | ||
469 | int tx_dma_ints; | ||
470 | int rx_tot; | ||
471 | int tx_tot; | ||
472 | }; | ||
473 | |||
474 | static struct ser_statistics_type ser_stat[NR_PORTS]; | ||
475 | |||
476 | #else | ||
477 | |||
478 | #define PROCSTAT(x) | ||
479 | |||
480 | #endif /* CONFIG_ETRAX_SERIAL_PROC_ENTRY */ | ||
481 | |||
482 | /* RS-485 */ | 454 | /* RS-485 */ |
483 | #if defined(CONFIG_ETRAX_RS485) | 455 | #if defined(CONFIG_ETRAX_RS485) |
484 | #ifdef CONFIG_ETRAX_FAST_TIMER | 456 | #ifdef CONFIG_ETRAX_FAST_TIMER |
@@ -487,9 +459,6 @@ static struct fast_timer fast_timers_rs485[NR_PORTS]; | |||
487 | #if defined(CONFIG_ETRAX_RS485_ON_PA) | 459 | #if defined(CONFIG_ETRAX_RS485_ON_PA) |
488 | static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT; | 460 | static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT; |
489 | #endif | 461 | #endif |
490 | #if defined(CONFIG_ETRAX_RS485_ON_PORT_G) | ||
491 | static int rs485_port_g_bit = CONFIG_ETRAX_RS485_ON_PORT_G_BIT; | ||
492 | #endif | ||
493 | #endif | 462 | #endif |
494 | 463 | ||
495 | /* Info and macros needed for each ports extra control/status signals. */ | 464 | /* Info and macros needed for each ports extra control/status signals. */ |
@@ -739,10 +708,10 @@ static unsigned char dummy_ser[NR_PORTS] = {0xFF, 0xFF, 0xFF,0xFF}; | |||
739 | defined(CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED) || \ | 708 | defined(CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED) || \ |
740 | defined(CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED) || \ | 709 | defined(CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED) || \ |
741 | defined(CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED) | 710 | defined(CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED) |
742 | #define CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED | 711 | #define ETRAX_SERX_DTR_RI_DSR_CD_MIXED |
743 | #endif | 712 | #endif |
744 | 713 | ||
745 | #ifdef CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED | 714 | #ifdef ETRAX_SERX_DTR_RI_DSR_CD_MIXED |
746 | /* The pins can be mixed on PA and PB */ | 715 | /* The pins can be mixed on PA and PB */ |
747 | #define CONTROL_PINS_PORT_NOT_USED(line) \ | 716 | #define CONTROL_PINS_PORT_NOT_USED(line) \ |
748 | &dummy_ser[line], &dummy_ser[line], \ | 717 | &dummy_ser[line], &dummy_ser[line], \ |
@@ -835,7 +804,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] = | |||
835 | #endif | 804 | #endif |
836 | } | 805 | } |
837 | }; | 806 | }; |
838 | #else /* CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED */ | 807 | #else /* ETRAX_SERX_DTR_RI_DSR_CD_MIXED */ |
839 | 808 | ||
840 | /* All pins are on either PA or PB for each serial port */ | 809 | /* All pins are on either PA or PB for each serial port */ |
841 | #define CONTROL_PINS_PORT_NOT_USED(line) \ | 810 | #define CONTROL_PINS_PORT_NOT_USED(line) \ |
@@ -917,7 +886,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] = | |||
917 | #endif | 886 | #endif |
918 | } | 887 | } |
919 | }; | 888 | }; |
920 | #endif /* !CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED */ | 889 | #endif /* !ETRAX_SERX_DTR_RI_DSR_CD_MIXED */ |
921 | 890 | ||
922 | #define E100_RTS_MASK 0x20 | 891 | #define E100_RTS_MASK 0x20 |
923 | #define E100_CTS_MASK 0x40 | 892 | #define E100_CTS_MASK 0x40 |
@@ -1367,16 +1336,6 @@ e100_enable_rs485(struct tty_struct *tty, struct serial_rs485 *r) | |||
1367 | #if defined(CONFIG_ETRAX_RS485_ON_PA) | 1336 | #if defined(CONFIG_ETRAX_RS485_ON_PA) |
1368 | *R_PORT_PA_DATA = port_pa_data_shadow |= (1 << rs485_pa_bit); | 1337 | *R_PORT_PA_DATA = port_pa_data_shadow |= (1 << rs485_pa_bit); |
1369 | #endif | 1338 | #endif |
1370 | #if defined(CONFIG_ETRAX_RS485_ON_PORT_G) | ||
1371 | REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, | ||
1372 | rs485_port_g_bit, 1); | ||
1373 | #endif | ||
1374 | #if defined(CONFIG_ETRAX_RS485_LTC1387) | ||
1375 | REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, | ||
1376 | CONFIG_ETRAX_RS485_LTC1387_DXEN_PORT_G_BIT, 1); | ||
1377 | REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, | ||
1378 | CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1); | ||
1379 | #endif | ||
1380 | 1339 | ||
1381 | info->rs485 = *r; | 1340 | info->rs485 = *r; |
1382 | 1341 | ||
@@ -1676,7 +1635,8 @@ alloc_recv_buffer(unsigned int size) | |||
1676 | { | 1635 | { |
1677 | struct etrax_recv_buffer *buffer; | 1636 | struct etrax_recv_buffer *buffer; |
1678 | 1637 | ||
1679 | if (!(buffer = kmalloc(sizeof *buffer + size, GFP_ATOMIC))) | 1638 | buffer = kmalloc(sizeof *buffer + size, GFP_ATOMIC); |
1639 | if (!buffer) | ||
1680 | return NULL; | 1640 | return NULL; |
1681 | 1641 | ||
1682 | buffer->next = NULL; | 1642 | buffer->next = NULL; |
@@ -1712,7 +1672,8 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl | |||
1712 | { | 1672 | { |
1713 | struct etrax_recv_buffer *buffer; | 1673 | struct etrax_recv_buffer *buffer; |
1714 | if (info->uses_dma_in) { | 1674 | if (info->uses_dma_in) { |
1715 | if (!(buffer = alloc_recv_buffer(4))) | 1675 | buffer = alloc_recv_buffer(4); |
1676 | if (!buffer) | ||
1716 | return 0; | 1677 | return 0; |
1717 | 1678 | ||
1718 | buffer->length = 1; | 1679 | buffer->length = 1; |
@@ -1750,7 +1711,8 @@ static unsigned int handle_descr_data(struct e100_serial *info, | |||
1750 | 1711 | ||
1751 | append_recv_buffer(info, buffer); | 1712 | append_recv_buffer(info, buffer); |
1752 | 1713 | ||
1753 | if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE))) | 1714 | buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE); |
1715 | if (!buffer) | ||
1754 | panic("%s: Failed to allocate memory for receive buffer!\n", __func__); | 1716 | panic("%s: Failed to allocate memory for receive buffer!\n", __func__); |
1755 | 1717 | ||
1756 | descr->buf = virt_to_phys(buffer->buffer); | 1718 | descr->buf = virt_to_phys(buffer->buffer); |
@@ -1841,7 +1803,6 @@ static void receive_chars_dma(struct e100_serial *info) | |||
1841 | */ | 1803 | */ |
1842 | unsigned char data = info->ioport[REG_DATA]; | 1804 | unsigned char data = info->ioport[REG_DATA]; |
1843 | 1805 | ||
1844 | PROCSTAT(ser_stat[info->line].errors_cnt++); | ||
1845 | DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n", | 1806 | DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n", |
1846 | ((rstat & SER_ERROR_MASK) << 8) | data); | 1807 | ((rstat & SER_ERROR_MASK) << 8) | data); |
1847 | 1808 | ||
@@ -1867,7 +1828,8 @@ static int start_recv_dma(struct e100_serial *info) | |||
1867 | 1828 | ||
1868 | /* Set up the receiving descriptors */ | 1829 | /* Set up the receiving descriptors */ |
1869 | for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) { | 1830 | for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) { |
1870 | if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE))) | 1831 | buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE); |
1832 | if (!buffer) | ||
1871 | panic("%s: Failed to allocate memory for receive buffer!\n", __func__); | 1833 | panic("%s: Failed to allocate memory for receive buffer!\n", __func__); |
1872 | 1834 | ||
1873 | descr[i].ctrl = d_int; | 1835 | descr[i].ctrl = d_int; |
@@ -1943,7 +1905,6 @@ tr_interrupt(int irq, void *dev_id) | |||
1943 | /* Read jiffies_usec first, | 1905 | /* Read jiffies_usec first, |
1944 | * we want this time to be as late as possible | 1906 | * we want this time to be as late as possible |
1945 | */ | 1907 | */ |
1946 | PROCSTAT(ser_stat[info->line].tx_dma_ints++); | ||
1947 | info->last_tx_active_usec = GET_JIFFIES_USEC(); | 1908 | info->last_tx_active_usec = GET_JIFFIES_USEC(); |
1948 | info->last_tx_active = jiffies; | 1909 | info->last_tx_active = jiffies; |
1949 | transmit_chars_dma(info); | 1910 | transmit_chars_dma(info); |
@@ -2022,7 +1983,6 @@ static int force_eop_if_needed(struct e100_serial *info) | |||
2022 | */ | 1983 | */ |
2023 | if (!info->forced_eop) { | 1984 | if (!info->forced_eop) { |
2024 | info->forced_eop = 1; | 1985 | info->forced_eop = 1; |
2025 | PROCSTAT(ser_stat[info->line].timeout_flush_cnt++); | ||
2026 | TIMERD(DEBUG_LOG(info->line, "timeout EOP %i\n", info->line)); | 1986 | TIMERD(DEBUG_LOG(info->line, "timeout EOP %i\n", info->line)); |
2027 | FORCE_EOP(info); | 1987 | FORCE_EOP(info); |
2028 | } | 1988 | } |
@@ -2374,7 +2334,6 @@ static void handle_ser_rx_interrupt(struct e100_serial *info) | |||
2374 | DEBUG_LOG(info->line, "#iERR s d %04X\n", | 2334 | DEBUG_LOG(info->line, "#iERR s d %04X\n", |
2375 | ((rstat & SER_ERROR_MASK) << 8) | data); | 2335 | ((rstat & SER_ERROR_MASK) << 8) | data); |
2376 | } | 2336 | } |
2377 | PROCSTAT(ser_stat[info->line].early_errors_cnt++); | ||
2378 | } else { /* It was a valid byte, now let the DMA do the rest */ | 2337 | } else { /* It was a valid byte, now let the DMA do the rest */ |
2379 | unsigned long curr_time_u = GET_JIFFIES_USEC(); | 2338 | unsigned long curr_time_u = GET_JIFFIES_USEC(); |
2380 | unsigned long curr_time = jiffies; | 2339 | unsigned long curr_time = jiffies; |
@@ -2407,7 +2366,6 @@ static void handle_ser_rx_interrupt(struct e100_serial *info) | |||
2407 | DINTR2(DEBUG_LOG(info->line, "ser_rx OK %d\n", info->line)); | 2366 | DINTR2(DEBUG_LOG(info->line, "ser_rx OK %d\n", info->line)); |
2408 | info->break_detected_cnt = 0; | 2367 | info->break_detected_cnt = 0; |
2409 | 2368 | ||
2410 | PROCSTAT(ser_stat[info->line].ser_ints_ok_cnt++); | ||
2411 | } | 2369 | } |
2412 | /* Restarting the DMA never hurts */ | 2370 | /* Restarting the DMA never hurts */ |
2413 | *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); | 2371 | *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); |
@@ -2867,19 +2825,6 @@ change_speed(struct e100_serial *info) | |||
2867 | *R_SERIAL_PRESCALE = divisor; | 2825 | *R_SERIAL_PRESCALE = divisor; |
2868 | info->baud = SERIAL_PRESCALE_BASE/divisor; | 2826 | info->baud = SERIAL_PRESCALE_BASE/divisor; |
2869 | } | 2827 | } |
2870 | #ifdef CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED | ||
2871 | else if ((info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8 && | ||
2872 | info->custom_divisor == 1) || | ||
2873 | (info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ && | ||
2874 | info->custom_divisor == 8)) { | ||
2875 | /* ext_clk selected */ | ||
2876 | alt_source = | ||
2877 | IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, extern) | | ||
2878 | IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, extern); | ||
2879 | DBAUD(printk("using external baudrate: %lu\n", CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8)); | ||
2880 | info->baud = CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8; | ||
2881 | } | ||
2882 | #endif | ||
2883 | else | 2828 | else |
2884 | { | 2829 | { |
2885 | /* Bad baudbase, we don't support using timer0 | 2830 | /* Bad baudbase, we don't support using timer0 |
@@ -3216,9 +3161,7 @@ rs_throttle(struct tty_struct * tty) | |||
3216 | { | 3161 | { |
3217 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3162 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3218 | #ifdef SERIAL_DEBUG_THROTTLE | 3163 | #ifdef SERIAL_DEBUG_THROTTLE |
3219 | char buf[64]; | 3164 | printk("throttle %s: %lu....\n", tty_name(tty), |
3220 | |||
3221 | printk("throttle %s: %lu....\n", tty_name(tty, buf), | ||
3222 | (unsigned long)tty->ldisc.chars_in_buffer(tty)); | 3165 | (unsigned long)tty->ldisc.chars_in_buffer(tty)); |
3223 | #endif | 3166 | #endif |
3224 | DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); | 3167 | DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); |
@@ -3238,9 +3181,7 @@ rs_unthrottle(struct tty_struct * tty) | |||
3238 | { | 3181 | { |
3239 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3182 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3240 | #ifdef SERIAL_DEBUG_THROTTLE | 3183 | #ifdef SERIAL_DEBUG_THROTTLE |
3241 | char buf[64]; | 3184 | printk("unthrottle %s: %lu....\n", tty_name(tty), |
3242 | |||
3243 | printk("unthrottle %s: %lu....\n", tty_name(tty, buf), | ||
3244 | (unsigned long)tty->ldisc.chars_in_buffer(tty)); | 3185 | (unsigned long)tty->ldisc.chars_in_buffer(tty)); |
3245 | #endif | 3186 | #endif |
3246 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); | 3187 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); |
@@ -3725,16 +3666,6 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3725 | #if defined(CONFIG_ETRAX_RS485_ON_PA) | 3666 | #if defined(CONFIG_ETRAX_RS485_ON_PA) |
3726 | *R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit); | 3667 | *R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit); |
3727 | #endif | 3668 | #endif |
3728 | #if defined(CONFIG_ETRAX_RS485_ON_PORT_G) | ||
3729 | REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, | ||
3730 | rs485_port_g_bit, 0); | ||
3731 | #endif | ||
3732 | #if defined(CONFIG_ETRAX_RS485_LTC1387) | ||
3733 | REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, | ||
3734 | CONFIG_ETRAX_RS485_LTC1387_DXEN_PORT_G_BIT, 0); | ||
3735 | REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, | ||
3736 | CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 0); | ||
3737 | #endif | ||
3738 | } | 3669 | } |
3739 | #endif | 3670 | #endif |
3740 | 3671 | ||
@@ -4263,15 +4194,6 @@ static int __init rs_init(void) | |||
4263 | return -EBUSY; | 4194 | return -EBUSY; |
4264 | } | 4195 | } |
4265 | #endif | 4196 | #endif |
4266 | #if defined(CONFIG_ETRAX_RS485_ON_PORT_G) | ||
4267 | if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit, | ||
4268 | rs485_port_g_bit)) { | ||
4269 | printk(KERN_ERR "ETRAX100LX serial: Could not allocate " | ||
4270 | "RS485 pin\n"); | ||
4271 | put_tty_driver(driver); | ||
4272 | return -EBUSY; | ||
4273 | } | ||
4274 | #endif | ||
4275 | #endif | 4197 | #endif |
4276 | 4198 | ||
4277 | /* Initialize the tty_driver structure */ | 4199 | /* Initialize the tty_driver structure */ |
diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index 6dc471e30e79..f09636083426 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c | |||
@@ -72,6 +72,7 @@ static int __init parse_options(struct earlycon_device *device, char *options) | |||
72 | 72 | ||
73 | switch (port->iotype) { | 73 | switch (port->iotype) { |
74 | case UPIO_MEM32: | 74 | case UPIO_MEM32: |
75 | case UPIO_MEM32BE: | ||
75 | port->regshift = 2; /* fall-through */ | 76 | port->regshift = 2; /* fall-through */ |
76 | case UPIO_MEM: | 77 | case UPIO_MEM: |
77 | port->mapbase = addr; | 78 | port->mapbase = addr; |
@@ -90,9 +91,11 @@ static int __init parse_options(struct earlycon_device *device, char *options) | |||
90 | strlcpy(device->options, options, length); | 91 | strlcpy(device->options, options, length); |
91 | } | 92 | } |
92 | 93 | ||
93 | if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM32) | 94 | if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM32 || |
95 | port->iotype == UPIO_MEM32BE) | ||
94 | pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n", | 96 | pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n", |
95 | (port->iotype == UPIO_MEM32) ? "32" : "", | 97 | (port->iotype == UPIO_MEM) ? "" : |
98 | (port->iotype == UPIO_MEM32) ? "32" : "32be", | ||
96 | (unsigned long long)port->mapbase, | 99 | (unsigned long long)port->mapbase, |
97 | device->options); | 100 | device->options); |
98 | else | 101 | else |
@@ -133,7 +136,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match) | |||
133 | * | 136 | * |
134 | * Registers the earlycon console matching the earlycon specified | 137 | * Registers the earlycon console matching the earlycon specified |
135 | * in the param string @buf. Acceptable param strings are of the form | 138 | * in the param string @buf. Acceptable param strings are of the form |
136 | * <name>,io|mmio|mmio32,<addr>,<options> | 139 | * <name>,io|mmio|mmio32|mmio32be,<addr>,<options> |
137 | * <name>,0x<addr>,<options> | 140 | * <name>,0x<addr>,<options> |
138 | * <name>,<options> | 141 | * <name>,<options> |
139 | * <name> | 142 | * <name> |
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 45fc323b95e6..ffc7cb2585a6 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c | |||
@@ -1504,7 +1504,8 @@ static int icom_probe(struct pci_dev *dev, | |||
1504 | return retval; | 1504 | return retval; |
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | if ( (retval = pci_request_regions(dev, "icom"))) { | 1507 | retval = pci_request_regions(dev, "icom"); |
1508 | if (retval) { | ||
1508 | dev_err(&dev->dev, "pci_request_regions FAILED\n"); | 1509 | dev_err(&dev->dev, "pci_request_regions FAILED\n"); |
1509 | pci_disable_device(dev); | 1510 | pci_disable_device(dev); |
1510 | return retval; | 1511 | return retval; |
@@ -1512,7 +1513,8 @@ static int icom_probe(struct pci_dev *dev, | |||
1512 | 1513 | ||
1513 | pci_set_master(dev); | 1514 | pci_set_master(dev); |
1514 | 1515 | ||
1515 | if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) { | 1516 | retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg); |
1517 | if (retval) { | ||
1516 | dev_err(&dev->dev, "PCI Config read FAILED\n"); | 1518 | dev_err(&dev->dev, "PCI Config read FAILED\n"); |
1517 | return retval; | 1519 | return retval; |
1518 | } | 1520 | } |
@@ -1556,9 +1558,8 @@ static int icom_probe(struct pci_dev *dev, | |||
1556 | } | 1558 | } |
1557 | 1559 | ||
1558 | /* save off irq and request irq line */ | 1560 | /* save off irq and request irq line */ |
1559 | if ( (retval = request_irq(dev->irq, icom_interrupt, | 1561 | retval = request_irq(dev->irq, icom_interrupt, IRQF_SHARED, ICOM_DRIVER_NAME, (void *)icom_adapter); |
1560 | IRQF_SHARED, ICOM_DRIVER_NAME, | 1562 | if (retval) { |
1561 | (void *) icom_adapter))) { | ||
1562 | goto probe_exit2; | 1563 | goto probe_exit2; |
1563 | } | 1564 | } |
1564 | 1565 | ||
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 590390970996..536a33b99be9 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -1175,7 +1175,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi) | |||
1175 | ret = request_irq(gpio_to_irq(ifx_dev->gpio.reset_out), | 1175 | ret = request_irq(gpio_to_irq(ifx_dev->gpio.reset_out), |
1176 | ifx_spi_reset_interrupt, | 1176 | ifx_spi_reset_interrupt, |
1177 | IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, DRVNAME, | 1177 | IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, DRVNAME, |
1178 | (void *)ifx_dev); | 1178 | ifx_dev); |
1179 | if (ret) { | 1179 | if (ret) { |
1180 | dev_err(&spi->dev, "Unable to get irq %x\n", | 1180 | dev_err(&spi->dev, "Unable to get irq %x\n", |
1181 | gpio_to_irq(ifx_dev->gpio.reset_out)); | 1181 | gpio_to_irq(ifx_dev->gpio.reset_out)); |
@@ -1185,9 +1185,8 @@ static int ifx_spi_spi_probe(struct spi_device *spi) | |||
1185 | ret = ifx_spi_reset(ifx_dev); | 1185 | ret = ifx_spi_reset(ifx_dev); |
1186 | 1186 | ||
1187 | ret = request_irq(gpio_to_irq(ifx_dev->gpio.srdy), | 1187 | ret = request_irq(gpio_to_irq(ifx_dev->gpio.srdy), |
1188 | ifx_spi_srdy_interrupt, | 1188 | ifx_spi_srdy_interrupt, IRQF_TRIGGER_RISING, DRVNAME, |
1189 | IRQF_TRIGGER_RISING, DRVNAME, | 1189 | ifx_dev); |
1190 | (void *)ifx_dev); | ||
1191 | if (ret) { | 1190 | if (ret) { |
1192 | dev_err(&spi->dev, "Unable to get irq %x", | 1191 | dev_err(&spi->dev, "Unable to get irq %x", |
1193 | gpio_to_irq(ifx_dev->gpio.srdy)); | 1192 | gpio_to_irq(ifx_dev->gpio.srdy)); |
@@ -1212,7 +1211,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi) | |||
1212 | return 0; | 1211 | return 0; |
1213 | 1212 | ||
1214 | error_ret7: | 1213 | error_ret7: |
1215 | free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), (void *)ifx_dev); | 1214 | free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), ifx_dev); |
1216 | error_ret6: | 1215 | error_ret6: |
1217 | gpio_free(ifx_dev->gpio.srdy); | 1216 | gpio_free(ifx_dev->gpio.srdy); |
1218 | error_ret5: | 1217 | error_ret5: |
@@ -1243,8 +1242,8 @@ static int ifx_spi_spi_remove(struct spi_device *spi) | |||
1243 | /* stop activity */ | 1242 | /* stop activity */ |
1244 | tasklet_kill(&ifx_dev->io_work_tasklet); | 1243 | tasklet_kill(&ifx_dev->io_work_tasklet); |
1245 | /* free irq */ | 1244 | /* free irq */ |
1246 | free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), (void *)ifx_dev); | 1245 | free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), ifx_dev); |
1247 | free_irq(gpio_to_irq(ifx_dev->gpio.srdy), (void *)ifx_dev); | 1246 | free_irq(gpio_to_irq(ifx_dev->gpio.srdy), ifx_dev); |
1248 | 1247 | ||
1249 | gpio_free(ifx_dev->gpio.srdy); | 1248 | gpio_free(ifx_dev->gpio.srdy); |
1250 | gpio_free(ifx_dev->gpio.mrdy); | 1249 | gpio_free(ifx_dev->gpio.mrdy); |
@@ -1381,7 +1380,7 @@ static void __exit ifx_spi_exit(void) | |||
1381 | /* unregister */ | 1380 | /* unregister */ |
1382 | tty_unregister_driver(tty_drv); | 1381 | tty_unregister_driver(tty_drv); |
1383 | put_tty_driver(tty_drv); | 1382 | put_tty_driver(tty_drv); |
1384 | spi_unregister_driver((void *)&ifx_spi_driver); | 1383 | spi_unregister_driver(&ifx_spi_driver); |
1385 | unregister_reboot_notifier(&ifx_modem_reboot_notifier_block); | 1384 | unregister_reboot_notifier(&ifx_modem_reboot_notifier_block); |
1386 | } | 1385 | } |
1387 | 1386 | ||
@@ -1420,7 +1419,7 @@ static int __init ifx_spi_init(void) | |||
1420 | goto err_free_tty; | 1419 | goto err_free_tty; |
1421 | } | 1420 | } |
1422 | 1421 | ||
1423 | result = spi_register_driver((void *)&ifx_spi_driver); | 1422 | result = spi_register_driver(&ifx_spi_driver); |
1424 | if (result) { | 1423 | if (result) { |
1425 | pr_err("%s: spi_register_driver failed(%d)", | 1424 | pr_err("%s: spi_register_driver failed(%d)", |
1426 | DRVNAME, result); | 1425 | DRVNAME, result); |
@@ -1436,7 +1435,7 @@ static int __init ifx_spi_init(void) | |||
1436 | 1435 | ||
1437 | return 0; | 1436 | return 0; |
1438 | err_unreg_spi: | 1437 | err_unreg_spi: |
1439 | spi_unregister_driver((void *)&ifx_spi_driver); | 1438 | spi_unregister_driver(&ifx_spi_driver); |
1440 | err_unreg_tty: | 1439 | err_unreg_tty: |
1441 | tty_unregister_driver(tty_drv); | 1440 | tty_unregister_driver(tty_drv); |
1442 | err_free_tty: | 1441 | err_free_tty: |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 88250395b0ce..2c90dc31bfaa 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -239,7 +239,7 @@ static struct imx_uart_data imx_uart_devdata[] = { | |||
239 | }, | 239 | }, |
240 | }; | 240 | }; |
241 | 241 | ||
242 | static struct platform_device_id imx_uart_devtype[] = { | 242 | static const struct platform_device_id imx_uart_devtype[] = { |
243 | { | 243 | { |
244 | .name = "imx1-uart", | 244 | .name = "imx1-uart", |
245 | .driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX1_UART], | 245 | .driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX1_UART], |
@@ -853,7 +853,7 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
853 | #define TXTL 2 /* reset default */ | 853 | #define TXTL 2 /* reset default */ |
854 | #define RXTL 1 /* reset default */ | 854 | #define RXTL 1 /* reset default */ |
855 | 855 | ||
856 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | 856 | static void imx_setup_ufcr(struct imx_port *sport, unsigned int mode) |
857 | { | 857 | { |
858 | unsigned int val; | 858 | unsigned int val; |
859 | 859 | ||
@@ -861,7 +861,6 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | |||
861 | val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE); | 861 | val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE); |
862 | val |= TXTL << UFCR_TXTL_SHF | RXTL; | 862 | val |= TXTL << UFCR_TXTL_SHF | RXTL; |
863 | writel(val, sport->port.membase + UFCR); | 863 | writel(val, sport->port.membase + UFCR); |
864 | return 0; | ||
865 | } | 864 | } |
866 | 865 | ||
867 | #define RX_BUF_SIZE (PAGE_SIZE) | 866 | #define RX_BUF_SIZE (PAGE_SIZE) |
@@ -1122,6 +1121,12 @@ static int imx_startup(struct uart_port *port) | |||
1122 | 1121 | ||
1123 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); | 1122 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); |
1124 | 1123 | ||
1124 | /* Can we enable the DMA support? */ | ||
1125 | if (is_imx6q_uart(sport) && !uart_console(port) && | ||
1126 | !sport->dma_is_inited) | ||
1127 | imx_uart_dma_init(sport); | ||
1128 | |||
1129 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1125 | /* Reset fifo's and state machines */ | 1130 | /* Reset fifo's and state machines */ |
1126 | i = 100; | 1131 | i = 100; |
1127 | 1132 | ||
@@ -1132,13 +1137,6 @@ static int imx_startup(struct uart_port *port) | |||
1132 | while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0)) | 1137 | while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0)) |
1133 | udelay(1); | 1138 | udelay(1); |
1134 | 1139 | ||
1135 | /* Can we enable the DMA support? */ | ||
1136 | if (is_imx6q_uart(sport) && !uart_console(port) && | ||
1137 | !sport->dma_is_inited) | ||
1138 | imx_uart_dma_init(sport); | ||
1139 | |||
1140 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1141 | |||
1142 | /* | 1140 | /* |
1143 | * Finally, clear and enable interrupts | 1141 | * Finally, clear and enable interrupts |
1144 | */ | 1142 | */ |
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index abd7ea26ed9a..27b5fefac171 100644 --- a/drivers/tty/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c | |||
@@ -2137,7 +2137,8 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd) | |||
2137 | 2137 | ||
2138 | /* register port with the serial core */ | 2138 | /* register port with the serial core */ |
2139 | 2139 | ||
2140 | if ((ret = ioc3_serial_core_attach(is, idd))) | 2140 | ret = ioc3_serial_core_attach(is, idd); |
2141 | if (ret) | ||
2141 | goto out4; | 2142 | goto out4; |
2142 | 2143 | ||
2143 | Num_of_ioc3_cards++; | 2144 | Num_of_ioc3_cards++; |
diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index aa28209f44c1..e5c42fef69d2 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c | |||
@@ -1011,7 +1011,8 @@ static irqreturn_t ioc4_intr(int irq, void *arg) | |||
1011 | */ | 1011 | */ |
1012 | for (xx = 0; xx < num_intrs; xx++) { | 1012 | for (xx = 0; xx < num_intrs; xx++) { |
1013 | intr_info = &soft->is_intr_type[intr_type].is_intr_info[xx]; | 1013 | intr_info = &soft->is_intr_type[intr_type].is_intr_info[xx]; |
1014 | if ((this_mir = this_ir & intr_info->sd_bits)) { | 1014 | this_mir = this_ir & intr_info->sd_bits; |
1015 | if (this_mir) { | ||
1015 | /* Disable owned interrupts, call handler */ | 1016 | /* Disable owned interrupts, call handler */ |
1016 | handled++; | 1017 | handled++; |
1017 | write_ireg(soft, intr_info->sd_bits, IOC4_W_IEC, | 1018 | write_ireg(soft, intr_info->sd_bits, IOC4_W_IEC, |
@@ -2865,10 +2866,12 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) | |||
2865 | 2866 | ||
2866 | /* register port with the serial core - 1 rs232, 1 rs422 */ | 2867 | /* register port with the serial core - 1 rs232, 1 rs422 */ |
2867 | 2868 | ||
2868 | if ((ret = ioc4_serial_core_attach(idd->idd_pdev, PROTO_RS232))) | 2869 | ret = ioc4_serial_core_attach(idd->idd_pdev, PROTO_RS232); |
2870 | if (ret) | ||
2869 | goto out4; | 2871 | goto out4; |
2870 | 2872 | ||
2871 | if ((ret = ioc4_serial_core_attach(idd->idd_pdev, PROTO_RS422))) | 2873 | ret = ioc4_serial_core_attach(idd->idd_pdev, PROTO_RS422); |
2874 | if (ret) | ||
2872 | goto out5; | 2875 | goto out5; |
2873 | 2876 | ||
2874 | Num_of_ioc4_cards++; | 2877 | Num_of_ioc4_cards++; |
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 129dc5be6028..117df151627d 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c | |||
@@ -173,18 +173,18 @@ static int kgdb_nmi_poll_one_knock(void) | |||
173 | bool kgdb_nmi_poll_knock(void) | 173 | bool kgdb_nmi_poll_knock(void) |
174 | { | 174 | { |
175 | if (kgdb_nmi_knock < 0) | 175 | if (kgdb_nmi_knock < 0) |
176 | return 1; | 176 | return true; |
177 | 177 | ||
178 | while (1) { | 178 | while (1) { |
179 | int ret; | 179 | int ret; |
180 | 180 | ||
181 | ret = kgdb_nmi_poll_one_knock(); | 181 | ret = kgdb_nmi_poll_one_knock(); |
182 | if (ret == NO_POLL_CHAR) | 182 | if (ret == NO_POLL_CHAR) |
183 | return 0; | 183 | return false; |
184 | else if (ret == 1) | 184 | else if (ret == 1) |
185 | break; | 185 | break; |
186 | } | 186 | } |
187 | return 1; | 187 | return true; |
188 | } | 188 | } |
189 | 189 | ||
190 | /* | 190 | /* |
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index a9b0ab38a68c..02eb32217685 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c | |||
@@ -597,7 +597,7 @@ console_initcall(mcf_console_init); | |||
597 | #define MCF_CONSOLE NULL | 597 | #define MCF_CONSOLE NULL |
598 | 598 | ||
599 | /****************************************************************************/ | 599 | /****************************************************************************/ |
600 | #endif /* CONFIG_MCF_CONSOLE */ | 600 | #endif /* CONFIG_SERIAL_MCF_CONSOLE */ |
601 | /****************************************************************************/ | 601 | /****************************************************************************/ |
602 | 602 | ||
603 | /* | 603 | /* |
diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 67c036702629..0fc83c962d10 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c | |||
@@ -370,7 +370,7 @@ static int meson_uart_verify_port(struct uart_port *port, | |||
370 | static void meson_uart_release_port(struct uart_port *port) | 370 | static void meson_uart_release_port(struct uart_port *port) |
371 | { | 371 | { |
372 | if (port->flags & UPF_IOREMAP) { | 372 | if (port->flags & UPF_IOREMAP) { |
373 | iounmap(port->membase); | 373 | devm_iounmap(port->dev, port->membase); |
374 | port->membase = NULL; | 374 | port->membase = NULL; |
375 | } | 375 | } |
376 | } | 376 | } |
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 1589f17c1fca..6fc07eb9d74e 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -405,7 +405,7 @@ static struct psc_ops mpc5200b_psc_ops = { | |||
405 | .get_mr1 = mpc52xx_psc_get_mr1, | 405 | .get_mr1 = mpc52xx_psc_get_mr1, |
406 | }; | 406 | }; |
407 | 407 | ||
408 | #endif /* CONFIG_MPC52xx */ | 408 | #endif /* CONFIG_PPC_MPC52xx */ |
409 | 409 | ||
410 | #ifdef CONFIG_PPC_MPC512x | 410 | #ifdef CONFIG_PPC_MPC512x |
411 | #define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1)) | 411 | #define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1)) |
diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index 856fd5a5fa3c..82bb6d1fe23b 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c | |||
@@ -913,7 +913,8 @@ static int mpsc_make_ready(struct mpsc_port_info *pi) | |||
913 | 913 | ||
914 | if (!pi->ready) { | 914 | if (!pi->ready) { |
915 | mpsc_init_hw(pi); | 915 | mpsc_init_hw(pi); |
916 | if ((rc = mpsc_alloc_ring_mem(pi))) | 916 | rc = mpsc_alloc_ring_mem(pi); |
917 | if (rc) | ||
917 | return rc; | 918 | return rc; |
918 | mpsc_init_rings(pi); | 919 | mpsc_init_rings(pi); |
919 | pi->ready = 1; | 920 | pi->ready = 1; |
@@ -1895,7 +1896,8 @@ static int mpsc_shared_drv_probe(struct platform_device *dev) | |||
1895 | int rc = -ENODEV; | 1896 | int rc = -ENODEV; |
1896 | 1897 | ||
1897 | if (dev->id == 0) { | 1898 | if (dev->id == 0) { |
1898 | if (!(rc = mpsc_shared_map_regs(dev))) { | 1899 | rc = mpsc_shared_map_regs(dev); |
1900 | if (!rc) { | ||
1899 | pdata = (struct mpsc_shared_pdata *) | 1901 | pdata = (struct mpsc_shared_pdata *) |
1900 | dev_get_platdata(&dev->dev); | 1902 | dev_get_platdata(&dev->dev); |
1901 | 1903 | ||
@@ -2081,14 +2083,16 @@ static int mpsc_drv_probe(struct platform_device *dev) | |||
2081 | if (dev->id < MPSC_NUM_CTLRS) { | 2083 | if (dev->id < MPSC_NUM_CTLRS) { |
2082 | pi = &mpsc_ports[dev->id]; | 2084 | pi = &mpsc_ports[dev->id]; |
2083 | 2085 | ||
2084 | if (!(rc = mpsc_drv_map_regs(pi, dev))) { | 2086 | rc = mpsc_drv_map_regs(pi, dev); |
2087 | if (!rc) { | ||
2085 | mpsc_drv_get_platform_data(pi, dev, dev->id); | 2088 | mpsc_drv_get_platform_data(pi, dev, dev->id); |
2086 | pi->port.dev = &dev->dev; | 2089 | pi->port.dev = &dev->dev; |
2087 | 2090 | ||
2088 | if (!(rc = mpsc_make_ready(pi))) { | 2091 | rc = mpsc_make_ready(pi); |
2092 | if (!rc) { | ||
2089 | spin_lock_init(&pi->tx_lock); | 2093 | spin_lock_init(&pi->tx_lock); |
2090 | if (!(rc = uart_add_one_port(&mpsc_reg, | 2094 | rc = uart_add_one_port(&mpsc_reg, &pi->port); |
2091 | &pi->port))) { | 2095 | if (!rc) { |
2092 | rc = 0; | 2096 | rc = 0; |
2093 | } else { | 2097 | } else { |
2094 | mpsc_release_port((struct uart_port *) | 2098 | mpsc_release_port((struct uart_port *) |
@@ -2136,9 +2140,12 @@ static int __init mpsc_drv_init(void) | |||
2136 | memset(mpsc_ports, 0, sizeof(mpsc_ports)); | 2140 | memset(mpsc_ports, 0, sizeof(mpsc_ports)); |
2137 | memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs)); | 2141 | memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs)); |
2138 | 2142 | ||
2139 | if (!(rc = uart_register_driver(&mpsc_reg))) { | 2143 | rc = uart_register_driver(&mpsc_reg); |
2140 | if (!(rc = platform_driver_register(&mpsc_shared_driver))) { | 2144 | if (!rc) { |
2141 | if ((rc = platform_driver_register(&mpsc_driver))) { | 2145 | rc = platform_driver_register(&mpsc_shared_driver); |
2146 | if (!rc) { | ||
2147 | rc = platform_driver_register(&mpsc_driver); | ||
2148 | if (rc) { | ||
2142 | platform_driver_unregister(&mpsc_shared_driver); | 2149 | platform_driver_unregister(&mpsc_shared_driver); |
2143 | uart_unregister_driver(&mpsc_reg); | 2150 | uart_unregister_driver(&mpsc_reg); |
2144 | } | 2151 | } |
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c deleted file mode 100644 index 1238ac370bff..000000000000 --- a/drivers/tty/serial/msm_smd_tty.c +++ /dev/null | |||
@@ -1,232 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Google, Inc. | ||
3 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | ||
4 | * Author: Brian Swetland <swetland@google.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/fs.h> | ||
19 | #include <linux/cdev.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/wait.h> | ||
22 | |||
23 | #include <linux/tty.h> | ||
24 | #include <linux/tty_driver.h> | ||
25 | #include <linux/tty_flip.h> | ||
26 | |||
27 | #include <mach/msm_smd.h> | ||
28 | |||
29 | #define MAX_SMD_TTYS 32 | ||
30 | |||
31 | struct smd_tty_info { | ||
32 | struct tty_port port; | ||
33 | smd_channel_t *ch; | ||
34 | }; | ||
35 | |||
36 | struct smd_tty_channel_desc { | ||
37 | int id; | ||
38 | const char *name; | ||
39 | }; | ||
40 | |||
41 | static struct smd_tty_info smd_tty[MAX_SMD_TTYS]; | ||
42 | |||
43 | static const struct smd_tty_channel_desc smd_default_tty_channels[] = { | ||
44 | { .id = 0, .name = "SMD_DS" }, | ||
45 | { .id = 27, .name = "SMD_GPSNMEA" }, | ||
46 | }; | ||
47 | |||
48 | static const struct smd_tty_channel_desc *smd_tty_channels = | ||
49 | smd_default_tty_channels; | ||
50 | static int smd_tty_channels_len = ARRAY_SIZE(smd_default_tty_channels); | ||
51 | |||
52 | static void smd_tty_notify(void *priv, unsigned event) | ||
53 | { | ||
54 | unsigned char *ptr; | ||
55 | int avail; | ||
56 | struct smd_tty_info *info = priv; | ||
57 | struct tty_struct *tty; | ||
58 | |||
59 | if (event != SMD_EVENT_DATA) | ||
60 | return; | ||
61 | |||
62 | tty = tty_port_tty_get(&info->port); | ||
63 | if (!tty) | ||
64 | return; | ||
65 | |||
66 | for (;;) { | ||
67 | if (test_bit(TTY_THROTTLED, &tty->flags)) | ||
68 | break; | ||
69 | avail = smd_read_avail(info->ch); | ||
70 | if (avail == 0) | ||
71 | break; | ||
72 | |||
73 | avail = tty_prepare_flip_string(&info->port, &ptr, avail); | ||
74 | |||
75 | if (smd_read(info->ch, ptr, avail) != avail) { | ||
76 | /* shouldn't be possible since we're in interrupt | ||
77 | ** context here and nobody else could 'steal' our | ||
78 | ** characters. | ||
79 | */ | ||
80 | pr_err("OOPS - smd_tty_buffer mismatch?!"); | ||
81 | } | ||
82 | |||
83 | tty_flip_buffer_push(&info->port); | ||
84 | } | ||
85 | |||
86 | /* XXX only when writable and necessary */ | ||
87 | tty_wakeup(tty); | ||
88 | tty_kref_put(tty); | ||
89 | } | ||
90 | |||
91 | static int smd_tty_port_activate(struct tty_port *tport, struct tty_struct *tty) | ||
92 | { | ||
93 | struct smd_tty_info *info = container_of(tport, struct smd_tty_info, | ||
94 | port); | ||
95 | int i, res = 0; | ||
96 | const char *name = NULL; | ||
97 | |||
98 | for (i = 0; i < smd_tty_channels_len; i++) { | ||
99 | if (smd_tty_channels[i].id == tty->index) { | ||
100 | name = smd_tty_channels[i].name; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | if (!name) | ||
105 | return -ENODEV; | ||
106 | |||
107 | if (info->ch) | ||
108 | smd_kick(info->ch); | ||
109 | else | ||
110 | res = smd_open(name, &info->ch, info, smd_tty_notify); | ||
111 | |||
112 | if (!res) | ||
113 | tty->driver_data = info; | ||
114 | |||
115 | return res; | ||
116 | } | ||
117 | |||
118 | static void smd_tty_port_shutdown(struct tty_port *tport) | ||
119 | { | ||
120 | struct smd_tty_info *info = container_of(tport, struct smd_tty_info, | ||
121 | port); | ||
122 | |||
123 | if (info->ch) { | ||
124 | smd_close(info->ch); | ||
125 | info->ch = 0; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | static int smd_tty_open(struct tty_struct *tty, struct file *f) | ||
130 | { | ||
131 | struct smd_tty_info *info = smd_tty + tty->index; | ||
132 | |||
133 | return tty_port_open(&info->port, tty, f); | ||
134 | } | ||
135 | |||
136 | static void smd_tty_close(struct tty_struct *tty, struct file *f) | ||
137 | { | ||
138 | struct smd_tty_info *info = tty->driver_data; | ||
139 | |||
140 | tty_port_close(&info->port, tty, f); | ||
141 | } | ||
142 | |||
143 | static int smd_tty_write(struct tty_struct *tty, | ||
144 | const unsigned char *buf, int len) | ||
145 | { | ||
146 | struct smd_tty_info *info = tty->driver_data; | ||
147 | int avail; | ||
148 | |||
149 | /* if we're writing to a packet channel we will | ||
150 | ** never be able to write more data than there | ||
151 | ** is currently space for | ||
152 | */ | ||
153 | avail = smd_write_avail(info->ch); | ||
154 | if (len > avail) | ||
155 | len = avail; | ||
156 | |||
157 | return smd_write(info->ch, buf, len); | ||
158 | } | ||
159 | |||
160 | static int smd_tty_write_room(struct tty_struct *tty) | ||
161 | { | ||
162 | struct smd_tty_info *info = tty->driver_data; | ||
163 | return smd_write_avail(info->ch); | ||
164 | } | ||
165 | |||
166 | static int smd_tty_chars_in_buffer(struct tty_struct *tty) | ||
167 | { | ||
168 | struct smd_tty_info *info = tty->driver_data; | ||
169 | return smd_read_avail(info->ch); | ||
170 | } | ||
171 | |||
172 | static void smd_tty_unthrottle(struct tty_struct *tty) | ||
173 | { | ||
174 | struct smd_tty_info *info = tty->driver_data; | ||
175 | smd_kick(info->ch); | ||
176 | } | ||
177 | |||
178 | static const struct tty_port_operations smd_tty_port_ops = { | ||
179 | .shutdown = smd_tty_port_shutdown, | ||
180 | .activate = smd_tty_port_activate, | ||
181 | }; | ||
182 | |||
183 | static const struct tty_operations smd_tty_ops = { | ||
184 | .open = smd_tty_open, | ||
185 | .close = smd_tty_close, | ||
186 | .write = smd_tty_write, | ||
187 | .write_room = smd_tty_write_room, | ||
188 | .chars_in_buffer = smd_tty_chars_in_buffer, | ||
189 | .unthrottle = smd_tty_unthrottle, | ||
190 | }; | ||
191 | |||
192 | static struct tty_driver *smd_tty_driver; | ||
193 | |||
194 | static int __init smd_tty_init(void) | ||
195 | { | ||
196 | int ret, i; | ||
197 | |||
198 | smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS); | ||
199 | if (smd_tty_driver == 0) | ||
200 | return -ENOMEM; | ||
201 | |||
202 | smd_tty_driver->driver_name = "smd_tty_driver"; | ||
203 | smd_tty_driver->name = "smd"; | ||
204 | smd_tty_driver->major = 0; | ||
205 | smd_tty_driver->minor_start = 0; | ||
206 | smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
207 | smd_tty_driver->subtype = SERIAL_TYPE_NORMAL; | ||
208 | smd_tty_driver->init_termios = tty_std_termios; | ||
209 | smd_tty_driver->init_termios.c_iflag = 0; | ||
210 | smd_tty_driver->init_termios.c_oflag = 0; | ||
211 | smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | ||
212 | smd_tty_driver->init_termios.c_lflag = 0; | ||
213 | smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | | ||
214 | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
215 | tty_set_operations(smd_tty_driver, &smd_tty_ops); | ||
216 | |||
217 | ret = tty_register_driver(smd_tty_driver); | ||
218 | if (ret) | ||
219 | return ret; | ||
220 | |||
221 | for (i = 0; i < smd_tty_channels_len; i++) { | ||
222 | struct tty_port *port = &smd_tty[smd_tty_channels[i].id].port; | ||
223 | tty_port_init(port); | ||
224 | port->ops = &smd_tty_port_ops; | ||
225 | tty_port_register_device(port, smd_tty_driver, | ||
226 | smd_tty_channels[i].id, NULL); | ||
227 | } | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | module_init(smd_tty_init); | ||
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index f7e5825b55ab..13cf7738fbdc 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -169,7 +169,7 @@ struct mxs_auart_port { | |||
169 | bool ms_irq_enabled; | 169 | bool ms_irq_enabled; |
170 | }; | 170 | }; |
171 | 171 | ||
172 | static struct platform_device_id mxs_auart_devtype[] = { | 172 | static const struct platform_device_id mxs_auart_devtype[] = { |
173 | { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART }, | 173 | { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART }, |
174 | { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART }, | 174 | { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART }, |
175 | { /* sentinel */ } | 175 | { /* sentinel */ } |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 137381e649e5..6823df99bd76 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -67,14 +67,17 @@ static int of_platform_serial_setup(struct platform_device *ofdev, | |||
67 | if (of_property_read_u32(np, "clock-frequency", &clk)) { | 67 | if (of_property_read_u32(np, "clock-frequency", &clk)) { |
68 | 68 | ||
69 | /* Get clk rate through clk driver if present */ | 69 | /* Get clk rate through clk driver if present */ |
70 | info->clk = clk_get(&ofdev->dev, NULL); | 70 | info->clk = devm_clk_get(&ofdev->dev, NULL); |
71 | if (IS_ERR(info->clk)) { | 71 | if (IS_ERR(info->clk)) { |
72 | dev_warn(&ofdev->dev, | 72 | dev_warn(&ofdev->dev, |
73 | "clk or clock-frequency not defined\n"); | 73 | "clk or clock-frequency not defined\n"); |
74 | return PTR_ERR(info->clk); | 74 | return PTR_ERR(info->clk); |
75 | } | 75 | } |
76 | 76 | ||
77 | clk_prepare_enable(info->clk); | 77 | ret = clk_prepare_enable(info->clk); |
78 | if (ret < 0) | ||
79 | return ret; | ||
80 | |||
78 | clk = clk_get_rate(info->clk); | 81 | clk = clk_get_rate(info->clk); |
79 | } | 82 | } |
80 | /* If current-speed was set, then try not to change it. */ | 83 | /* If current-speed was set, then try not to change it. */ |
@@ -188,7 +191,6 @@ static int of_platform_serial_probe(struct platform_device *ofdev) | |||
188 | { | 191 | { |
189 | struct uart_8250_port port8250; | 192 | struct uart_8250_port port8250; |
190 | memset(&port8250, 0, sizeof(port8250)); | 193 | memset(&port8250, 0, sizeof(port8250)); |
191 | port.type = port_type; | ||
192 | port8250.port = port; | 194 | port8250.port = port; |
193 | 195 | ||
194 | if (port.fifosize) | 196 | if (port.fifosize) |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index a0ae942d9562..67d0c213b1c7 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -348,7 +348,7 @@ static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport) | |||
348 | s3c24xx_serial_start_tx_dma(ourport, count); | 348 | s3c24xx_serial_start_tx_dma(ourport, count); |
349 | } | 349 | } |
350 | 350 | ||
351 | void s3c24xx_serial_start_tx(struct uart_port *port) | 351 | static void s3c24xx_serial_start_tx(struct uart_port *port) |
352 | { | 352 | { |
353 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 353 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
354 | struct circ_buf *xmit = &port->state->xmit; | 354 | struct circ_buf *xmit = &port->state->xmit; |
@@ -2337,7 +2337,7 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { | |||
2337 | #define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL | 2337 | #define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL |
2338 | #endif | 2338 | #endif |
2339 | 2339 | ||
2340 | static struct platform_device_id s3c24xx_serial_driver_ids[] = { | 2340 | static const struct platform_device_id s3c24xx_serial_driver_ids[] = { |
2341 | { | 2341 | { |
2342 | .name = "s3c2410-uart", | 2342 | .name = "s3c2410-uart", |
2343 | .driver_data = S3C2410_SERIAL_DRV_DATA, | 2343 | .driver_data = S3C2410_SERIAL_DRV_DATA, |
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 468354ef7baa..9e6576004a42 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/serial.h> | 25 | #include <linux/serial.h> |
26 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
27 | #include <linux/tty_flip.h> | 27 | #include <linux/tty_flip.h> |
28 | #include <linux/spi/spi.h> | ||
28 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
29 | 30 | ||
30 | #define SC16IS7XX_NAME "sc16is7xx" | 31 | #define SC16IS7XX_NAME "sc16is7xx" |
@@ -300,25 +301,38 @@ struct sc16is7xx_devtype { | |||
300 | int nr_uart; | 301 | int nr_uart; |
301 | }; | 302 | }; |
302 | 303 | ||
304 | #define SC16IS7XX_RECONF_MD (1 << 0) | ||
305 | #define SC16IS7XX_RECONF_IER (1 << 1) | ||
306 | #define SC16IS7XX_RECONF_RS485 (1 << 2) | ||
307 | |||
308 | struct sc16is7xx_one_config { | ||
309 | unsigned int flags; | ||
310 | u8 ier_clear; | ||
311 | }; | ||
312 | |||
303 | struct sc16is7xx_one { | 313 | struct sc16is7xx_one { |
304 | struct uart_port port; | 314 | struct uart_port port; |
305 | struct work_struct tx_work; | 315 | struct kthread_work tx_work; |
306 | struct work_struct md_work; | 316 | struct kthread_work reg_work; |
317 | struct sc16is7xx_one_config config; | ||
307 | }; | 318 | }; |
308 | 319 | ||
309 | struct sc16is7xx_port { | 320 | struct sc16is7xx_port { |
310 | struct uart_driver uart; | 321 | struct uart_driver uart; |
311 | struct sc16is7xx_devtype *devtype; | 322 | struct sc16is7xx_devtype *devtype; |
312 | struct regmap *regmap; | 323 | struct regmap *regmap; |
313 | struct mutex mutex; | ||
314 | struct clk *clk; | 324 | struct clk *clk; |
315 | #ifdef CONFIG_GPIOLIB | 325 | #ifdef CONFIG_GPIOLIB |
316 | struct gpio_chip gpio; | 326 | struct gpio_chip gpio; |
317 | #endif | 327 | #endif |
318 | unsigned char buf[SC16IS7XX_FIFO_SIZE]; | 328 | unsigned char buf[SC16IS7XX_FIFO_SIZE]; |
329 | struct kthread_worker kworker; | ||
330 | struct task_struct *kworker_task; | ||
331 | struct kthread_work irq_work; | ||
319 | struct sc16is7xx_one p[0]; | 332 | struct sc16is7xx_one p[0]; |
320 | }; | 333 | }; |
321 | 334 | ||
335 | #define to_sc16is7xx_port(p,e) ((container_of((p), struct sc16is7xx_port, e))) | ||
322 | #define to_sc16is7xx_one(p,e) ((container_of((p), struct sc16is7xx_one, e))) | 336 | #define to_sc16is7xx_one(p,e) ((container_of((p), struct sc16is7xx_one, e))) |
323 | 337 | ||
324 | static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg) | 338 | static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg) |
@@ -615,9 +629,7 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) | |||
615 | !!(msr & SC16IS7XX_MSR_CTS_BIT)); | 629 | !!(msr & SC16IS7XX_MSR_CTS_BIT)); |
616 | break; | 630 | break; |
617 | case SC16IS7XX_IIR_THRI_SRC: | 631 | case SC16IS7XX_IIR_THRI_SRC: |
618 | mutex_lock(&s->mutex); | ||
619 | sc16is7xx_handle_tx(port); | 632 | sc16is7xx_handle_tx(port); |
620 | mutex_unlock(&s->mutex); | ||
621 | break; | 633 | break; |
622 | default: | 634 | default: |
623 | dev_err_ratelimited(port->dev, | 635 | dev_err_ratelimited(port->dev, |
@@ -628,81 +640,115 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) | |||
628 | } while (1); | 640 | } while (1); |
629 | } | 641 | } |
630 | 642 | ||
631 | static irqreturn_t sc16is7xx_ist(int irq, void *dev_id) | 643 | static void sc16is7xx_ist(struct kthread_work *ws) |
632 | { | 644 | { |
633 | struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; | 645 | struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work); |
634 | int i; | 646 | int i; |
635 | 647 | ||
636 | for (i = 0; i < s->uart.nr; ++i) | 648 | for (i = 0; i < s->uart.nr; ++i) |
637 | sc16is7xx_port_irq(s, i); | 649 | sc16is7xx_port_irq(s, i); |
650 | } | ||
651 | |||
652 | static irqreturn_t sc16is7xx_irq(int irq, void *dev_id) | ||
653 | { | ||
654 | struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; | ||
655 | |||
656 | queue_kthread_work(&s->kworker, &s->irq_work); | ||
638 | 657 | ||
639 | return IRQ_HANDLED; | 658 | return IRQ_HANDLED; |
640 | } | 659 | } |
641 | 660 | ||
642 | static void sc16is7xx_wq_proc(struct work_struct *ws) | 661 | static void sc16is7xx_tx_proc(struct kthread_work *ws) |
643 | { | 662 | { |
644 | struct sc16is7xx_one *one = to_sc16is7xx_one(ws, tx_work); | 663 | struct uart_port *port = &(to_sc16is7xx_one(ws, tx_work)->port); |
645 | struct sc16is7xx_port *s = dev_get_drvdata(one->port.dev); | 664 | |
665 | if ((port->rs485.flags & SER_RS485_ENABLED) && | ||
666 | (port->rs485.delay_rts_before_send > 0)) | ||
667 | msleep(port->rs485.delay_rts_before_send); | ||
646 | 668 | ||
647 | mutex_lock(&s->mutex); | 669 | sc16is7xx_handle_tx(port); |
648 | sc16is7xx_handle_tx(&one->port); | ||
649 | mutex_unlock(&s->mutex); | ||
650 | } | 670 | } |
651 | 671 | ||
652 | static void sc16is7xx_stop_tx(struct uart_port* port) | 672 | static void sc16is7xx_reconf_rs485(struct uart_port *port) |
653 | { | 673 | { |
654 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); | 674 | const u32 mask = SC16IS7XX_EFCR_AUTO_RS485_BIT | |
655 | struct circ_buf *xmit = &one->port.state->xmit; | 675 | SC16IS7XX_EFCR_RTS_INVERT_BIT; |
656 | 676 | u32 efcr = 0; | |
657 | /* handle rs485 */ | 677 | struct serial_rs485 *rs485 = &port->rs485; |
658 | if (port->rs485.flags & SER_RS485_ENABLED) { | 678 | unsigned long irqflags; |
659 | /* do nothing if current tx not yet completed */ | 679 | |
660 | int lsr = sc16is7xx_port_read(port, SC16IS7XX_LSR_REG); | 680 | spin_lock_irqsave(&port->lock, irqflags); |
661 | if (!(lsr & SC16IS7XX_LSR_TEMT_BIT)) | 681 | if (rs485->flags & SER_RS485_ENABLED) { |
662 | return; | 682 | efcr |= SC16IS7XX_EFCR_AUTO_RS485_BIT; |
663 | 683 | ||
664 | if (uart_circ_empty(xmit) && | 684 | if (rs485->flags & SER_RS485_RTS_AFTER_SEND) |
665 | (port->rs485.delay_rts_after_send > 0)) | 685 | efcr |= SC16IS7XX_EFCR_RTS_INVERT_BIT; |
666 | mdelay(port->rs485.delay_rts_after_send); | ||
667 | } | 686 | } |
687 | spin_unlock_irqrestore(&port->lock, irqflags); | ||
668 | 688 | ||
669 | sc16is7xx_port_update(port, SC16IS7XX_IER_REG, | 689 | sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, mask, efcr); |
670 | SC16IS7XX_IER_THRI_BIT, | ||
671 | 0); | ||
672 | } | 690 | } |
673 | 691 | ||
674 | static void sc16is7xx_stop_rx(struct uart_port* port) | 692 | static void sc16is7xx_reg_proc(struct kthread_work *ws) |
675 | { | 693 | { |
694 | struct sc16is7xx_one *one = to_sc16is7xx_one(ws, reg_work); | ||
695 | struct sc16is7xx_one_config config; | ||
696 | unsigned long irqflags; | ||
697 | |||
698 | spin_lock_irqsave(&one->port.lock, irqflags); | ||
699 | config = one->config; | ||
700 | memset(&one->config, 0, sizeof(one->config)); | ||
701 | spin_unlock_irqrestore(&one->port.lock, irqflags); | ||
702 | |||
703 | if (config.flags & SC16IS7XX_RECONF_MD) | ||
704 | sc16is7xx_port_update(&one->port, SC16IS7XX_MCR_REG, | ||
705 | SC16IS7XX_MCR_LOOP_BIT, | ||
706 | (one->port.mctrl & TIOCM_LOOP) ? | ||
707 | SC16IS7XX_MCR_LOOP_BIT : 0); | ||
708 | |||
709 | if (config.flags & SC16IS7XX_RECONF_IER) | ||
710 | sc16is7xx_port_update(&one->port, SC16IS7XX_IER_REG, | ||
711 | config.ier_clear, 0); | ||
712 | |||
713 | if (config.flags & SC16IS7XX_RECONF_RS485) | ||
714 | sc16is7xx_reconf_rs485(&one->port); | ||
715 | } | ||
716 | |||
717 | static void sc16is7xx_ier_clear(struct uart_port *port, u8 bit) | ||
718 | { | ||
719 | struct sc16is7xx_port *s = dev_get_drvdata(port->dev); | ||
676 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); | 720 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); |
677 | 721 | ||
678 | one->port.read_status_mask &= ~SC16IS7XX_LSR_DR_BIT; | 722 | one->config.flags |= SC16IS7XX_RECONF_IER; |
679 | sc16is7xx_port_update(port, SC16IS7XX_IER_REG, | 723 | one->config.ier_clear |= bit; |
680 | SC16IS7XX_LSR_DR_BIT, | 724 | queue_kthread_work(&s->kworker, &one->reg_work); |
681 | 0); | 725 | } |
726 | |||
727 | static void sc16is7xx_stop_tx(struct uart_port *port) | ||
728 | { | ||
729 | sc16is7xx_ier_clear(port, SC16IS7XX_IER_THRI_BIT); | ||
730 | } | ||
731 | |||
732 | static void sc16is7xx_stop_rx(struct uart_port *port) | ||
733 | { | ||
734 | sc16is7xx_ier_clear(port, SC16IS7XX_IER_RDI_BIT); | ||
682 | } | 735 | } |
683 | 736 | ||
684 | static void sc16is7xx_start_tx(struct uart_port *port) | 737 | static void sc16is7xx_start_tx(struct uart_port *port) |
685 | { | 738 | { |
739 | struct sc16is7xx_port *s = dev_get_drvdata(port->dev); | ||
686 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); | 740 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); |
687 | 741 | ||
688 | /* handle rs485 */ | 742 | queue_kthread_work(&s->kworker, &one->tx_work); |
689 | if ((port->rs485.flags & SER_RS485_ENABLED) && | ||
690 | (port->rs485.delay_rts_before_send > 0)) { | ||
691 | mdelay(port->rs485.delay_rts_before_send); | ||
692 | } | ||
693 | |||
694 | if (!work_pending(&one->tx_work)) | ||
695 | schedule_work(&one->tx_work); | ||
696 | } | 743 | } |
697 | 744 | ||
698 | static unsigned int sc16is7xx_tx_empty(struct uart_port *port) | 745 | static unsigned int sc16is7xx_tx_empty(struct uart_port *port) |
699 | { | 746 | { |
700 | unsigned int lvl, lsr; | 747 | unsigned int lsr; |
701 | 748 | ||
702 | lvl = sc16is7xx_port_read(port, SC16IS7XX_TXLVL_REG); | ||
703 | lsr = sc16is7xx_port_read(port, SC16IS7XX_LSR_REG); | 749 | lsr = sc16is7xx_port_read(port, SC16IS7XX_LSR_REG); |
704 | 750 | ||
705 | return ((lsr & SC16IS7XX_LSR_THRE_BIT) && !lvl) ? TIOCSER_TEMT : 0; | 751 | return (lsr & SC16IS7XX_LSR_TEMT_BIT) ? TIOCSER_TEMT : 0; |
706 | } | 752 | } |
707 | 753 | ||
708 | static unsigned int sc16is7xx_get_mctrl(struct uart_port *port) | 754 | static unsigned int sc16is7xx_get_mctrl(struct uart_port *port) |
@@ -713,21 +759,13 @@ static unsigned int sc16is7xx_get_mctrl(struct uart_port *port) | |||
713 | return TIOCM_DSR | TIOCM_CAR; | 759 | return TIOCM_DSR | TIOCM_CAR; |
714 | } | 760 | } |
715 | 761 | ||
716 | static void sc16is7xx_md_proc(struct work_struct *ws) | ||
717 | { | ||
718 | struct sc16is7xx_one *one = to_sc16is7xx_one(ws, md_work); | ||
719 | |||
720 | sc16is7xx_port_update(&one->port, SC16IS7XX_MCR_REG, | ||
721 | SC16IS7XX_MCR_LOOP_BIT, | ||
722 | (one->port.mctrl & TIOCM_LOOP) ? | ||
723 | SC16IS7XX_MCR_LOOP_BIT : 0); | ||
724 | } | ||
725 | |||
726 | static void sc16is7xx_set_mctrl(struct uart_port *port, unsigned int mctrl) | 762 | static void sc16is7xx_set_mctrl(struct uart_port *port, unsigned int mctrl) |
727 | { | 763 | { |
764 | struct sc16is7xx_port *s = dev_get_drvdata(port->dev); | ||
728 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); | 765 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); |
729 | 766 | ||
730 | schedule_work(&one->md_work); | 767 | one->config.flags |= SC16IS7XX_RECONF_MD; |
768 | queue_kthread_work(&s->kworker, &one->reg_work); | ||
731 | } | 769 | } |
732 | 770 | ||
733 | static void sc16is7xx_break_ctl(struct uart_port *port, int break_state) | 771 | static void sc16is7xx_break_ctl(struct uart_port *port, int break_state) |
@@ -831,9 +869,8 @@ static void sc16is7xx_set_termios(struct uart_port *port, | |||
831 | static int sc16is7xx_config_rs485(struct uart_port *port, | 869 | static int sc16is7xx_config_rs485(struct uart_port *port, |
832 | struct serial_rs485 *rs485) | 870 | struct serial_rs485 *rs485) |
833 | { | 871 | { |
834 | const u32 mask = SC16IS7XX_EFCR_AUTO_RS485_BIT | | 872 | struct sc16is7xx_port *s = dev_get_drvdata(port->dev); |
835 | SC16IS7XX_EFCR_RTS_INVERT_BIT; | 873 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); |
836 | u32 efcr = 0; | ||
837 | 874 | ||
838 | if (rs485->flags & SER_RS485_ENABLED) { | 875 | if (rs485->flags & SER_RS485_ENABLED) { |
839 | bool rts_during_rx, rts_during_tx; | 876 | bool rts_during_rx, rts_during_tx; |
@@ -841,21 +878,23 @@ static int sc16is7xx_config_rs485(struct uart_port *port, | |||
841 | rts_during_rx = rs485->flags & SER_RS485_RTS_AFTER_SEND; | 878 | rts_during_rx = rs485->flags & SER_RS485_RTS_AFTER_SEND; |
842 | rts_during_tx = rs485->flags & SER_RS485_RTS_ON_SEND; | 879 | rts_during_tx = rs485->flags & SER_RS485_RTS_ON_SEND; |
843 | 880 | ||
844 | efcr |= SC16IS7XX_EFCR_AUTO_RS485_BIT; | 881 | if (rts_during_rx == rts_during_tx) |
845 | |||
846 | if (!rts_during_rx && rts_during_tx) | ||
847 | /* default */; | ||
848 | else if (rts_during_rx && !rts_during_tx) | ||
849 | efcr |= SC16IS7XX_EFCR_RTS_INVERT_BIT; | ||
850 | else | ||
851 | dev_err(port->dev, | 882 | dev_err(port->dev, |
852 | "unsupported RTS signalling on_send:%d after_send:%d - exactly one of RS485 RTS flags should be set\n", | 883 | "unsupported RTS signalling on_send:%d after_send:%d - exactly one of RS485 RTS flags should be set\n", |
853 | rts_during_tx, rts_during_rx); | 884 | rts_during_tx, rts_during_rx); |
854 | } | ||
855 | 885 | ||
856 | sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, mask, efcr); | 886 | /* |
887 | * RTS signal is handled by HW, it's timing can't be influenced. | ||
888 | * However, it's sometimes useful to delay TX even without RTS | ||
889 | * control therefore we try to handle .delay_rts_before_send. | ||
890 | */ | ||
891 | if (rs485->delay_rts_after_send) | ||
892 | return -EINVAL; | ||
893 | } | ||
857 | 894 | ||
858 | port->rs485 = *rs485; | 895 | port->rs485 = *rs485; |
896 | one->config.flags |= SC16IS7XX_RECONF_RS485; | ||
897 | queue_kthread_work(&s->kworker, &one->reg_work); | ||
859 | 898 | ||
860 | return 0; | 899 | return 0; |
861 | } | 900 | } |
@@ -916,6 +955,8 @@ static int sc16is7xx_startup(struct uart_port *port) | |||
916 | 955 | ||
917 | static void sc16is7xx_shutdown(struct uart_port *port) | 956 | static void sc16is7xx_shutdown(struct uart_port *port) |
918 | { | 957 | { |
958 | struct sc16is7xx_port *s = dev_get_drvdata(port->dev); | ||
959 | |||
919 | /* Disable all interrupts */ | 960 | /* Disable all interrupts */ |
920 | sc16is7xx_port_write(port, SC16IS7XX_IER_REG, 0); | 961 | sc16is7xx_port_write(port, SC16IS7XX_IER_REG, 0); |
921 | /* Disable TX/RX */ | 962 | /* Disable TX/RX */ |
@@ -926,6 +967,8 @@ static void sc16is7xx_shutdown(struct uart_port *port) | |||
926 | SC16IS7XX_EFCR_TXDISABLE_BIT); | 967 | SC16IS7XX_EFCR_TXDISABLE_BIT); |
927 | 968 | ||
928 | sc16is7xx_power(port, 0); | 969 | sc16is7xx_power(port, 0); |
970 | |||
971 | flush_kthread_worker(&s->kworker); | ||
929 | } | 972 | } |
930 | 973 | ||
931 | static const char *sc16is7xx_type(struct uart_port *port) | 974 | static const char *sc16is7xx_type(struct uart_port *port) |
@@ -1043,6 +1086,7 @@ static int sc16is7xx_probe(struct device *dev, | |||
1043 | struct sc16is7xx_devtype *devtype, | 1086 | struct sc16is7xx_devtype *devtype, |
1044 | struct regmap *regmap, int irq, unsigned long flags) | 1087 | struct regmap *regmap, int irq, unsigned long flags) |
1045 | { | 1088 | { |
1089 | struct sched_param sched_param = { .sched_priority = MAX_RT_PRIO / 2 }; | ||
1046 | unsigned long freq, *pfreq = dev_get_platdata(dev); | 1090 | unsigned long freq, *pfreq = dev_get_platdata(dev); |
1047 | int i, ret; | 1091 | int i, ret; |
1048 | struct sc16is7xx_port *s; | 1092 | struct sc16is7xx_port *s; |
@@ -1084,6 +1128,16 @@ static int sc16is7xx_probe(struct device *dev, | |||
1084 | goto out_clk; | 1128 | goto out_clk; |
1085 | } | 1129 | } |
1086 | 1130 | ||
1131 | init_kthread_worker(&s->kworker); | ||
1132 | init_kthread_work(&s->irq_work, sc16is7xx_ist); | ||
1133 | s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker, | ||
1134 | "sc16is7xx"); | ||
1135 | if (IS_ERR(s->kworker_task)) { | ||
1136 | ret = PTR_ERR(s->kworker_task); | ||
1137 | goto out_uart; | ||
1138 | } | ||
1139 | sched_setscheduler(s->kworker_task, SCHED_FIFO, &sched_param); | ||
1140 | |||
1087 | #ifdef CONFIG_GPIOLIB | 1141 | #ifdef CONFIG_GPIOLIB |
1088 | if (devtype->nr_gpio) { | 1142 | if (devtype->nr_gpio) { |
1089 | /* Setup GPIO cotroller */ | 1143 | /* Setup GPIO cotroller */ |
@@ -1099,12 +1153,10 @@ static int sc16is7xx_probe(struct device *dev, | |||
1099 | s->gpio.can_sleep = 1; | 1153 | s->gpio.can_sleep = 1; |
1100 | ret = gpiochip_add(&s->gpio); | 1154 | ret = gpiochip_add(&s->gpio); |
1101 | if (ret) | 1155 | if (ret) |
1102 | goto out_uart; | 1156 | goto out_thread; |
1103 | } | 1157 | } |
1104 | #endif | 1158 | #endif |
1105 | 1159 | ||
1106 | mutex_init(&s->mutex); | ||
1107 | |||
1108 | for (i = 0; i < devtype->nr_uart; ++i) { | 1160 | for (i = 0; i < devtype->nr_uart; ++i) { |
1109 | /* Initialize port data */ | 1161 | /* Initialize port data */ |
1110 | s->p[i].port.line = i; | 1162 | s->p[i].port.line = i; |
@@ -1123,10 +1175,9 @@ static int sc16is7xx_probe(struct device *dev, | |||
1123 | sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_EFCR_REG, | 1175 | sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_EFCR_REG, |
1124 | SC16IS7XX_EFCR_RXDISABLE_BIT | | 1176 | SC16IS7XX_EFCR_RXDISABLE_BIT | |
1125 | SC16IS7XX_EFCR_TXDISABLE_BIT); | 1177 | SC16IS7XX_EFCR_TXDISABLE_BIT); |
1126 | /* Initialize queue for start TX */ | 1178 | /* Initialize kthread work structs */ |
1127 | INIT_WORK(&s->p[i].tx_work, sc16is7xx_wq_proc); | 1179 | init_kthread_work(&s->p[i].tx_work, sc16is7xx_tx_proc); |
1128 | /* Initialize queue for changing mode */ | 1180 | init_kthread_work(&s->p[i].reg_work, sc16is7xx_reg_proc); |
1129 | INIT_WORK(&s->p[i].md_work, sc16is7xx_md_proc); | ||
1130 | /* Register port */ | 1181 | /* Register port */ |
1131 | uart_add_one_port(&s->uart, &s->p[i].port); | 1182 | uart_add_one_port(&s->uart, &s->p[i].port); |
1132 | /* Go to suspend mode */ | 1183 | /* Go to suspend mode */ |
@@ -1134,22 +1185,23 @@ static int sc16is7xx_probe(struct device *dev, | |||
1134 | } | 1185 | } |
1135 | 1186 | ||
1136 | /* Setup interrupt */ | 1187 | /* Setup interrupt */ |
1137 | ret = devm_request_threaded_irq(dev, irq, NULL, sc16is7xx_ist, | 1188 | ret = devm_request_irq(dev, irq, sc16is7xx_irq, |
1138 | IRQF_ONESHOT | flags, dev_name(dev), s); | 1189 | IRQF_ONESHOT | flags, dev_name(dev), s); |
1139 | if (!ret) | 1190 | if (!ret) |
1140 | return 0; | 1191 | return 0; |
1141 | 1192 | ||
1142 | for (i = 0; i < s->uart.nr; i++) | 1193 | for (i = 0; i < s->uart.nr; i++) |
1143 | uart_remove_one_port(&s->uart, &s->p[i].port); | 1194 | uart_remove_one_port(&s->uart, &s->p[i].port); |
1144 | 1195 | ||
1145 | mutex_destroy(&s->mutex); | ||
1146 | |||
1147 | #ifdef CONFIG_GPIOLIB | 1196 | #ifdef CONFIG_GPIOLIB |
1148 | if (devtype->nr_gpio) | 1197 | if (devtype->nr_gpio) |
1149 | gpiochip_remove(&s->gpio); | 1198 | gpiochip_remove(&s->gpio); |
1150 | 1199 | ||
1151 | out_uart: | 1200 | out_thread: |
1152 | #endif | 1201 | #endif |
1202 | kthread_stop(s->kworker_task); | ||
1203 | |||
1204 | out_uart: | ||
1153 | uart_unregister_driver(&s->uart); | 1205 | uart_unregister_driver(&s->uart); |
1154 | 1206 | ||
1155 | out_clk: | 1207 | out_clk: |
@@ -1170,13 +1222,13 @@ static int sc16is7xx_remove(struct device *dev) | |||
1170 | #endif | 1222 | #endif |
1171 | 1223 | ||
1172 | for (i = 0; i < s->uart.nr; i++) { | 1224 | for (i = 0; i < s->uart.nr; i++) { |
1173 | cancel_work_sync(&s->p[i].tx_work); | ||
1174 | cancel_work_sync(&s->p[i].md_work); | ||
1175 | uart_remove_one_port(&s->uart, &s->p[i].port); | 1225 | uart_remove_one_port(&s->uart, &s->p[i].port); |
1176 | sc16is7xx_power(&s->p[i].port, 0); | 1226 | sc16is7xx_power(&s->p[i].port, 0); |
1177 | } | 1227 | } |
1178 | 1228 | ||
1179 | mutex_destroy(&s->mutex); | 1229 | flush_kthread_worker(&s->kworker); |
1230 | kthread_stop(s->kworker_task); | ||
1231 | |||
1180 | uart_unregister_driver(&s->uart); | 1232 | uart_unregister_driver(&s->uart); |
1181 | if (!IS_ERR(s->clk)) | 1233 | if (!IS_ERR(s->clk)) |
1182 | clk_disable_unprepare(s->clk); | 1234 | clk_disable_unprepare(s->clk); |
@@ -1204,6 +1256,75 @@ static struct regmap_config regcfg = { | |||
1204 | .precious_reg = sc16is7xx_regmap_precious, | 1256 | .precious_reg = sc16is7xx_regmap_precious, |
1205 | }; | 1257 | }; |
1206 | 1258 | ||
1259 | #ifdef CONFIG_SERIAL_SC16IS7XX_SPI | ||
1260 | static int sc16is7xx_spi_probe(struct spi_device *spi) | ||
1261 | { | ||
1262 | struct sc16is7xx_devtype *devtype; | ||
1263 | unsigned long flags = 0; | ||
1264 | struct regmap *regmap; | ||
1265 | int ret; | ||
1266 | |||
1267 | /* Setup SPI bus */ | ||
1268 | spi->bits_per_word = 8; | ||
1269 | /* only supports mode 0 on SC16IS762 */ | ||
1270 | spi->mode = spi->mode ? : SPI_MODE_0; | ||
1271 | spi->max_speed_hz = spi->max_speed_hz ? : 15000000; | ||
1272 | ret = spi_setup(spi); | ||
1273 | if (ret) | ||
1274 | return ret; | ||
1275 | |||
1276 | if (spi->dev.of_node) { | ||
1277 | const struct of_device_id *of_id = | ||
1278 | of_match_device(sc16is7xx_dt_ids, &spi->dev); | ||
1279 | |||
1280 | devtype = (struct sc16is7xx_devtype *)of_id->data; | ||
1281 | } else { | ||
1282 | const struct spi_device_id *id_entry = spi_get_device_id(spi); | ||
1283 | |||
1284 | devtype = (struct sc16is7xx_devtype *)id_entry->driver_data; | ||
1285 | flags = IRQF_TRIGGER_FALLING; | ||
1286 | } | ||
1287 | |||
1288 | regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) | | ||
1289 | (devtype->nr_uart - 1); | ||
1290 | regmap = devm_regmap_init_spi(spi, ®cfg); | ||
1291 | |||
1292 | return sc16is7xx_probe(&spi->dev, devtype, regmap, spi->irq, flags); | ||
1293 | } | ||
1294 | |||
1295 | static int sc16is7xx_spi_remove(struct spi_device *spi) | ||
1296 | { | ||
1297 | return sc16is7xx_remove(&spi->dev); | ||
1298 | } | ||
1299 | |||
1300 | static const struct spi_device_id sc16is7xx_spi_id_table[] = { | ||
1301 | { "sc16is74x", (kernel_ulong_t)&sc16is74x_devtype, }, | ||
1302 | { "sc16is740", (kernel_ulong_t)&sc16is74x_devtype, }, | ||
1303 | { "sc16is741", (kernel_ulong_t)&sc16is74x_devtype, }, | ||
1304 | { "sc16is750", (kernel_ulong_t)&sc16is750_devtype, }, | ||
1305 | { "sc16is752", (kernel_ulong_t)&sc16is752_devtype, }, | ||
1306 | { "sc16is760", (kernel_ulong_t)&sc16is760_devtype, }, | ||
1307 | { "sc16is762", (kernel_ulong_t)&sc16is762_devtype, }, | ||
1308 | { } | ||
1309 | }; | ||
1310 | |||
1311 | MODULE_DEVICE_TABLE(spi, sc16is7xx_spi_id_table); | ||
1312 | |||
1313 | static struct spi_driver sc16is7xx_spi_uart_driver = { | ||
1314 | .driver = { | ||
1315 | .name = SC16IS7XX_NAME, | ||
1316 | .owner = THIS_MODULE, | ||
1317 | .of_match_table = of_match_ptr(sc16is7xx_dt_ids), | ||
1318 | }, | ||
1319 | .probe = sc16is7xx_spi_probe, | ||
1320 | .remove = sc16is7xx_spi_remove, | ||
1321 | .id_table = sc16is7xx_spi_id_table, | ||
1322 | }; | ||
1323 | |||
1324 | MODULE_ALIAS("spi:sc16is7xx"); | ||
1325 | #endif | ||
1326 | |||
1327 | #ifdef CONFIG_SERIAL_SC16IS7XX_I2C | ||
1207 | static int sc16is7xx_i2c_probe(struct i2c_client *i2c, | 1328 | static int sc16is7xx_i2c_probe(struct i2c_client *i2c, |
1208 | const struct i2c_device_id *id) | 1329 | const struct i2c_device_id *id) |
1209 | { | 1330 | { |
@@ -1235,6 +1356,8 @@ static int sc16is7xx_i2c_remove(struct i2c_client *client) | |||
1235 | 1356 | ||
1236 | static const struct i2c_device_id sc16is7xx_i2c_id_table[] = { | 1357 | static const struct i2c_device_id sc16is7xx_i2c_id_table[] = { |
1237 | { "sc16is74x", (kernel_ulong_t)&sc16is74x_devtype, }, | 1358 | { "sc16is74x", (kernel_ulong_t)&sc16is74x_devtype, }, |
1359 | { "sc16is740", (kernel_ulong_t)&sc16is74x_devtype, }, | ||
1360 | { "sc16is741", (kernel_ulong_t)&sc16is74x_devtype, }, | ||
1238 | { "sc16is750", (kernel_ulong_t)&sc16is750_devtype, }, | 1361 | { "sc16is750", (kernel_ulong_t)&sc16is750_devtype, }, |
1239 | { "sc16is752", (kernel_ulong_t)&sc16is752_devtype, }, | 1362 | { "sc16is752", (kernel_ulong_t)&sc16is752_devtype, }, |
1240 | { "sc16is760", (kernel_ulong_t)&sc16is760_devtype, }, | 1363 | { "sc16is760", (kernel_ulong_t)&sc16is760_devtype, }, |
@@ -1253,8 +1376,43 @@ static struct i2c_driver sc16is7xx_i2c_uart_driver = { | |||
1253 | .remove = sc16is7xx_i2c_remove, | 1376 | .remove = sc16is7xx_i2c_remove, |
1254 | .id_table = sc16is7xx_i2c_id_table, | 1377 | .id_table = sc16is7xx_i2c_id_table, |
1255 | }; | 1378 | }; |
1256 | module_i2c_driver(sc16is7xx_i2c_uart_driver); | 1379 | |
1257 | MODULE_ALIAS("i2c:sc16is7xx"); | 1380 | MODULE_ALIAS("i2c:sc16is7xx"); |
1381 | #endif | ||
1382 | |||
1383 | static int __init sc16is7xx_init(void) | ||
1384 | { | ||
1385 | int ret = 0; | ||
1386 | #ifdef CONFIG_SERIAL_SC16IS7XX_I2C | ||
1387 | ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver); | ||
1388 | if (ret < 0) { | ||
1389 | pr_err("failed to init sc16is7xx i2c --> %d\n", ret); | ||
1390 | return ret; | ||
1391 | } | ||
1392 | #endif | ||
1393 | |||
1394 | #ifdef CONFIG_SERIAL_SC16IS7XX_SPI | ||
1395 | ret = spi_register_driver(&sc16is7xx_spi_uart_driver); | ||
1396 | if (ret < 0) { | ||
1397 | pr_err("failed to init sc16is7xx spi --> %d\n", ret); | ||
1398 | return ret; | ||
1399 | } | ||
1400 | #endif | ||
1401 | return ret; | ||
1402 | } | ||
1403 | module_init(sc16is7xx_init); | ||
1404 | |||
1405 | static void __exit sc16is7xx_exit(void) | ||
1406 | { | ||
1407 | #ifdef CONFIG_SERIAL_SC16IS7XX_I2C | ||
1408 | i2c_del_driver(&sc16is7xx_i2c_uart_driver); | ||
1409 | #endif | ||
1410 | |||
1411 | #ifdef CONFIG_SERIAL_SC16IS7XX_SPI | ||
1412 | spi_unregister_driver(&sc16is7xx_spi_uart_driver); | ||
1413 | #endif | ||
1414 | } | ||
1415 | module_exit(sc16is7xx_exit); | ||
1258 | 1416 | ||
1259 | MODULE_LICENSE("GPL"); | 1417 | MODULE_LICENSE("GPL"); |
1260 | MODULE_AUTHOR("Jon Ringle <jringle@gridpoint.com>"); | 1418 | MODULE_AUTHOR("Jon Ringle <jringle@gridpoint.com>"); |
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 1d5ea3964ee5..cf0133ae762d 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c | |||
@@ -131,8 +131,8 @@ struct tegra_uart_port { | |||
131 | struct dma_async_tx_descriptor *rx_dma_desc; | 131 | struct dma_async_tx_descriptor *rx_dma_desc; |
132 | dma_cookie_t tx_cookie; | 132 | dma_cookie_t tx_cookie; |
133 | dma_cookie_t rx_cookie; | 133 | dma_cookie_t rx_cookie; |
134 | int tx_bytes_requested; | 134 | unsigned int tx_bytes_requested; |
135 | int rx_bytes_requested; | 135 | unsigned int rx_bytes_requested; |
136 | }; | 136 | }; |
137 | 137 | ||
138 | static void tegra_uart_start_next_tx(struct tegra_uart_port *tup); | 138 | static void tegra_uart_start_next_tx(struct tegra_uart_port *tup); |
@@ -234,6 +234,22 @@ static void tegra_uart_break_ctl(struct uart_port *u, int break_ctl) | |||
234 | tup->lcr_shadow = lcr; | 234 | tup->lcr_shadow = lcr; |
235 | } | 235 | } |
236 | 236 | ||
237 | /** | ||
238 | * tegra_uart_wait_cycle_time: Wait for N UART clock periods | ||
239 | * | ||
240 | * @tup: Tegra serial port data structure. | ||
241 | * @cycles: Number of clock periods to wait. | ||
242 | * | ||
243 | * Tegra UARTs are clocked at 16X the baud/bit rate and hence the UART | ||
244 | * clock speed is 16X the current baud rate. | ||
245 | */ | ||
246 | static void tegra_uart_wait_cycle_time(struct tegra_uart_port *tup, | ||
247 | unsigned int cycles) | ||
248 | { | ||
249 | if (tup->current_baud) | ||
250 | udelay(DIV_ROUND_UP(cycles * 1000000, tup->current_baud * 16)); | ||
251 | } | ||
252 | |||
237 | /* Wait for a symbol-time. */ | 253 | /* Wait for a symbol-time. */ |
238 | static void tegra_uart_wait_sym_time(struct tegra_uart_port *tup, | 254 | static void tegra_uart_wait_sym_time(struct tegra_uart_port *tup, |
239 | unsigned int syms) | 255 | unsigned int syms) |
@@ -263,8 +279,12 @@ static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits) | |||
263 | /* Dummy read to ensure the write is posted */ | 279 | /* Dummy read to ensure the write is posted */ |
264 | tegra_uart_read(tup, UART_SCR); | 280 | tegra_uart_read(tup, UART_SCR); |
265 | 281 | ||
266 | /* Wait for the flush to propagate. */ | 282 | /* |
267 | tegra_uart_wait_sym_time(tup, 1); | 283 | * For all tegra devices (up to t210), there is a hardware issue that |
284 | * requires software to wait for 32 UART clock periods for the flush | ||
285 | * to propagate, otherwise data could be lost. | ||
286 | */ | ||
287 | tegra_uart_wait_cycle_time(tup, 32); | ||
268 | } | 288 | } |
269 | 289 | ||
270 | static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) | 290 | static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) |
@@ -388,9 +408,9 @@ static void tegra_uart_tx_dma_complete(void *args) | |||
388 | struct circ_buf *xmit = &tup->uport.state->xmit; | 408 | struct circ_buf *xmit = &tup->uport.state->xmit; |
389 | struct dma_tx_state state; | 409 | struct dma_tx_state state; |
390 | unsigned long flags; | 410 | unsigned long flags; |
391 | int count; | 411 | unsigned int count; |
392 | 412 | ||
393 | dmaengine_tx_status(tup->tx_dma_chan, tup->rx_cookie, &state); | 413 | dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); |
394 | count = tup->tx_bytes_requested - state.residue; | 414 | count = tup->tx_bytes_requested - state.residue; |
395 | async_tx_ack(tup->tx_dma_desc); | 415 | async_tx_ack(tup->tx_dma_desc); |
396 | spin_lock_irqsave(&tup->uport.lock, flags); | 416 | spin_lock_irqsave(&tup->uport.lock, flags); |
@@ -480,7 +500,7 @@ static void tegra_uart_stop_tx(struct uart_port *u) | |||
480 | struct tegra_uart_port *tup = to_tegra_uport(u); | 500 | struct tegra_uart_port *tup = to_tegra_uport(u); |
481 | struct circ_buf *xmit = &tup->uport.state->xmit; | 501 | struct circ_buf *xmit = &tup->uport.state->xmit; |
482 | struct dma_tx_state state; | 502 | struct dma_tx_state state; |
483 | int count; | 503 | unsigned int count; |
484 | 504 | ||
485 | if (tup->tx_in_progress != TEGRA_UART_TX_DMA) | 505 | if (tup->tx_in_progress != TEGRA_UART_TX_DMA) |
486 | return; | 506 | return; |
@@ -530,10 +550,15 @@ static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, | |||
530 | } | 550 | } |
531 | 551 | ||
532 | static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, | 552 | static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, |
533 | struct tty_port *tty, int count) | 553 | struct tty_port *tty, |
554 | unsigned int count) | ||
534 | { | 555 | { |
535 | int copied; | 556 | int copied; |
536 | 557 | ||
558 | /* If count is zero, then there is no data to be copied */ | ||
559 | if (!count) | ||
560 | return; | ||
561 | |||
537 | tup->uport.icount.rx += count; | 562 | tup->uport.icount.rx += count; |
538 | if (!tty) { | 563 | if (!tty) { |
539 | dev_err(tup->uport.dev, "No tty port\n"); | 564 | dev_err(tup->uport.dev, "No tty port\n"); |
@@ -555,21 +580,30 @@ static void tegra_uart_rx_dma_complete(void *args) | |||
555 | { | 580 | { |
556 | struct tegra_uart_port *tup = args; | 581 | struct tegra_uart_port *tup = args; |
557 | struct uart_port *u = &tup->uport; | 582 | struct uart_port *u = &tup->uport; |
558 | int count = tup->rx_bytes_requested; | 583 | unsigned int count = tup->rx_bytes_requested; |
559 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | 584 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); |
560 | struct tty_port *port = &u->state->port; | 585 | struct tty_port *port = &u->state->port; |
561 | unsigned long flags; | 586 | unsigned long flags; |
587 | struct dma_tx_state state; | ||
588 | enum dma_status status; | ||
562 | 589 | ||
563 | async_tx_ack(tup->rx_dma_desc); | ||
564 | spin_lock_irqsave(&u->lock, flags); | 590 | spin_lock_irqsave(&u->lock, flags); |
565 | 591 | ||
592 | status = dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); | ||
593 | |||
594 | if (status == DMA_IN_PROGRESS) { | ||
595 | dev_dbg(tup->uport.dev, "RX DMA is in progress\n"); | ||
596 | goto done; | ||
597 | } | ||
598 | |||
599 | async_tx_ack(tup->rx_dma_desc); | ||
600 | |||
566 | /* Deactivate flow control to stop sender */ | 601 | /* Deactivate flow control to stop sender */ |
567 | if (tup->rts_active) | 602 | if (tup->rts_active) |
568 | set_rts(tup, false); | 603 | set_rts(tup, false); |
569 | 604 | ||
570 | /* If we are here, DMA is stopped */ | 605 | /* If we are here, DMA is stopped */ |
571 | if (count) | 606 | tegra_uart_copy_rx_to_tty(tup, port, count); |
572 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
573 | 607 | ||
574 | tegra_uart_handle_rx_pio(tup, port); | 608 | tegra_uart_handle_rx_pio(tup, port); |
575 | if (tty) { | 609 | if (tty) { |
@@ -584,6 +618,7 @@ static void tegra_uart_rx_dma_complete(void *args) | |||
584 | if (tup->rts_active) | 618 | if (tup->rts_active) |
585 | set_rts(tup, true); | 619 | set_rts(tup, true); |
586 | 620 | ||
621 | done: | ||
587 | spin_unlock_irqrestore(&u->lock, flags); | 622 | spin_unlock_irqrestore(&u->lock, flags); |
588 | } | 623 | } |
589 | 624 | ||
@@ -594,7 +629,7 @@ static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup, | |||
594 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | 629 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); |
595 | struct tty_port *port = &tup->uport.state->port; | 630 | struct tty_port *port = &tup->uport.state->port; |
596 | struct uart_port *u = &tup->uport; | 631 | struct uart_port *u = &tup->uport; |
597 | int count; | 632 | unsigned int count; |
598 | 633 | ||
599 | /* Deactivate flow control to stop sender */ | 634 | /* Deactivate flow control to stop sender */ |
600 | if (tup->rts_active) | 635 | if (tup->rts_active) |
@@ -606,8 +641,7 @@ static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup, | |||
606 | count = tup->rx_bytes_requested - state.residue; | 641 | count = tup->rx_bytes_requested - state.residue; |
607 | 642 | ||
608 | /* If we are here, DMA is stopped */ | 643 | /* If we are here, DMA is stopped */ |
609 | if (count) | 644 | tegra_uart_copy_rx_to_tty(tup, port, count); |
610 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
611 | 645 | ||
612 | tegra_uart_handle_rx_pio(tup, port); | 646 | tegra_uart_handle_rx_pio(tup, port); |
613 | if (tty) { | 647 | if (tty) { |
@@ -865,6 +899,16 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup) | |||
865 | tup->fcr_shadow |= TEGRA_UART_TX_TRIG_16B; | 899 | tup->fcr_shadow |= TEGRA_UART_TX_TRIG_16B; |
866 | tegra_uart_write(tup, tup->fcr_shadow, UART_FCR); | 900 | tegra_uart_write(tup, tup->fcr_shadow, UART_FCR); |
867 | 901 | ||
902 | /* Dummy read to ensure the write is posted */ | ||
903 | tegra_uart_read(tup, UART_SCR); | ||
904 | |||
905 | /* | ||
906 | * For all tegra devices (up to t210), there is a hardware issue that | ||
907 | * requires software to wait for 3 UART clock periods after enabling | ||
908 | * the TX fifo, otherwise data could be lost. | ||
909 | */ | ||
910 | tegra_uart_wait_cycle_time(tup, 3); | ||
911 | |||
868 | /* | 912 | /* |
869 | * Initialize the UART with default configuration | 913 | * Initialize the UART with default configuration |
870 | * (115200, N, 8, 1) so that the receive DMA buffer may be | 914 | * (115200, N, 8, 1) so that the receive DMA buffer may be |
@@ -905,6 +949,28 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup) | |||
905 | return 0; | 949 | return 0; |
906 | } | 950 | } |
907 | 951 | ||
952 | static void tegra_uart_dma_channel_free(struct tegra_uart_port *tup, | ||
953 | bool dma_to_memory) | ||
954 | { | ||
955 | if (dma_to_memory) { | ||
956 | dmaengine_terminate_all(tup->rx_dma_chan); | ||
957 | dma_release_channel(tup->rx_dma_chan); | ||
958 | dma_free_coherent(tup->uport.dev, TEGRA_UART_RX_DMA_BUFFER_SIZE, | ||
959 | tup->rx_dma_buf_virt, tup->rx_dma_buf_phys); | ||
960 | tup->rx_dma_chan = NULL; | ||
961 | tup->rx_dma_buf_phys = 0; | ||
962 | tup->rx_dma_buf_virt = NULL; | ||
963 | } else { | ||
964 | dmaengine_terminate_all(tup->tx_dma_chan); | ||
965 | dma_release_channel(tup->tx_dma_chan); | ||
966 | dma_unmap_single(tup->uport.dev, tup->tx_dma_buf_phys, | ||
967 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
968 | tup->tx_dma_chan = NULL; | ||
969 | tup->tx_dma_buf_phys = 0; | ||
970 | tup->tx_dma_buf_virt = NULL; | ||
971 | } | ||
972 | } | ||
973 | |||
908 | static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, | 974 | static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, |
909 | bool dma_to_memory) | 975 | bool dma_to_memory) |
910 | { | 976 | { |
@@ -933,67 +999,39 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, | |||
933 | dma_release_channel(dma_chan); | 999 | dma_release_channel(dma_chan); |
934 | return -ENOMEM; | 1000 | return -ENOMEM; |
935 | } | 1001 | } |
1002 | dma_sconfig.src_addr = tup->uport.mapbase; | ||
1003 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
1004 | dma_sconfig.src_maxburst = 4; | ||
1005 | tup->rx_dma_chan = dma_chan; | ||
1006 | tup->rx_dma_buf_virt = dma_buf; | ||
1007 | tup->rx_dma_buf_phys = dma_phys; | ||
936 | } else { | 1008 | } else { |
937 | dma_phys = dma_map_single(tup->uport.dev, | 1009 | dma_phys = dma_map_single(tup->uport.dev, |
938 | tup->uport.state->xmit.buf, UART_XMIT_SIZE, | 1010 | tup->uport.state->xmit.buf, UART_XMIT_SIZE, |
939 | DMA_TO_DEVICE); | 1011 | DMA_TO_DEVICE); |
1012 | if (dma_mapping_error(tup->uport.dev, dma_phys)) { | ||
1013 | dev_err(tup->uport.dev, "dma_map_single tx failed\n"); | ||
1014 | dma_release_channel(dma_chan); | ||
1015 | return -ENOMEM; | ||
1016 | } | ||
940 | dma_buf = tup->uport.state->xmit.buf; | 1017 | dma_buf = tup->uport.state->xmit.buf; |
941 | } | ||
942 | |||
943 | if (dma_to_memory) { | ||
944 | dma_sconfig.src_addr = tup->uport.mapbase; | ||
945 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
946 | dma_sconfig.src_maxburst = 4; | ||
947 | } else { | ||
948 | dma_sconfig.dst_addr = tup->uport.mapbase; | 1018 | dma_sconfig.dst_addr = tup->uport.mapbase; |
949 | dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | 1019 | dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
950 | dma_sconfig.dst_maxburst = 16; | 1020 | dma_sconfig.dst_maxburst = 16; |
1021 | tup->tx_dma_chan = dma_chan; | ||
1022 | tup->tx_dma_buf_virt = dma_buf; | ||
1023 | tup->tx_dma_buf_phys = dma_phys; | ||
951 | } | 1024 | } |
952 | 1025 | ||
953 | ret = dmaengine_slave_config(dma_chan, &dma_sconfig); | 1026 | ret = dmaengine_slave_config(dma_chan, &dma_sconfig); |
954 | if (ret < 0) { | 1027 | if (ret < 0) { |
955 | dev_err(tup->uport.dev, | 1028 | dev_err(tup->uport.dev, |
956 | "Dma slave config failed, err = %d\n", ret); | 1029 | "Dma slave config failed, err = %d\n", ret); |
957 | goto scrub; | 1030 | tegra_uart_dma_channel_free(tup, dma_to_memory); |
1031 | return ret; | ||
958 | } | 1032 | } |
959 | 1033 | ||
960 | if (dma_to_memory) { | ||
961 | tup->rx_dma_chan = dma_chan; | ||
962 | tup->rx_dma_buf_virt = dma_buf; | ||
963 | tup->rx_dma_buf_phys = dma_phys; | ||
964 | } else { | ||
965 | tup->tx_dma_chan = dma_chan; | ||
966 | tup->tx_dma_buf_virt = dma_buf; | ||
967 | tup->tx_dma_buf_phys = dma_phys; | ||
968 | } | ||
969 | return 0; | 1034 | return 0; |
970 | |||
971 | scrub: | ||
972 | dma_release_channel(dma_chan); | ||
973 | return ret; | ||
974 | } | ||
975 | |||
976 | static void tegra_uart_dma_channel_free(struct tegra_uart_port *tup, | ||
977 | bool dma_to_memory) | ||
978 | { | ||
979 | struct dma_chan *dma_chan; | ||
980 | |||
981 | if (dma_to_memory) { | ||
982 | dma_free_coherent(tup->uport.dev, TEGRA_UART_RX_DMA_BUFFER_SIZE, | ||
983 | tup->rx_dma_buf_virt, tup->rx_dma_buf_phys); | ||
984 | dma_chan = tup->rx_dma_chan; | ||
985 | tup->rx_dma_chan = NULL; | ||
986 | tup->rx_dma_buf_phys = 0; | ||
987 | tup->rx_dma_buf_virt = NULL; | ||
988 | } else { | ||
989 | dma_unmap_single(tup->uport.dev, tup->tx_dma_buf_phys, | ||
990 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
991 | dma_chan = tup->tx_dma_chan; | ||
992 | tup->tx_dma_chan = NULL; | ||
993 | tup->tx_dma_buf_phys = 0; | ||
994 | tup->tx_dma_buf_virt = NULL; | ||
995 | } | ||
996 | dma_release_channel(dma_chan); | ||
997 | } | 1035 | } |
998 | 1036 | ||
999 | static int tegra_uart_startup(struct uart_port *u) | 1037 | static int tegra_uart_startup(struct uart_port *u) |
@@ -1060,8 +1098,6 @@ static void tegra_uart_shutdown(struct uart_port *u) | |||
1060 | tegra_uart_dma_channel_free(tup, true); | 1098 | tegra_uart_dma_channel_free(tup, true); |
1061 | tegra_uart_dma_channel_free(tup, false); | 1099 | tegra_uart_dma_channel_free(tup, false); |
1062 | free_irq(u->irq, tup); | 1100 | free_irq(u->irq, tup); |
1063 | |||
1064 | tegra_uart_flush_buffer(u); | ||
1065 | } | 1101 | } |
1066 | 1102 | ||
1067 | static void tegra_uart_enable_ms(struct uart_port *u) | 1103 | static void tegra_uart_enable_ms(struct uart_port *u) |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0b7bb12dfc68..7ae1592f7ec9 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -335,18 +335,29 @@ unsigned int | |||
335 | uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, | 335 | uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, |
336 | struct ktermios *old, unsigned int min, unsigned int max) | 336 | struct ktermios *old, unsigned int min, unsigned int max) |
337 | { | 337 | { |
338 | unsigned int try, baud, altbaud = 38400; | 338 | unsigned int try; |
339 | unsigned int baud; | ||
340 | unsigned int altbaud; | ||
339 | int hung_up = 0; | 341 | int hung_up = 0; |
340 | upf_t flags = port->flags & UPF_SPD_MASK; | 342 | upf_t flags = port->flags & UPF_SPD_MASK; |
341 | 343 | ||
342 | if (flags == UPF_SPD_HI) | 344 | switch (flags) { |
345 | case UPF_SPD_HI: | ||
343 | altbaud = 57600; | 346 | altbaud = 57600; |
344 | else if (flags == UPF_SPD_VHI) | 347 | break; |
348 | case UPF_SPD_VHI: | ||
345 | altbaud = 115200; | 349 | altbaud = 115200; |
346 | else if (flags == UPF_SPD_SHI) | 350 | break; |
351 | case UPF_SPD_SHI: | ||
347 | altbaud = 230400; | 352 | altbaud = 230400; |
348 | else if (flags == UPF_SPD_WARP) | 353 | break; |
354 | case UPF_SPD_WARP: | ||
349 | altbaud = 460800; | 355 | altbaud = 460800; |
356 | break; | ||
357 | default: | ||
358 | altbaud = 38400; | ||
359 | break; | ||
360 | } | ||
350 | 361 | ||
351 | for (try = 0; try < 2; try++) { | 362 | for (try = 0; try < 2; try++) { |
352 | baud = tty_termios_baud_rate(termios); | 363 | baud = tty_termios_baud_rate(termios); |
@@ -894,12 +905,10 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
894 | * need to rate-limit; it's CAP_SYS_ADMIN only. | 905 | * need to rate-limit; it's CAP_SYS_ADMIN only. |
895 | */ | 906 | */ |
896 | if (uport->flags & UPF_SPD_MASK) { | 907 | if (uport->flags & UPF_SPD_MASK) { |
897 | char buf[64]; | ||
898 | |||
899 | dev_notice(uport->dev, | 908 | dev_notice(uport->dev, |
900 | "%s sets custom speed on %s. This is deprecated.\n", | 909 | "%s sets custom speed on %s. This is deprecated.\n", |
901 | current->comm, | 910 | current->comm, |
902 | tty_name(port->tty, buf)); | 911 | tty_name(port->tty)); |
903 | } | 912 | } |
904 | uart_change_speed(tty, state, NULL); | 913 | uart_change_speed(tty, state, NULL); |
905 | } | 914 | } |
@@ -1816,8 +1825,8 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co) | |||
1816 | * @options: ptr for <options> field; NULL if not present (out) | 1825 | * @options: ptr for <options> field; NULL if not present (out) |
1817 | * | 1826 | * |
1818 | * Decodes earlycon kernel command line parameters of the form | 1827 | * Decodes earlycon kernel command line parameters of the form |
1819 | * earlycon=<name>,io|mmio|mmio32,<addr>,<options> | 1828 | * earlycon=<name>,io|mmio|mmio32|mmio32be,<addr>,<options> |
1820 | * console=<name>,io|mmio|mmio32,<addr>,<options> | 1829 | * console=<name>,io|mmio|mmio32|mmio32be,<addr>,<options> |
1821 | * | 1830 | * |
1822 | * The optional form | 1831 | * The optional form |
1823 | * earlycon=<name>,0x<addr>,<options> | 1832 | * earlycon=<name>,0x<addr>,<options> |
@@ -1835,6 +1844,9 @@ int uart_parse_earlycon(char *p, unsigned char *iotype, unsigned long *addr, | |||
1835 | } else if (strncmp(p, "mmio32,", 7) == 0) { | 1844 | } else if (strncmp(p, "mmio32,", 7) == 0) { |
1836 | *iotype = UPIO_MEM32; | 1845 | *iotype = UPIO_MEM32; |
1837 | p += 7; | 1846 | p += 7; |
1847 | } else if (strncmp(p, "mmio32be,", 9) == 0) { | ||
1848 | *iotype = UPIO_MEM32BE; | ||
1849 | p += 9; | ||
1838 | } else if (strncmp(p, "io,", 3) == 0) { | 1850 | } else if (strncmp(p, "io,", 3) == 0) { |
1839 | *iotype = UPIO_PORT; | 1851 | *iotype = UPIO_PORT; |
1840 | p += 3; | 1852 | p += 3; |
diff --git a/drivers/tty/serial/serial_ks8695.c b/drivers/tty/serial/serial_ks8695.c index 5c79bdab985d..b4decf8787de 100644 --- a/drivers/tty/serial/serial_ks8695.c +++ b/drivers/tty/serial/serial_ks8695.c | |||
@@ -328,7 +328,7 @@ static int ks8695uart_startup(struct uart_port *port) | |||
328 | { | 328 | { |
329 | int retval; | 329 | int retval; |
330 | 330 | ||
331 | set_irq_flags(KS8695_IRQ_UART_TX, IRQF_VALID | IRQF_NOAUTOEN); | 331 | irq_modify_status(KS8695_IRQ_UART_TX, IRQ_NOREQUEST, IRQ_NOAUTOEN); |
332 | tx_enable(port, 0); | 332 | tx_enable(port, 0); |
333 | rx_enable(port, 1); | 333 | rx_enable(port, 1); |
334 | ms_enable(port, 1); | 334 | ms_enable(port, 1); |
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index d7b846d41630..402f7fb54133 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c | |||
@@ -49,8 +49,7 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl) | |||
49 | unsigned int count = 0; | 49 | unsigned int count = 0; |
50 | 50 | ||
51 | for (i = 0; i < UART_GPIO_MAX; i++) | 51 | for (i = 0; i < UART_GPIO_MAX; i++) |
52 | if (!IS_ERR_OR_NULL(gpios->gpio[i]) && | 52 | if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) { |
53 | mctrl_gpios_desc[i].dir_out) { | ||
54 | desc_array[count] = gpios->gpio[i]; | 53 | desc_array[count] = gpios->gpio[i]; |
55 | value_array[count] = !!(mctrl & mctrl_gpios_desc[i].mctrl); | 54 | value_array[count] = !!(mctrl & mctrl_gpios_desc[i].mctrl); |
56 | count++; | 55 | count++; |
@@ -118,7 +117,7 @@ void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios) | |||
118 | enum mctrl_gpio_idx i; | 117 | enum mctrl_gpio_idx i; |
119 | 118 | ||
120 | for (i = 0; i < UART_GPIO_MAX; i++) | 119 | for (i = 0; i < UART_GPIO_MAX; i++) |
121 | if (!IS_ERR_OR_NULL(gpios->gpio[i])) | 120 | if (gpios->gpio[i]) |
122 | devm_gpiod_put(dev, gpios->gpio[i]); | 121 | devm_gpiod_put(dev, gpios->gpio[i]); |
123 | devm_kfree(dev, gpios); | 122 | devm_kfree(dev, gpios); |
124 | } | 123 | } |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 95772cf4e7b0..1b2f894bdc9e 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -81,7 +81,8 @@ struct sci_port { | |||
81 | 81 | ||
82 | /* Platform configuration */ | 82 | /* Platform configuration */ |
83 | struct plat_sci_port *cfg; | 83 | struct plat_sci_port *cfg; |
84 | int overrun_bit; | 84 | unsigned int overrun_reg; |
85 | unsigned int overrun_mask; | ||
85 | unsigned int error_mask; | 86 | unsigned int error_mask; |
86 | unsigned int sampling_rate; | 87 | unsigned int sampling_rate; |
87 | resource_size_t reg_size; | 88 | resource_size_t reg_size; |
@@ -168,6 +169,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
168 | [SCSPTR] = sci_reg_invalid, | 169 | [SCSPTR] = sci_reg_invalid, |
169 | [SCLSR] = sci_reg_invalid, | 170 | [SCLSR] = sci_reg_invalid, |
170 | [HSSRR] = sci_reg_invalid, | 171 | [HSSRR] = sci_reg_invalid, |
172 | [SCPCR] = sci_reg_invalid, | ||
173 | [SCPDR] = sci_reg_invalid, | ||
171 | }, | 174 | }, |
172 | 175 | ||
173 | /* | 176 | /* |
@@ -188,6 +191,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
188 | [SCSPTR] = sci_reg_invalid, | 191 | [SCSPTR] = sci_reg_invalid, |
189 | [SCLSR] = sci_reg_invalid, | 192 | [SCLSR] = sci_reg_invalid, |
190 | [HSSRR] = sci_reg_invalid, | 193 | [HSSRR] = sci_reg_invalid, |
194 | [SCPCR] = sci_reg_invalid, | ||
195 | [SCPDR] = sci_reg_invalid, | ||
191 | }, | 196 | }, |
192 | 197 | ||
193 | /* | 198 | /* |
@@ -207,6 +212,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
207 | [SCSPTR] = sci_reg_invalid, | 212 | [SCSPTR] = sci_reg_invalid, |
208 | [SCLSR] = sci_reg_invalid, | 213 | [SCLSR] = sci_reg_invalid, |
209 | [HSSRR] = sci_reg_invalid, | 214 | [HSSRR] = sci_reg_invalid, |
215 | [SCPCR] = { 0x30, 16 }, | ||
216 | [SCPDR] = { 0x34, 16 }, | ||
210 | }, | 217 | }, |
211 | 218 | ||
212 | /* | 219 | /* |
@@ -226,6 +233,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
226 | [SCSPTR] = sci_reg_invalid, | 233 | [SCSPTR] = sci_reg_invalid, |
227 | [SCLSR] = sci_reg_invalid, | 234 | [SCLSR] = sci_reg_invalid, |
228 | [HSSRR] = sci_reg_invalid, | 235 | [HSSRR] = sci_reg_invalid, |
236 | [SCPCR] = { 0x30, 16 }, | ||
237 | [SCPDR] = { 0x34, 16 }, | ||
229 | }, | 238 | }, |
230 | 239 | ||
231 | /* | 240 | /* |
@@ -246,6 +255,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
246 | [SCSPTR] = { 0x20, 16 }, | 255 | [SCSPTR] = { 0x20, 16 }, |
247 | [SCLSR] = { 0x24, 16 }, | 256 | [SCLSR] = { 0x24, 16 }, |
248 | [HSSRR] = sci_reg_invalid, | 257 | [HSSRR] = sci_reg_invalid, |
258 | [SCPCR] = sci_reg_invalid, | ||
259 | [SCPDR] = sci_reg_invalid, | ||
249 | }, | 260 | }, |
250 | 261 | ||
251 | /* | 262 | /* |
@@ -265,6 +276,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
265 | [SCSPTR] = sci_reg_invalid, | 276 | [SCSPTR] = sci_reg_invalid, |
266 | [SCLSR] = sci_reg_invalid, | 277 | [SCLSR] = sci_reg_invalid, |
267 | [HSSRR] = sci_reg_invalid, | 278 | [HSSRR] = sci_reg_invalid, |
279 | [SCPCR] = sci_reg_invalid, | ||
280 | [SCPDR] = sci_reg_invalid, | ||
268 | }, | 281 | }, |
269 | 282 | ||
270 | /* | 283 | /* |
@@ -284,6 +297,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
284 | [SCSPTR] = { 0x20, 16 }, | 297 | [SCSPTR] = { 0x20, 16 }, |
285 | [SCLSR] = { 0x24, 16 }, | 298 | [SCLSR] = { 0x24, 16 }, |
286 | [HSSRR] = sci_reg_invalid, | 299 | [HSSRR] = sci_reg_invalid, |
300 | [SCPCR] = sci_reg_invalid, | ||
301 | [SCPDR] = sci_reg_invalid, | ||
287 | }, | 302 | }, |
288 | 303 | ||
289 | /* | 304 | /* |
@@ -303,6 +318,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
303 | [SCSPTR] = { 0x20, 16 }, | 318 | [SCSPTR] = { 0x20, 16 }, |
304 | [SCLSR] = { 0x24, 16 }, | 319 | [SCLSR] = { 0x24, 16 }, |
305 | [HSSRR] = { 0x40, 16 }, | 320 | [HSSRR] = { 0x40, 16 }, |
321 | [SCPCR] = sci_reg_invalid, | ||
322 | [SCPDR] = sci_reg_invalid, | ||
306 | }, | 323 | }, |
307 | 324 | ||
308 | /* | 325 | /* |
@@ -323,6 +340,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
323 | [SCSPTR] = sci_reg_invalid, | 340 | [SCSPTR] = sci_reg_invalid, |
324 | [SCLSR] = { 0x24, 16 }, | 341 | [SCLSR] = { 0x24, 16 }, |
325 | [HSSRR] = sci_reg_invalid, | 342 | [HSSRR] = sci_reg_invalid, |
343 | [SCPCR] = sci_reg_invalid, | ||
344 | [SCPDR] = sci_reg_invalid, | ||
326 | }, | 345 | }, |
327 | 346 | ||
328 | /* | 347 | /* |
@@ -343,6 +362,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
343 | [SCSPTR] = { 0x24, 16 }, | 362 | [SCSPTR] = { 0x24, 16 }, |
344 | [SCLSR] = { 0x28, 16 }, | 363 | [SCLSR] = { 0x28, 16 }, |
345 | [HSSRR] = sci_reg_invalid, | 364 | [HSSRR] = sci_reg_invalid, |
365 | [SCPCR] = sci_reg_invalid, | ||
366 | [SCPDR] = sci_reg_invalid, | ||
346 | }, | 367 | }, |
347 | 368 | ||
348 | /* | 369 | /* |
@@ -363,6 +384,8 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | |||
363 | [SCSPTR] = sci_reg_invalid, | 384 | [SCSPTR] = sci_reg_invalid, |
364 | [SCLSR] = sci_reg_invalid, | 385 | [SCLSR] = sci_reg_invalid, |
365 | [HSSRR] = sci_reg_invalid, | 386 | [HSSRR] = sci_reg_invalid, |
387 | [SCPCR] = sci_reg_invalid, | ||
388 | [SCPDR] = sci_reg_invalid, | ||
366 | }, | 389 | }, |
367 | }; | 390 | }; |
368 | 391 | ||
@@ -781,7 +804,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
781 | struct sci_port *s = to_sci_port(port); | 804 | struct sci_port *s = to_sci_port(port); |
782 | 805 | ||
783 | /* Handle overruns */ | 806 | /* Handle overruns */ |
784 | if (status & (1 << s->overrun_bit)) { | 807 | if (status & s->overrun_mask) { |
785 | port->icount.overrun++; | 808 | port->icount.overrun++; |
786 | 809 | ||
787 | /* overrun error */ | 810 | /* overrun error */ |
@@ -844,32 +867,17 @@ static int sci_handle_fifo_overrun(struct uart_port *port) | |||
844 | struct tty_port *tport = &port->state->port; | 867 | struct tty_port *tport = &port->state->port; |
845 | struct sci_port *s = to_sci_port(port); | 868 | struct sci_port *s = to_sci_port(port); |
846 | struct plat_sci_reg *reg; | 869 | struct plat_sci_reg *reg; |
847 | int copied = 0, offset; | 870 | int copied = 0; |
848 | u16 status, bit; | 871 | u16 status; |
849 | |||
850 | switch (port->type) { | ||
851 | case PORT_SCIF: | ||
852 | case PORT_HSCIF: | ||
853 | offset = SCLSR; | ||
854 | break; | ||
855 | case PORT_SCIFA: | ||
856 | case PORT_SCIFB: | ||
857 | offset = SCxSR; | ||
858 | break; | ||
859 | default: | ||
860 | return 0; | ||
861 | } | ||
862 | 872 | ||
863 | reg = sci_getreg(port, offset); | 873 | reg = sci_getreg(port, s->overrun_reg); |
864 | if (!reg->size) | 874 | if (!reg->size) |
865 | return 0; | 875 | return 0; |
866 | 876 | ||
867 | status = serial_port_in(port, offset); | 877 | status = serial_port_in(port, s->overrun_reg); |
868 | bit = 1 << s->overrun_bit; | 878 | if (status & s->overrun_mask) { |
869 | 879 | status &= ~s->overrun_mask; | |
870 | if (status & bit) { | 880 | serial_port_out(port, s->overrun_reg, status); |
871 | status &= ~bit; | ||
872 | serial_port_out(port, offset, status); | ||
873 | 881 | ||
874 | port->icount.overrun++; | 882 | port->icount.overrun++; |
875 | 883 | ||
@@ -1021,15 +1029,11 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
1021 | 1029 | ||
1022 | ssr_status = serial_port_in(port, SCxSR); | 1030 | ssr_status = serial_port_in(port, SCxSR); |
1023 | scr_status = serial_port_in(port, SCSCR); | 1031 | scr_status = serial_port_in(port, SCSCR); |
1024 | switch (port->type) { | 1032 | if (s->overrun_reg == SCxSR) |
1025 | case PORT_SCIF: | ||
1026 | case PORT_HSCIF: | ||
1027 | orer_status = serial_port_in(port, SCLSR); | ||
1028 | break; | ||
1029 | case PORT_SCIFA: | ||
1030 | case PORT_SCIFB: | ||
1031 | orer_status = ssr_status; | 1033 | orer_status = ssr_status; |
1032 | break; | 1034 | else { |
1035 | if (sci_getreg(port, s->overrun_reg)->size) | ||
1036 | orer_status = serial_port_in(port, s->overrun_reg); | ||
1033 | } | 1037 | } |
1034 | 1038 | ||
1035 | err_enabled = scr_status & port_rx_irq_mask(port); | 1039 | err_enabled = scr_status & port_rx_irq_mask(port); |
@@ -1059,7 +1063,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
1059 | ret = sci_br_interrupt(irq, ptr); | 1063 | ret = sci_br_interrupt(irq, ptr); |
1060 | 1064 | ||
1061 | /* Overrun Interrupt */ | 1065 | /* Overrun Interrupt */ |
1062 | if (orer_status & (1 << s->overrun_bit)) | 1066 | if (orer_status & s->overrun_mask) |
1063 | sci_handle_fifo_overrun(port); | 1067 | sci_handle_fifo_overrun(port); |
1064 | 1068 | ||
1065 | return ret; | 1069 | return ret; |
@@ -2226,32 +2230,38 @@ static int sci_init_single(struct platform_device *dev, | |||
2226 | switch (p->type) { | 2230 | switch (p->type) { |
2227 | case PORT_SCIFB: | 2231 | case PORT_SCIFB: |
2228 | port->fifosize = 256; | 2232 | port->fifosize = 256; |
2229 | sci_port->overrun_bit = 9; | 2233 | sci_port->overrun_reg = SCxSR; |
2234 | sci_port->overrun_mask = SCIFA_ORER; | ||
2230 | sampling_rate = 16; | 2235 | sampling_rate = 16; |
2231 | break; | 2236 | break; |
2232 | case PORT_HSCIF: | 2237 | case PORT_HSCIF: |
2233 | port->fifosize = 128; | 2238 | port->fifosize = 128; |
2234 | sampling_rate = 0; | 2239 | sampling_rate = 0; |
2235 | sci_port->overrun_bit = 0; | 2240 | sci_port->overrun_reg = SCLSR; |
2241 | sci_port->overrun_mask = SCLSR_ORER; | ||
2236 | break; | 2242 | break; |
2237 | case PORT_SCIFA: | 2243 | case PORT_SCIFA: |
2238 | port->fifosize = 64; | 2244 | port->fifosize = 64; |
2239 | sci_port->overrun_bit = 9; | 2245 | sci_port->overrun_reg = SCxSR; |
2246 | sci_port->overrun_mask = SCIFA_ORER; | ||
2240 | sampling_rate = 16; | 2247 | sampling_rate = 16; |
2241 | break; | 2248 | break; |
2242 | case PORT_SCIF: | 2249 | case PORT_SCIF: |
2243 | port->fifosize = 16; | 2250 | port->fifosize = 16; |
2244 | if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { | 2251 | if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { |
2245 | sci_port->overrun_bit = 9; | 2252 | sci_port->overrun_reg = SCxSR; |
2253 | sci_port->overrun_mask = SCIFA_ORER; | ||
2246 | sampling_rate = 16; | 2254 | sampling_rate = 16; |
2247 | } else { | 2255 | } else { |
2248 | sci_port->overrun_bit = 0; | 2256 | sci_port->overrun_reg = SCLSR; |
2257 | sci_port->overrun_mask = SCLSR_ORER; | ||
2249 | sampling_rate = 32; | 2258 | sampling_rate = 32; |
2250 | } | 2259 | } |
2251 | break; | 2260 | break; |
2252 | default: | 2261 | default: |
2253 | port->fifosize = 1; | 2262 | port->fifosize = 1; |
2254 | sci_port->overrun_bit = 5; | 2263 | sci_port->overrun_reg = SCxSR; |
2264 | sci_port->overrun_mask = SCI_ORER; | ||
2255 | sampling_rate = 32; | 2265 | sampling_rate = 32; |
2256 | break; | 2266 | break; |
2257 | } | 2267 | } |
@@ -2297,15 +2307,11 @@ static int sci_init_single(struct platform_device *dev, | |||
2297 | SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; | 2307 | SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; |
2298 | 2308 | ||
2299 | /* | 2309 | /* |
2300 | * Establish sensible defaults for the overrun detection, unless | ||
2301 | * the part has explicitly disabled support for it. | ||
2302 | */ | ||
2303 | |||
2304 | /* | ||
2305 | * Make the error mask inclusive of overrun detection, if | 2310 | * Make the error mask inclusive of overrun detection, if |
2306 | * supported. | 2311 | * supported. |
2307 | */ | 2312 | */ |
2308 | sci_port->error_mask |= 1 << sci_port->overrun_bit; | 2313 | if (sci_port->overrun_reg == SCxSR) |
2314 | sci_port->error_mask |= sci_port->overrun_mask; | ||
2309 | 2315 | ||
2310 | port->type = p->type; | 2316 | port->type = p->type; |
2311 | port->flags = UPF_FIXED_PORT | p->flags; | 2317 | port->flags = UPF_FIXED_PORT | p->flags; |
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index d5db81a0a430..3393f67b4e84 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
@@ -1,7 +1,115 @@ | |||
1 | #include <linux/bitops.h> | ||
1 | #include <linux/serial_core.h> | 2 | #include <linux/serial_core.h> |
2 | #include <linux/io.h> | 3 | #include <linux/io.h> |
3 | #include <linux/gpio.h> | 4 | #include <linux/gpio.h> |
4 | 5 | ||
6 | #define SCI_MAJOR 204 | ||
7 | #define SCI_MINOR_START 8 | ||
8 | |||
9 | |||
10 | /* | ||
11 | * SCI register subset common for all port types. | ||
12 | * Not all registers will exist on all parts. | ||
13 | */ | ||
14 | enum { | ||
15 | SCSMR, /* Serial Mode Register */ | ||
16 | SCBRR, /* Bit Rate Register */ | ||
17 | SCSCR, /* Serial Control Register */ | ||
18 | SCxSR, /* Serial Status Register */ | ||
19 | SCFCR, /* FIFO Control Register */ | ||
20 | SCFDR, /* FIFO Data Count Register */ | ||
21 | SCxTDR, /* Transmit (FIFO) Data Register */ | ||
22 | SCxRDR, /* Receive (FIFO) Data Register */ | ||
23 | SCLSR, /* Line Status Register */ | ||
24 | SCTFDR, /* Transmit FIFO Data Count Register */ | ||
25 | SCRFDR, /* Receive FIFO Data Count Register */ | ||
26 | SCSPTR, /* Serial Port Register */ | ||
27 | HSSRR, /* Sampling Rate Register */ | ||
28 | SCPCR, /* Serial Port Control Register */ | ||
29 | SCPDR, /* Serial Port Data Register */ | ||
30 | |||
31 | SCIx_NR_REGS, | ||
32 | }; | ||
33 | |||
34 | |||
35 | /* SCSMR (Serial Mode Register) */ | ||
36 | #define SCSMR_CHR BIT(6) /* 7-bit Character Length */ | ||
37 | #define SCSMR_PE BIT(5) /* Parity Enable */ | ||
38 | #define SCSMR_ODD BIT(4) /* Odd Parity */ | ||
39 | #define SCSMR_STOP BIT(3) /* Stop Bit Length */ | ||
40 | #define SCSMR_CKS 0x0003 /* Clock Select */ | ||
41 | |||
42 | /* Serial Control Register, SCIFA/SCIFB only bits */ | ||
43 | #define SCSCR_TDRQE BIT(15) /* Tx Data Transfer Request Enable */ | ||
44 | #define SCSCR_RDRQE BIT(14) /* Rx Data Transfer Request Enable */ | ||
45 | |||
46 | /* SCxSR (Serial Status Register) on SCI */ | ||
47 | #define SCI_TDRE BIT(7) /* Transmit Data Register Empty */ | ||
48 | #define SCI_RDRF BIT(6) /* Receive Data Register Full */ | ||
49 | #define SCI_ORER BIT(5) /* Overrun Error */ | ||
50 | #define SCI_FER BIT(4) /* Framing Error */ | ||
51 | #define SCI_PER BIT(3) /* Parity Error */ | ||
52 | #define SCI_TEND BIT(2) /* Transmit End */ | ||
53 | #define SCI_RESERVED 0x03 /* All reserved bits */ | ||
54 | |||
55 | #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) | ||
56 | |||
57 | #define SCI_RDxF_CLEAR ~(SCI_RESERVED | SCI_RDRF) | ||
58 | #define SCI_ERROR_CLEAR ~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER) | ||
59 | #define SCI_TDxE_CLEAR ~(SCI_RESERVED | SCI_TEND | SCI_TDRE) | ||
60 | #define SCI_BREAK_CLEAR ~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER) | ||
61 | |||
62 | /* SCxSR (Serial Status Register) on SCIF, SCIFA, SCIFB, HSCIF */ | ||
63 | #define SCIF_ER BIT(7) /* Receive Error */ | ||
64 | #define SCIF_TEND BIT(6) /* Transmission End */ | ||
65 | #define SCIF_TDFE BIT(5) /* Transmit FIFO Data Empty */ | ||
66 | #define SCIF_BRK BIT(4) /* Break Detect */ | ||
67 | #define SCIF_FER BIT(3) /* Framing Error */ | ||
68 | #define SCIF_PER BIT(2) /* Parity Error */ | ||
69 | #define SCIF_RDF BIT(1) /* Receive FIFO Data Full */ | ||
70 | #define SCIF_DR BIT(0) /* Receive Data Ready */ | ||
71 | /* SCIF only (optional) */ | ||
72 | #define SCIF_PERC 0xf000 /* Number of Parity Errors */ | ||
73 | #define SCIF_FERC 0x0f00 /* Number of Framing Errors */ | ||
74 | /*SCIFA/SCIFB and SCIF on SH7705/SH7720/SH7721 only */ | ||
75 | #define SCIFA_ORER BIT(9) /* Overrun Error */ | ||
76 | |||
77 | #define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_BRK | SCIF_ER) | ||
78 | |||
79 | #define SCIF_RDxF_CLEAR ~(SCIF_DR | SCIF_RDF) | ||
80 | #define SCIF_ERROR_CLEAR ~(SCIFA_ORER | SCIF_PER | SCIF_FER | SCIF_ER) | ||
81 | #define SCIF_TDxE_CLEAR ~(SCIF_TDFE) | ||
82 | #define SCIF_BREAK_CLEAR ~(SCIF_PER | SCIF_FER | SCIF_BRK) | ||
83 | |||
84 | /* SCFCR (FIFO Control Register) */ | ||
85 | #define SCFCR_MCE BIT(3) /* Modem Control Enable */ | ||
86 | #define SCFCR_TFRST BIT(2) /* Transmit FIFO Data Register Reset */ | ||
87 | #define SCFCR_RFRST BIT(1) /* Receive FIFO Data Register Reset */ | ||
88 | #define SCFCR_LOOP BIT(0) /* Loopback Test */ | ||
89 | |||
90 | /* SCLSR (Line Status Register) on (H)SCIF */ | ||
91 | #define SCLSR_ORER BIT(0) /* Overrun Error */ | ||
92 | |||
93 | /* SCSPTR (Serial Port Register), optional */ | ||
94 | #define SCSPTR_RTSIO BIT(7) /* Serial Port RTS Pin Input/Output */ | ||
95 | #define SCSPTR_RTSDT BIT(6) /* Serial Port RTS Pin Data */ | ||
96 | #define SCSPTR_CTSIO BIT(5) /* Serial Port CTS Pin Input/Output */ | ||
97 | #define SCSPTR_CTSDT BIT(4) /* Serial Port CTS Pin Data */ | ||
98 | #define SCSPTR_SPB2IO BIT(1) /* Serial Port Break Input/Output */ | ||
99 | #define SCSPTR_SPB2DT BIT(0) /* Serial Port Break Data */ | ||
100 | |||
101 | /* HSSRR HSCIF */ | ||
102 | #define HSCIF_SRE BIT(15) /* Sampling Rate Register Enable */ | ||
103 | |||
104 | /* SCPCR (Serial Port Control Register), SCIFA/SCIFB only */ | ||
105 | #define SCPCR_RTSC BIT(4) /* Serial Port RTS Pin / Output Pin */ | ||
106 | #define SCPCR_CTSC BIT(3) /* Serial Port CTS Pin / Input Pin */ | ||
107 | |||
108 | /* SCPDR (Serial Port Data Register), SCIFA/SCIFB only */ | ||
109 | #define SCPDR_RTSD BIT(4) /* Serial Port RTS Output Pin Data */ | ||
110 | #define SCPDR_CTSD BIT(3) /* Serial Port CTS Input Pin Data */ | ||
111 | |||
112 | |||
5 | #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) | 113 | #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) |
6 | #define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) | 114 | #define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) |
7 | #define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) | 115 | #define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) |
@@ -15,24 +123,24 @@ | |||
15 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 123 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
16 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 124 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
17 | defined(CONFIG_ARCH_SH73A0) || \ | 125 | defined(CONFIG_ARCH_SH73A0) || \ |
18 | defined(CONFIG_ARCH_SH7372) || \ | ||
19 | defined(CONFIG_ARCH_R8A7740) | 126 | defined(CONFIG_ARCH_R8A7740) |
20 | 127 | ||
21 | # define SCxSR_RDxF_CLEAR(port) (serial_port_in(port, SCxSR) & 0xfffc) | 128 | # define SCxSR_RDxF_CLEAR(port) \ |
22 | # define SCxSR_ERROR_CLEAR(port) (serial_port_in(port, SCxSR) & 0xfd73) | 129 | (serial_port_in(port, SCxSR) & SCIF_RDxF_CLEAR) |
23 | # define SCxSR_TDxE_CLEAR(port) (serial_port_in(port, SCxSR) & 0xffdf) | 130 | # define SCxSR_ERROR_CLEAR(port) \ |
24 | # define SCxSR_BREAK_CLEAR(port) (serial_port_in(port, SCxSR) & 0xffe3) | 131 | (serial_port_in(port, SCxSR) & SCIF_ERROR_CLEAR) |
132 | # define SCxSR_TDxE_CLEAR(port) \ | ||
133 | (serial_port_in(port, SCxSR) & SCIF_TDxE_CLEAR) | ||
134 | # define SCxSR_BREAK_CLEAR(port) \ | ||
135 | (serial_port_in(port, SCxSR) & SCIF_BREAK_CLEAR) | ||
25 | #else | 136 | #else |
26 | # define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc) | 137 | # define SCxSR_RDxF_CLEAR(port) \ |
27 | # define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073) | 138 | ((((port)->type == PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR) & 0xff) |
28 | # define SCxSR_TDxE_CLEAR(port) (((port)->type == PORT_SCI) ? 0x78 : 0x00df) | 139 | # define SCxSR_ERROR_CLEAR(port) \ |
29 | # define SCxSR_BREAK_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x00e3) | 140 | ((((port)->type == PORT_SCI) ? SCI_ERROR_CLEAR : SCIF_ERROR_CLEAR) & 0xff) |
141 | # define SCxSR_TDxE_CLEAR(port) \ | ||
142 | ((((port)->type == PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR) & 0xff) | ||
143 | # define SCxSR_BREAK_CLEAR(port) \ | ||
144 | ((((port)->type == PORT_SCI) ? SCI_BREAK_CLEAR : SCIF_BREAK_CLEAR) & 0xff) | ||
30 | #endif | 145 | #endif |
31 | 146 | ||
32 | /* SCFCR */ | ||
33 | #define SCFCR_RFRST 0x0002 | ||
34 | #define SCFCR_TFRST 0x0004 | ||
35 | #define SCFCR_MCE 0x0008 | ||
36 | |||
37 | #define SCI_MAJOR 204 | ||
38 | #define SCI_MINOR_START 8 | ||
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 9de3eabe5737..653cdd5fb508 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -36,8 +36,6 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count); | |||
36 | static struct uart_driver sirfsoc_uart_drv; | 36 | static struct uart_driver sirfsoc_uart_drv; |
37 | 37 | ||
38 | static void sirfsoc_uart_tx_dma_complete_callback(void *param); | 38 | static void sirfsoc_uart_tx_dma_complete_callback(void *param); |
39 | static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port); | ||
40 | static void sirfsoc_uart_rx_dma_complete_callback(void *param); | ||
41 | static const struct sirfsoc_baudrate_to_regv baudrate_to_regv[] = { | 39 | static const struct sirfsoc_baudrate_to_regv baudrate_to_regv[] = { |
42 | {4000000, 2359296}, | 40 | {4000000, 2359296}, |
43 | {3500000, 1310721}, | 41 | {3500000, 1310721}, |
@@ -59,50 +57,7 @@ static const struct sirfsoc_baudrate_to_regv baudrate_to_regv[] = { | |||
59 | {9600, 1114979}, | 57 | {9600, 1114979}, |
60 | }; | 58 | }; |
61 | 59 | ||
62 | static struct sirfsoc_uart_port sirfsoc_uart_ports[SIRFSOC_UART_NR] = { | 60 | static struct sirfsoc_uart_port *sirf_ports[SIRFSOC_UART_NR]; |
63 | [0] = { | ||
64 | .port = { | ||
65 | .iotype = UPIO_MEM, | ||
66 | .flags = UPF_BOOT_AUTOCONF, | ||
67 | .line = 0, | ||
68 | }, | ||
69 | }, | ||
70 | [1] = { | ||
71 | .port = { | ||
72 | .iotype = UPIO_MEM, | ||
73 | .flags = UPF_BOOT_AUTOCONF, | ||
74 | .line = 1, | ||
75 | }, | ||
76 | }, | ||
77 | [2] = { | ||
78 | .port = { | ||
79 | .iotype = UPIO_MEM, | ||
80 | .flags = UPF_BOOT_AUTOCONF, | ||
81 | .line = 2, | ||
82 | }, | ||
83 | }, | ||
84 | [3] = { | ||
85 | .port = { | ||
86 | .iotype = UPIO_MEM, | ||
87 | .flags = UPF_BOOT_AUTOCONF, | ||
88 | .line = 3, | ||
89 | }, | ||
90 | }, | ||
91 | [4] = { | ||
92 | .port = { | ||
93 | .iotype = UPIO_MEM, | ||
94 | .flags = UPF_BOOT_AUTOCONF, | ||
95 | .line = 4, | ||
96 | }, | ||
97 | }, | ||
98 | [5] = { | ||
99 | .port = { | ||
100 | .iotype = UPIO_MEM, | ||
101 | .flags = UPF_BOOT_AUTOCONF, | ||
102 | .line = 5, | ||
103 | }, | ||
104 | }, | ||
105 | }; | ||
106 | 61 | ||
107 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) | 62 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) |
108 | { | 63 | { |
@@ -116,8 +71,7 @@ static inline unsigned int sirfsoc_uart_tx_empty(struct uart_port *port) | |||
116 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 71 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
117 | struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; | 72 | struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; |
118 | reg = rd_regl(port, ureg->sirfsoc_tx_fifo_status); | 73 | reg = rd_regl(port, ureg->sirfsoc_tx_fifo_status); |
119 | 74 | return (reg & ufifo_st->ff_empty(port)) ? TIOCSER_TEMT : 0; | |
120 | return (reg & ufifo_st->ff_empty(port->line)) ? TIOCSER_TEMT : 0; | ||
121 | } | 75 | } |
122 | 76 | ||
123 | static unsigned int sirfsoc_uart_get_mctrl(struct uart_port *port) | 77 | static unsigned int sirfsoc_uart_get_mctrl(struct uart_port *port) |
@@ -152,6 +106,26 @@ static void sirfsoc_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
152 | unsigned int val = assert ? SIRFUART_AFC_CTRL_RX_THD : 0x0; | 106 | unsigned int val = assert ? SIRFUART_AFC_CTRL_RX_THD : 0x0; |
153 | unsigned int current_val; | 107 | unsigned int current_val; |
154 | 108 | ||
109 | if (mctrl & TIOCM_LOOP) { | ||
110 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) | ||
111 | wr_regl(port, ureg->sirfsoc_line_ctrl, | ||
112 | rd_regl(port, ureg->sirfsoc_line_ctrl) | | ||
113 | SIRFUART_LOOP_BACK); | ||
114 | else | ||
115 | wr_regl(port, ureg->sirfsoc_mode1, | ||
116 | rd_regl(port, ureg->sirfsoc_mode1) | | ||
117 | SIRFSOC_USP_LOOP_BACK_CTRL); | ||
118 | } else { | ||
119 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) | ||
120 | wr_regl(port, ureg->sirfsoc_line_ctrl, | ||
121 | rd_regl(port, ureg->sirfsoc_line_ctrl) & | ||
122 | ~SIRFUART_LOOP_BACK); | ||
123 | else | ||
124 | wr_regl(port, ureg->sirfsoc_mode1, | ||
125 | rd_regl(port, ureg->sirfsoc_mode1) & | ||
126 | ~SIRFSOC_USP_LOOP_BACK_CTRL); | ||
127 | } | ||
128 | |||
155 | if (!sirfport->hw_flow_ctrl || !sirfport->ms_enabled) | 129 | if (!sirfport->hw_flow_ctrl || !sirfport->ms_enabled) |
156 | return; | 130 | return; |
157 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { | 131 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { |
@@ -182,16 +156,19 @@ static void sirfsoc_uart_stop_tx(struct uart_port *port) | |||
182 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 156 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
183 | ~uint_en->sirfsoc_txfifo_empty_en); | 157 | ~uint_en->sirfsoc_txfifo_empty_en); |
184 | else | 158 | else |
185 | wr_regl(port, SIRFUART_INT_EN_CLR, | 159 | wr_regl(port, ureg->sirfsoc_int_en_clr_reg, |
186 | uint_en->sirfsoc_txfifo_empty_en); | 160 | uint_en->sirfsoc_txfifo_empty_en); |
187 | } | 161 | } |
188 | } else { | 162 | } else { |
163 | if (sirfport->uart_reg->uart_type == SIRF_USP_UART) | ||
164 | wr_regl(port, ureg->sirfsoc_tx_rx_en, rd_regl(port, | ||
165 | ureg->sirfsoc_tx_rx_en) & ~SIRFUART_TX_EN); | ||
189 | if (!sirfport->is_atlas7) | 166 | if (!sirfport->is_atlas7) |
190 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 167 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
191 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 168 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
192 | ~uint_en->sirfsoc_txfifo_empty_en); | 169 | ~uint_en->sirfsoc_txfifo_empty_en); |
193 | else | 170 | else |
194 | wr_regl(port, SIRFUART_INT_EN_CLR, | 171 | wr_regl(port, ureg->sirfsoc_int_en_clr_reg, |
195 | uint_en->sirfsoc_txfifo_empty_en); | 172 | uint_en->sirfsoc_txfifo_empty_en); |
196 | } | 173 | } |
197 | } | 174 | } |
@@ -222,7 +199,7 @@ static void sirfsoc_uart_tx_with_dma(struct sirfsoc_uart_port *sirfport) | |||
222 | rd_regl(port, ureg->sirfsoc_int_en_reg)& | 199 | rd_regl(port, ureg->sirfsoc_int_en_reg)& |
223 | ~(uint_en->sirfsoc_txfifo_empty_en)); | 200 | ~(uint_en->sirfsoc_txfifo_empty_en)); |
224 | else | 201 | else |
225 | wr_regl(port, SIRFUART_INT_EN_CLR, | 202 | wr_regl(port, ureg->sirfsoc_int_en_clr_reg, |
226 | uint_en->sirfsoc_txfifo_empty_en); | 203 | uint_en->sirfsoc_txfifo_empty_en); |
227 | /* | 204 | /* |
228 | * DMA requires buffer address and buffer length are both aligned with | 205 | * DMA requires buffer address and buffer length are both aligned with |
@@ -290,8 +267,11 @@ static void sirfsoc_uart_start_tx(struct uart_port *port) | |||
290 | if (sirfport->tx_dma_chan) | 267 | if (sirfport->tx_dma_chan) |
291 | sirfsoc_uart_tx_with_dma(sirfport); | 268 | sirfsoc_uart_tx_with_dma(sirfport); |
292 | else { | 269 | else { |
293 | sirfsoc_uart_pio_tx_chars(sirfport, | 270 | if (sirfport->uart_reg->uart_type == SIRF_USP_UART) |
294 | SIRFSOC_UART_IO_TX_REASONABLE_CNT); | 271 | wr_regl(port, ureg->sirfsoc_tx_rx_en, rd_regl(port, |
272 | ureg->sirfsoc_tx_rx_en) | SIRFUART_TX_EN); | ||
273 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_STOP); | ||
274 | sirfsoc_uart_pio_tx_chars(sirfport, port->fifosize); | ||
295 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START); | 275 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START); |
296 | if (!sirfport->is_atlas7) | 276 | if (!sirfport->is_atlas7) |
297 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 277 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
@@ -314,21 +294,25 @@ static void sirfsoc_uart_stop_rx(struct uart_port *port) | |||
314 | if (!sirfport->is_atlas7) | 294 | if (!sirfport->is_atlas7) |
315 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 295 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
316 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 296 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
317 | ~(SIRFUART_RX_DMA_INT_EN(port, uint_en) | | 297 | ~(SIRFUART_RX_DMA_INT_EN(uint_en, |
298 | sirfport->uart_reg->uart_type) | | ||
318 | uint_en->sirfsoc_rx_done_en)); | 299 | uint_en->sirfsoc_rx_done_en)); |
319 | else | 300 | else |
320 | wr_regl(port, SIRFUART_INT_EN_CLR, | 301 | wr_regl(port, ureg->sirfsoc_int_en_clr_reg, |
321 | SIRFUART_RX_DMA_INT_EN(port, uint_en)| | 302 | SIRFUART_RX_DMA_INT_EN(uint_en, |
322 | uint_en->sirfsoc_rx_done_en); | 303 | sirfport->uart_reg->uart_type)| |
304 | uint_en->sirfsoc_rx_done_en); | ||
323 | dmaengine_terminate_all(sirfport->rx_dma_chan); | 305 | dmaengine_terminate_all(sirfport->rx_dma_chan); |
324 | } else { | 306 | } else { |
325 | if (!sirfport->is_atlas7) | 307 | if (!sirfport->is_atlas7) |
326 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 308 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
327 | rd_regl(port, ureg->sirfsoc_int_en_reg)& | 309 | rd_regl(port, ureg->sirfsoc_int_en_reg)& |
328 | ~(SIRFUART_RX_IO_INT_EN(port, uint_en))); | 310 | ~(SIRFUART_RX_IO_INT_EN(uint_en, |
311 | sirfport->uart_reg->uart_type))); | ||
329 | else | 312 | else |
330 | wr_regl(port, SIRFUART_INT_EN_CLR, | 313 | wr_regl(port, ureg->sirfsoc_int_en_clr_reg, |
331 | SIRFUART_RX_IO_INT_EN(port, uint_en)); | 314 | SIRFUART_RX_IO_INT_EN(uint_en, |
315 | sirfport->uart_reg->uart_type)); | ||
332 | } | 316 | } |
333 | } | 317 | } |
334 | 318 | ||
@@ -349,7 +333,7 @@ static void sirfsoc_uart_disable_ms(struct uart_port *port) | |||
349 | rd_regl(port, ureg->sirfsoc_int_en_reg)& | 333 | rd_regl(port, ureg->sirfsoc_int_en_reg)& |
350 | ~uint_en->sirfsoc_cts_en); | 334 | ~uint_en->sirfsoc_cts_en); |
351 | else | 335 | else |
352 | wr_regl(port, SIRFUART_INT_EN_CLR, | 336 | wr_regl(port, ureg->sirfsoc_int_en_clr_reg, |
353 | uint_en->sirfsoc_cts_en); | 337 | uint_en->sirfsoc_cts_en); |
354 | } else | 338 | } else |
355 | disable_irq(gpio_to_irq(sirfport->cts_gpio)); | 339 | disable_irq(gpio_to_irq(sirfport->cts_gpio)); |
@@ -379,7 +363,8 @@ static void sirfsoc_uart_enable_ms(struct uart_port *port) | |||
379 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { | 363 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { |
380 | wr_regl(port, ureg->sirfsoc_afc_ctrl, | 364 | wr_regl(port, ureg->sirfsoc_afc_ctrl, |
381 | rd_regl(port, ureg->sirfsoc_afc_ctrl) | | 365 | rd_regl(port, ureg->sirfsoc_afc_ctrl) | |
382 | SIRFUART_AFC_TX_EN | SIRFUART_AFC_RX_EN); | 366 | SIRFUART_AFC_TX_EN | SIRFUART_AFC_RX_EN | |
367 | SIRFUART_AFC_CTRL_RX_THD); | ||
383 | if (!sirfport->is_atlas7) | 368 | if (!sirfport->is_atlas7) |
384 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 369 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
385 | rd_regl(port, ureg->sirfsoc_int_en_reg) | 370 | rd_regl(port, ureg->sirfsoc_int_en_reg) |
@@ -417,7 +402,7 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | |||
417 | if (!tty) | 402 | if (!tty) |
418 | return -ENODEV; | 403 | return -ENODEV; |
419 | while (!(rd_regl(port, ureg->sirfsoc_rx_fifo_status) & | 404 | while (!(rd_regl(port, ureg->sirfsoc_rx_fifo_status) & |
420 | ufifo_st->ff_empty(port->line))) { | 405 | ufifo_st->ff_empty(port))) { |
421 | ch = rd_regl(port, ureg->sirfsoc_rx_fifo_data) | | 406 | ch = rd_regl(port, ureg->sirfsoc_rx_fifo_data) | |
422 | SIRFUART_DUMMY_READ; | 407 | SIRFUART_DUMMY_READ; |
423 | if (unlikely(uart_handle_sysrq_char(port, ch))) | 408 | if (unlikely(uart_handle_sysrq_char(port, ch))) |
@@ -444,7 +429,7 @@ sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count) | |||
444 | unsigned int num_tx = 0; | 429 | unsigned int num_tx = 0; |
445 | while (!uart_circ_empty(xmit) && | 430 | while (!uart_circ_empty(xmit) && |
446 | !(rd_regl(port, ureg->sirfsoc_tx_fifo_status) & | 431 | !(rd_regl(port, ureg->sirfsoc_tx_fifo_status) & |
447 | ufifo_st->ff_full(port->line)) && | 432 | ufifo_st->ff_full(port)) && |
448 | count--) { | 433 | count--) { |
449 | wr_regl(port, ureg->sirfsoc_tx_fifo_data, | 434 | wr_regl(port, ureg->sirfsoc_tx_fifo_data, |
450 | xmit->buf[xmit->tail]); | 435 | xmit->buf[xmit->tail]); |
@@ -478,139 +463,6 @@ static void sirfsoc_uart_tx_dma_complete_callback(void *param) | |||
478 | spin_unlock_irqrestore(&port->lock, flags); | 463 | spin_unlock_irqrestore(&port->lock, flags); |
479 | } | 464 | } |
480 | 465 | ||
481 | static void sirfsoc_uart_insert_rx_buf_to_tty( | ||
482 | struct sirfsoc_uart_port *sirfport, int count) | ||
483 | { | ||
484 | struct uart_port *port = &sirfport->port; | ||
485 | struct tty_port *tport = &port->state->port; | ||
486 | int inserted; | ||
487 | |||
488 | inserted = tty_insert_flip_string(tport, | ||
489 | sirfport->rx_dma_items[sirfport->rx_completed].xmit.buf, count); | ||
490 | port->icount.rx += inserted; | ||
491 | } | ||
492 | |||
493 | static void sirfsoc_rx_submit_one_dma_desc(struct uart_port *port, int index) | ||
494 | { | ||
495 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
496 | |||
497 | sirfport->rx_dma_items[index].xmit.tail = | ||
498 | sirfport->rx_dma_items[index].xmit.head = 0; | ||
499 | sirfport->rx_dma_items[index].desc = | ||
500 | dmaengine_prep_slave_single(sirfport->rx_dma_chan, | ||
501 | sirfport->rx_dma_items[index].dma_addr, SIRFSOC_RX_DMA_BUF_SIZE, | ||
502 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); | ||
503 | if (!sirfport->rx_dma_items[index].desc) { | ||
504 | dev_err(port->dev, "DMA slave single fail\n"); | ||
505 | return; | ||
506 | } | ||
507 | sirfport->rx_dma_items[index].desc->callback = | ||
508 | sirfsoc_uart_rx_dma_complete_callback; | ||
509 | sirfport->rx_dma_items[index].desc->callback_param = sirfport; | ||
510 | sirfport->rx_dma_items[index].cookie = | ||
511 | dmaengine_submit(sirfport->rx_dma_items[index].desc); | ||
512 | dma_async_issue_pending(sirfport->rx_dma_chan); | ||
513 | } | ||
514 | |||
515 | static void sirfsoc_rx_tmo_process_tl(unsigned long param) | ||
516 | { | ||
517 | struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)param; | ||
518 | struct uart_port *port = &sirfport->port; | ||
519 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | ||
520 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | ||
521 | struct sirfsoc_int_status *uint_st = &sirfport->uart_reg->uart_int_st; | ||
522 | unsigned int count; | ||
523 | unsigned long flags; | ||
524 | struct dma_tx_state tx_state; | ||
525 | |||
526 | spin_lock_irqsave(&port->lock, flags); | ||
527 | while (DMA_COMPLETE == dmaengine_tx_status(sirfport->rx_dma_chan, | ||
528 | sirfport->rx_dma_items[sirfport->rx_completed].cookie, &tx_state)) { | ||
529 | sirfsoc_uart_insert_rx_buf_to_tty(sirfport, | ||
530 | SIRFSOC_RX_DMA_BUF_SIZE); | ||
531 | sirfport->rx_completed++; | ||
532 | sirfport->rx_completed %= SIRFSOC_RX_LOOP_BUF_CNT; | ||
533 | } | ||
534 | count = CIRC_CNT(sirfport->rx_dma_items[sirfport->rx_issued].xmit.head, | ||
535 | sirfport->rx_dma_items[sirfport->rx_issued].xmit.tail, | ||
536 | SIRFSOC_RX_DMA_BUF_SIZE); | ||
537 | if (count > 0) | ||
538 | sirfsoc_uart_insert_rx_buf_to_tty(sirfport, count); | ||
539 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | ||
540 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | | ||
541 | SIRFUART_IO_MODE); | ||
542 | sirfsoc_uart_pio_rx_chars(port, 4 - sirfport->rx_io_count); | ||
543 | if (sirfport->rx_io_count == 4) { | ||
544 | sirfport->rx_io_count = 0; | ||
545 | wr_regl(port, ureg->sirfsoc_int_st_reg, | ||
546 | uint_st->sirfsoc_rx_done); | ||
547 | if (!sirfport->is_atlas7) | ||
548 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
549 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | ||
550 | ~(uint_en->sirfsoc_rx_done_en)); | ||
551 | else | ||
552 | wr_regl(port, SIRFUART_INT_EN_CLR, | ||
553 | uint_en->sirfsoc_rx_done_en); | ||
554 | sirfsoc_uart_start_next_rx_dma(port); | ||
555 | } else { | ||
556 | wr_regl(port, ureg->sirfsoc_int_st_reg, | ||
557 | uint_st->sirfsoc_rx_done); | ||
558 | if (!sirfport->is_atlas7) | ||
559 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
560 | rd_regl(port, ureg->sirfsoc_int_en_reg) | | ||
561 | (uint_en->sirfsoc_rx_done_en)); | ||
562 | else | ||
563 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
564 | uint_en->sirfsoc_rx_done_en); | ||
565 | } | ||
566 | spin_unlock_irqrestore(&port->lock, flags); | ||
567 | tty_flip_buffer_push(&port->state->port); | ||
568 | } | ||
569 | |||
570 | static void sirfsoc_uart_handle_rx_tmo(struct sirfsoc_uart_port *sirfport) | ||
571 | { | ||
572 | struct uart_port *port = &sirfport->port; | ||
573 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | ||
574 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | ||
575 | struct dma_tx_state tx_state; | ||
576 | dmaengine_tx_status(sirfport->rx_dma_chan, | ||
577 | sirfport->rx_dma_items[sirfport->rx_issued].cookie, &tx_state); | ||
578 | dmaengine_terminate_all(sirfport->rx_dma_chan); | ||
579 | sirfport->rx_dma_items[sirfport->rx_issued].xmit.head = | ||
580 | SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue; | ||
581 | if (!sirfport->is_atlas7) | ||
582 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
583 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | ||
584 | ~(uint_en->sirfsoc_rx_timeout_en)); | ||
585 | else | ||
586 | wr_regl(port, SIRFUART_INT_EN_CLR, | ||
587 | uint_en->sirfsoc_rx_timeout_en); | ||
588 | tasklet_schedule(&sirfport->rx_tmo_process_tasklet); | ||
589 | } | ||
590 | |||
591 | static void sirfsoc_uart_handle_rx_done(struct sirfsoc_uart_port *sirfport) | ||
592 | { | ||
593 | struct uart_port *port = &sirfport->port; | ||
594 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | ||
595 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | ||
596 | struct sirfsoc_int_status *uint_st = &sirfport->uart_reg->uart_int_st; | ||
597 | |||
598 | sirfsoc_uart_pio_rx_chars(port, 4 - sirfport->rx_io_count); | ||
599 | if (sirfport->rx_io_count == 4) { | ||
600 | sirfport->rx_io_count = 0; | ||
601 | if (!sirfport->is_atlas7) | ||
602 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
603 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | ||
604 | ~(uint_en->sirfsoc_rx_done_en)); | ||
605 | else | ||
606 | wr_regl(port, SIRFUART_INT_EN_CLR, | ||
607 | uint_en->sirfsoc_rx_done_en); | ||
608 | wr_regl(port, ureg->sirfsoc_int_st_reg, | ||
609 | uint_st->sirfsoc_rx_timeout); | ||
610 | sirfsoc_uart_start_next_rx_dma(port); | ||
611 | } | ||
612 | } | ||
613 | |||
614 | static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | 466 | static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) |
615 | { | 467 | { |
616 | unsigned long intr_status; | 468 | unsigned long intr_status; |
@@ -628,20 +480,25 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | |||
628 | intr_status = rd_regl(port, ureg->sirfsoc_int_st_reg); | 480 | intr_status = rd_regl(port, ureg->sirfsoc_int_st_reg); |
629 | wr_regl(port, ureg->sirfsoc_int_st_reg, intr_status); | 481 | wr_regl(port, ureg->sirfsoc_int_st_reg, intr_status); |
630 | intr_status &= rd_regl(port, ureg->sirfsoc_int_en_reg); | 482 | intr_status &= rd_regl(port, ureg->sirfsoc_int_en_reg); |
631 | if (unlikely(intr_status & (SIRFUART_ERR_INT_STAT(port, uint_st)))) { | 483 | if (unlikely(intr_status & (SIRFUART_ERR_INT_STAT(uint_st, |
484 | sirfport->uart_reg->uart_type)))) { | ||
632 | if (intr_status & uint_st->sirfsoc_rxd_brk) { | 485 | if (intr_status & uint_st->sirfsoc_rxd_brk) { |
633 | port->icount.brk++; | 486 | port->icount.brk++; |
634 | if (uart_handle_break(port)) | 487 | if (uart_handle_break(port)) |
635 | goto recv_char; | 488 | goto recv_char; |
636 | } | 489 | } |
637 | if (intr_status & uint_st->sirfsoc_rx_oflow) | 490 | if (intr_status & uint_st->sirfsoc_rx_oflow) { |
638 | port->icount.overrun++; | 491 | port->icount.overrun++; |
492 | flag = TTY_OVERRUN; | ||
493 | } | ||
639 | if (intr_status & uint_st->sirfsoc_frm_err) { | 494 | if (intr_status & uint_st->sirfsoc_frm_err) { |
640 | port->icount.frame++; | 495 | port->icount.frame++; |
641 | flag = TTY_FRAME; | 496 | flag = TTY_FRAME; |
642 | } | 497 | } |
643 | if (intr_status & uint_st->sirfsoc_parity_err) | 498 | if (intr_status & uint_st->sirfsoc_parity_err) { |
499 | port->icount.parity++; | ||
644 | flag = TTY_PARITY; | 500 | flag = TTY_PARITY; |
501 | } | ||
645 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); | 502 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); |
646 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); | 503 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); |
647 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); | 504 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); |
@@ -662,15 +519,51 @@ recv_char: | |||
662 | uart_handle_cts_change(port, cts_status); | 519 | uart_handle_cts_change(port, cts_status); |
663 | wake_up_interruptible(&state->port.delta_msr_wait); | 520 | wake_up_interruptible(&state->port.delta_msr_wait); |
664 | } | 521 | } |
665 | if (sirfport->rx_dma_chan) { | 522 | if (!sirfport->rx_dma_chan && |
666 | if (intr_status & uint_st->sirfsoc_rx_timeout) | 523 | (intr_status & SIRFUART_RX_IO_INT_ST(uint_st))) { |
667 | sirfsoc_uart_handle_rx_tmo(sirfport); | 524 | /* |
668 | if (intr_status & uint_st->sirfsoc_rx_done) | 525 | * chip will trigger continuous RX_TIMEOUT interrupt |
669 | sirfsoc_uart_handle_rx_done(sirfport); | 526 | * in RXFIFO empty and not trigger if RXFIFO recevice |
670 | } else { | 527 | * data in limit time, original method use RX_TIMEOUT |
671 | if (intr_status & SIRFUART_RX_IO_INT_ST(uint_st)) | 528 | * will trigger lots of useless interrupt in RXFIFO |
672 | sirfsoc_uart_pio_rx_chars(port, | 529 | * empty.RXFIFO received one byte will trigger RX_DONE |
673 | SIRFSOC_UART_IO_RX_MAX_CNT); | 530 | * interrupt.use RX_DONE to wait for data received |
531 | * into RXFIFO, use RX_THD/RX_FULL for lots data receive | ||
532 | * and use RX_TIMEOUT for the last left data. | ||
533 | */ | ||
534 | if (intr_status & uint_st->sirfsoc_rx_done) { | ||
535 | if (!sirfport->is_atlas7) { | ||
536 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
537 | rd_regl(port, ureg->sirfsoc_int_en_reg) | ||
538 | & ~(uint_en->sirfsoc_rx_done_en)); | ||
539 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
540 | rd_regl(port, ureg->sirfsoc_int_en_reg) | ||
541 | | (uint_en->sirfsoc_rx_timeout_en)); | ||
542 | } else { | ||
543 | wr_regl(port, ureg->sirfsoc_int_en_clr_reg, | ||
544 | uint_en->sirfsoc_rx_done_en); | ||
545 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
546 | uint_en->sirfsoc_rx_timeout_en); | ||
547 | } | ||
548 | } else { | ||
549 | if (intr_status & uint_st->sirfsoc_rx_timeout) { | ||
550 | if (!sirfport->is_atlas7) { | ||
551 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
552 | rd_regl(port, ureg->sirfsoc_int_en_reg) | ||
553 | & ~(uint_en->sirfsoc_rx_timeout_en)); | ||
554 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
555 | rd_regl(port, ureg->sirfsoc_int_en_reg) | ||
556 | | (uint_en->sirfsoc_rx_done_en)); | ||
557 | } else { | ||
558 | wr_regl(port, | ||
559 | ureg->sirfsoc_int_en_clr_reg, | ||
560 | uint_en->sirfsoc_rx_timeout_en); | ||
561 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
562 | uint_en->sirfsoc_rx_done_en); | ||
563 | } | ||
564 | } | ||
565 | sirfsoc_uart_pio_rx_chars(port, port->fifosize); | ||
566 | } | ||
674 | } | 567 | } |
675 | spin_unlock(&port->lock); | 568 | spin_unlock(&port->lock); |
676 | tty_flip_buffer_push(&state->port); | 569 | tty_flip_buffer_push(&state->port); |
@@ -684,10 +577,10 @@ recv_char: | |||
684 | return IRQ_HANDLED; | 577 | return IRQ_HANDLED; |
685 | } else { | 578 | } else { |
686 | sirfsoc_uart_pio_tx_chars(sirfport, | 579 | sirfsoc_uart_pio_tx_chars(sirfport, |
687 | SIRFSOC_UART_IO_TX_REASONABLE_CNT); | 580 | port->fifosize); |
688 | if ((uart_circ_empty(xmit)) && | 581 | if ((uart_circ_empty(xmit)) && |
689 | (rd_regl(port, ureg->sirfsoc_tx_fifo_status) & | 582 | (rd_regl(port, ureg->sirfsoc_tx_fifo_status) & |
690 | ufifo_st->ff_empty(port->line))) | 583 | ufifo_st->ff_empty(port))) |
691 | sirfsoc_uart_stop_tx(port); | 584 | sirfsoc_uart_stop_tx(port); |
692 | } | 585 | } |
693 | } | 586 | } |
@@ -697,41 +590,8 @@ recv_char: | |||
697 | return IRQ_HANDLED; | 590 | return IRQ_HANDLED; |
698 | } | 591 | } |
699 | 592 | ||
700 | static void sirfsoc_uart_rx_dma_complete_tl(unsigned long param) | ||
701 | { | ||
702 | struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)param; | ||
703 | struct uart_port *port = &sirfport->port; | ||
704 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | ||
705 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | ||
706 | unsigned long flags; | ||
707 | struct dma_tx_state tx_state; | ||
708 | spin_lock_irqsave(&port->lock, flags); | ||
709 | while (DMA_COMPLETE == dmaengine_tx_status(sirfport->rx_dma_chan, | ||
710 | sirfport->rx_dma_items[sirfport->rx_completed].cookie, &tx_state)) { | ||
711 | sirfsoc_uart_insert_rx_buf_to_tty(sirfport, | ||
712 | SIRFSOC_RX_DMA_BUF_SIZE); | ||
713 | if (rd_regl(port, ureg->sirfsoc_int_en_reg) & | ||
714 | uint_en->sirfsoc_rx_timeout_en) | ||
715 | sirfsoc_rx_submit_one_dma_desc(port, | ||
716 | sirfport->rx_completed++); | ||
717 | else | ||
718 | sirfport->rx_completed++; | ||
719 | sirfport->rx_completed %= SIRFSOC_RX_LOOP_BUF_CNT; | ||
720 | } | ||
721 | spin_unlock_irqrestore(&port->lock, flags); | ||
722 | tty_flip_buffer_push(&port->state->port); | ||
723 | } | ||
724 | |||
725 | static void sirfsoc_uart_rx_dma_complete_callback(void *param) | 593 | static void sirfsoc_uart_rx_dma_complete_callback(void *param) |
726 | { | 594 | { |
727 | struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)param; | ||
728 | unsigned long flags; | ||
729 | |||
730 | spin_lock_irqsave(&sirfport->port.lock, flags); | ||
731 | sirfport->rx_issued++; | ||
732 | sirfport->rx_issued %= SIRFSOC_RX_LOOP_BUF_CNT; | ||
733 | tasklet_schedule(&sirfport->rx_dma_complete_tasklet); | ||
734 | spin_unlock_irqrestore(&sirfport->port.lock, flags); | ||
735 | } | 595 | } |
736 | 596 | ||
737 | /* submit rx dma task into dmaengine */ | 597 | /* submit rx dma task into dmaengine */ |
@@ -740,21 +600,36 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port) | |||
740 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 600 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
741 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 601 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
742 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | 602 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; |
743 | int i; | ||
744 | sirfport->rx_io_count = 0; | 603 | sirfport->rx_io_count = 0; |
745 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | 604 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, |
746 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & | 605 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & |
747 | ~SIRFUART_IO_MODE); | 606 | ~SIRFUART_IO_MODE); |
748 | for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) | 607 | sirfport->rx_dma_items.xmit.tail = |
749 | sirfsoc_rx_submit_one_dma_desc(port, i); | 608 | sirfport->rx_dma_items.xmit.head = 0; |
750 | sirfport->rx_completed = sirfport->rx_issued = 0; | 609 | sirfport->rx_dma_items.desc = |
610 | dmaengine_prep_dma_cyclic(sirfport->rx_dma_chan, | ||
611 | sirfport->rx_dma_items.dma_addr, SIRFSOC_RX_DMA_BUF_SIZE, | ||
612 | SIRFSOC_RX_DMA_BUF_SIZE / 2, | ||
613 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); | ||
614 | if (IS_ERR_OR_NULL(sirfport->rx_dma_items.desc)) { | ||
615 | dev_err(port->dev, "DMA slave single fail\n"); | ||
616 | return; | ||
617 | } | ||
618 | sirfport->rx_dma_items.desc->callback = | ||
619 | sirfsoc_uart_rx_dma_complete_callback; | ||
620 | sirfport->rx_dma_items.desc->callback_param = sirfport; | ||
621 | sirfport->rx_dma_items.cookie = | ||
622 | dmaengine_submit(sirfport->rx_dma_items.desc); | ||
623 | dma_async_issue_pending(sirfport->rx_dma_chan); | ||
751 | if (!sirfport->is_atlas7) | 624 | if (!sirfport->is_atlas7) |
752 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 625 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
753 | rd_regl(port, ureg->sirfsoc_int_en_reg) | | 626 | rd_regl(port, ureg->sirfsoc_int_en_reg) | |
754 | SIRFUART_RX_DMA_INT_EN(port, uint_en)); | 627 | SIRFUART_RX_DMA_INT_EN(uint_en, |
628 | sirfport->uart_reg->uart_type)); | ||
755 | else | 629 | else |
756 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 630 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
757 | SIRFUART_RX_DMA_INT_EN(port, uint_en)); | 631 | SIRFUART_RX_DMA_INT_EN(uint_en, |
632 | sirfport->uart_reg->uart_type)); | ||
758 | } | 633 | } |
759 | 634 | ||
760 | static void sirfsoc_uart_start_rx(struct uart_port *port) | 635 | static void sirfsoc_uart_start_rx(struct uart_port *port) |
@@ -773,10 +648,12 @@ static void sirfsoc_uart_start_rx(struct uart_port *port) | |||
773 | if (!sirfport->is_atlas7) | 648 | if (!sirfport->is_atlas7) |
774 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 649 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
775 | rd_regl(port, ureg->sirfsoc_int_en_reg) | | 650 | rd_regl(port, ureg->sirfsoc_int_en_reg) | |
776 | SIRFUART_RX_IO_INT_EN(port, uint_en)); | 651 | SIRFUART_RX_IO_INT_EN(uint_en, |
652 | sirfport->uart_reg->uart_type)); | ||
777 | else | 653 | else |
778 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 654 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
779 | SIRFUART_RX_IO_INT_EN(port, uint_en)); | 655 | SIRFUART_RX_IO_INT_EN(uint_en, |
656 | sirfport->uart_reg->uart_type)); | ||
780 | } | 657 | } |
781 | } | 658 | } |
782 | 659 | ||
@@ -789,7 +666,7 @@ sirfsoc_usp_calc_sample_div(unsigned long set_rate, | |||
789 | unsigned long ioclk_div = 0; | 666 | unsigned long ioclk_div = 0; |
790 | unsigned long temp_delta; | 667 | unsigned long temp_delta; |
791 | 668 | ||
792 | for (sample_div = SIRF_MIN_SAMPLE_DIV; | 669 | for (sample_div = SIRF_USP_MIN_SAMPLE_DIV; |
793 | sample_div <= SIRF_MAX_SAMPLE_DIV; sample_div++) { | 670 | sample_div <= SIRF_MAX_SAMPLE_DIV; sample_div++) { |
794 | temp_delta = ioclk_rate - | 671 | temp_delta = ioclk_rate - |
795 | (ioclk_rate + (set_rate * sample_div) / 2) | 672 | (ioclk_rate + (set_rate * sample_div) / 2) |
@@ -910,10 +787,11 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
910 | config_reg |= SIRFUART_STICK_BIT_MARK; | 787 | config_reg |= SIRFUART_STICK_BIT_MARK; |
911 | else | 788 | else |
912 | config_reg |= SIRFUART_STICK_BIT_SPACE; | 789 | config_reg |= SIRFUART_STICK_BIT_SPACE; |
913 | } else if (termios->c_cflag & PARODD) { | ||
914 | config_reg |= SIRFUART_STICK_BIT_ODD; | ||
915 | } else { | 790 | } else { |
916 | config_reg |= SIRFUART_STICK_BIT_EVEN; | 791 | if (termios->c_cflag & PARODD) |
792 | config_reg |= SIRFUART_STICK_BIT_ODD; | ||
793 | else | ||
794 | config_reg |= SIRFUART_STICK_BIT_EVEN; | ||
917 | } | 795 | } |
918 | } | 796 | } |
919 | } else { | 797 | } else { |
@@ -976,7 +854,7 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
976 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, | 854 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, |
977 | (txfifo_op_reg & ~SIRFUART_FIFO_START)); | 855 | (txfifo_op_reg & ~SIRFUART_FIFO_START)); |
978 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { | 856 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { |
979 | config_reg |= SIRFUART_RECV_TIMEOUT(port, rx_time_out); | 857 | config_reg |= SIRFUART_UART_RECV_TIMEOUT(rx_time_out); |
980 | wr_regl(port, ureg->sirfsoc_line_ctrl, config_reg); | 858 | wr_regl(port, ureg->sirfsoc_line_ctrl, config_reg); |
981 | } else { | 859 | } else { |
982 | /*tx frame ctrl*/ | 860 | /*tx frame ctrl*/ |
@@ -999,7 +877,7 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
999 | wr_regl(port, ureg->sirfsoc_rx_frame_ctrl, len_val); | 877 | wr_regl(port, ureg->sirfsoc_rx_frame_ctrl, len_val); |
1000 | /*async param*/ | 878 | /*async param*/ |
1001 | wr_regl(port, ureg->sirfsoc_async_param_reg, | 879 | wr_regl(port, ureg->sirfsoc_async_param_reg, |
1002 | (SIRFUART_RECV_TIMEOUT(port, rx_time_out)) | | 880 | (SIRFUART_USP_RECV_TIMEOUT(rx_time_out)) | |
1003 | (sample_div_reg & SIRFSOC_USP_ASYNC_DIV2_MASK) << | 881 | (sample_div_reg & SIRFSOC_USP_ASYNC_DIV2_MASK) << |
1004 | SIRFSOC_USP_ASYNC_DIV2_OFFSET); | 882 | SIRFSOC_USP_ASYNC_DIV2_OFFSET); |
1005 | } | 883 | } |
@@ -1011,6 +889,7 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
1011 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_DMA_MODE); | 889 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_DMA_MODE); |
1012 | else | 890 | else |
1013 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_IO_MODE); | 891 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_IO_MODE); |
892 | sirfport->rx_period_time = 20000000; | ||
1014 | /* Reset Rx/Tx FIFO Threshold level for proper baudrate */ | 893 | /* Reset Rx/Tx FIFO Threshold level for proper baudrate */ |
1015 | if (set_baud < 1000000) | 894 | if (set_baud < 1000000) |
1016 | threshold_div = 1; | 895 | threshold_div = 1; |
@@ -1032,19 +911,10 @@ static void sirfsoc_uart_pm(struct uart_port *port, unsigned int state, | |||
1032 | unsigned int oldstate) | 911 | unsigned int oldstate) |
1033 | { | 912 | { |
1034 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 913 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
1035 | if (!state) { | 914 | if (!state) |
1036 | if (sirfport->is_bt_uart) { | ||
1037 | clk_prepare_enable(sirfport->clk_noc); | ||
1038 | clk_prepare_enable(sirfport->clk_general); | ||
1039 | } | ||
1040 | clk_prepare_enable(sirfport->clk); | 915 | clk_prepare_enable(sirfport->clk); |
1041 | } else { | 916 | else |
1042 | clk_disable_unprepare(sirfport->clk); | 917 | clk_disable_unprepare(sirfport->clk); |
1043 | if (sirfport->is_bt_uart) { | ||
1044 | clk_disable_unprepare(sirfport->clk_general); | ||
1045 | clk_disable_unprepare(sirfport->clk_noc); | ||
1046 | } | ||
1047 | } | ||
1048 | } | 918 | } |
1049 | 919 | ||
1050 | static int sirfsoc_uart_startup(struct uart_port *port) | 920 | static int sirfsoc_uart_startup(struct uart_port *port) |
@@ -1053,7 +923,7 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
1053 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 923 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
1054 | unsigned int index = port->line; | 924 | unsigned int index = port->line; |
1055 | int ret; | 925 | int ret; |
1056 | set_irq_flags(port->irq, IRQF_VALID | IRQF_NOAUTOEN); | 926 | irq_modify_status(port->irq, IRQ_NOREQUEST, IRQ_NOAUTOEN); |
1057 | ret = request_irq(port->irq, | 927 | ret = request_irq(port->irq, |
1058 | sirfsoc_uart_isr, | 928 | sirfsoc_uart_isr, |
1059 | 0, | 929 | 0, |
@@ -1064,7 +934,6 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
1064 | index, port->irq); | 934 | index, port->irq); |
1065 | goto irq_err; | 935 | goto irq_err; |
1066 | } | 936 | } |
1067 | |||
1068 | /* initial hardware settings */ | 937 | /* initial hardware settings */ |
1069 | wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, | 938 | wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, |
1070 | rd_regl(port, ureg->sirfsoc_tx_dma_io_ctrl) | | 939 | rd_regl(port, ureg->sirfsoc_tx_dma_io_ctrl) | |
@@ -1072,6 +941,9 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
1072 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | 941 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, |
1073 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | | 942 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | |
1074 | SIRFUART_IO_MODE); | 943 | SIRFUART_IO_MODE); |
944 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | ||
945 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & | ||
946 | ~SIRFUART_RX_DMA_FLUSH); | ||
1075 | wr_regl(port, ureg->sirfsoc_tx_dma_io_len, 0); | 947 | wr_regl(port, ureg->sirfsoc_tx_dma_io_len, 0); |
1076 | wr_regl(port, ureg->sirfsoc_rx_dma_io_len, 0); | 948 | wr_regl(port, ureg->sirfsoc_rx_dma_io_len, 0); |
1077 | wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_RX_EN | SIRFUART_TX_EN); | 949 | wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_RX_EN | SIRFUART_TX_EN); |
@@ -1080,7 +952,6 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
1080 | SIRFSOC_USP_ENDIAN_CTRL_LSBF | | 952 | SIRFSOC_USP_ENDIAN_CTRL_LSBF | |
1081 | SIRFSOC_USP_EN); | 953 | SIRFSOC_USP_EN); |
1082 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_RESET); | 954 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_RESET); |
1083 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, 0); | ||
1084 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); | 955 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); |
1085 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); | 956 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); |
1086 | wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, SIRFUART_FIFO_THD(port)); | 957 | wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, SIRFUART_FIFO_THD(port)); |
@@ -1100,8 +971,8 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
1100 | sirfport->ms_enabled = false; | 971 | sirfport->ms_enabled = false; |
1101 | if (sirfport->uart_reg->uart_type == SIRF_USP_UART && | 972 | if (sirfport->uart_reg->uart_type == SIRF_USP_UART && |
1102 | sirfport->hw_flow_ctrl) { | 973 | sirfport->hw_flow_ctrl) { |
1103 | set_irq_flags(gpio_to_irq(sirfport->cts_gpio), | 974 | irq_modify_status(gpio_to_irq(sirfport->cts_gpio), |
1104 | IRQF_VALID | IRQF_NOAUTOEN); | 975 | IRQ_NOREQUEST, IRQ_NOAUTOEN); |
1105 | ret = request_irq(gpio_to_irq(sirfport->cts_gpio), | 976 | ret = request_irq(gpio_to_irq(sirfport->cts_gpio), |
1106 | sirfsoc_uart_usp_cts_handler, IRQF_TRIGGER_FALLING | | 977 | sirfsoc_uart_usp_cts_handler, IRQF_TRIGGER_FALLING | |
1107 | IRQF_TRIGGER_RISING, "usp_cts_irq", sirfport); | 978 | IRQF_TRIGGER_RISING, "usp_cts_irq", sirfport); |
@@ -1110,8 +981,16 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
1110 | goto init_rx_err; | 981 | goto init_rx_err; |
1111 | } | 982 | } |
1112 | } | 983 | } |
1113 | |||
1114 | enable_irq(port->irq); | 984 | enable_irq(port->irq); |
985 | if (sirfport->rx_dma_chan && !sirfport->is_hrt_enabled) { | ||
986 | sirfport->is_hrt_enabled = true; | ||
987 | sirfport->rx_period_time = 20000000; | ||
988 | sirfport->rx_dma_items.xmit.tail = | ||
989 | sirfport->rx_dma_items.xmit.head = 0; | ||
990 | hrtimer_start(&sirfport->hrt, | ||
991 | ns_to_ktime(sirfport->rx_period_time), | ||
992 | HRTIMER_MODE_REL); | ||
993 | } | ||
1115 | 994 | ||
1116 | return 0; | 995 | return 0; |
1117 | init_rx_err: | 996 | init_rx_err: |
@@ -1127,7 +1006,7 @@ static void sirfsoc_uart_shutdown(struct uart_port *port) | |||
1127 | if (!sirfport->is_atlas7) | 1006 | if (!sirfport->is_atlas7) |
1128 | wr_regl(port, ureg->sirfsoc_int_en_reg, 0); | 1007 | wr_regl(port, ureg->sirfsoc_int_en_reg, 0); |
1129 | else | 1008 | else |
1130 | wr_regl(port, SIRFUART_INT_EN_CLR, ~0UL); | 1009 | wr_regl(port, ureg->sirfsoc_int_en_clr_reg, ~0UL); |
1131 | 1010 | ||
1132 | free_irq(port->irq, sirfport); | 1011 | free_irq(port->irq, sirfport); |
1133 | if (sirfport->ms_enabled) | 1012 | if (sirfport->ms_enabled) |
@@ -1139,6 +1018,13 @@ static void sirfsoc_uart_shutdown(struct uart_port *port) | |||
1139 | } | 1018 | } |
1140 | if (sirfport->tx_dma_chan) | 1019 | if (sirfport->tx_dma_chan) |
1141 | sirfport->tx_dma_state = TX_DMA_IDLE; | 1020 | sirfport->tx_dma_state = TX_DMA_IDLE; |
1021 | if (sirfport->rx_dma_chan && sirfport->is_hrt_enabled) { | ||
1022 | while ((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & | ||
1023 | SIRFUART_RX_FIFO_MASK) > 0) | ||
1024 | ; | ||
1025 | sirfport->is_hrt_enabled = false; | ||
1026 | hrtimer_cancel(&sirfport->hrt); | ||
1027 | } | ||
1142 | } | 1028 | } |
1143 | 1029 | ||
1144 | static const char *sirfsoc_uart_type(struct uart_port *port) | 1030 | static const char *sirfsoc_uart_type(struct uart_port *port) |
@@ -1196,27 +1082,29 @@ sirfsoc_uart_console_setup(struct console *co, char *options) | |||
1196 | unsigned int bits = 8; | 1082 | unsigned int bits = 8; |
1197 | unsigned int parity = 'n'; | 1083 | unsigned int parity = 'n'; |
1198 | unsigned int flow = 'n'; | 1084 | unsigned int flow = 'n'; |
1199 | struct uart_port *port = &sirfsoc_uart_ports[co->index].port; | 1085 | struct sirfsoc_uart_port *sirfport; |
1200 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 1086 | struct sirfsoc_register *ureg; |
1201 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | ||
1202 | if (co->index < 0 || co->index >= SIRFSOC_UART_NR) | 1087 | if (co->index < 0 || co->index >= SIRFSOC_UART_NR) |
1203 | return -EINVAL; | 1088 | co->index = 1; |
1204 | 1089 | sirfport = sirf_ports[co->index]; | |
1205 | if (!port->mapbase) | 1090 | if (!sirfport) |
1091 | return -ENODEV; | ||
1092 | ureg = &sirfport->uart_reg->uart_reg; | ||
1093 | if (!sirfport->port.mapbase) | ||
1206 | return -ENODEV; | 1094 | return -ENODEV; |
1207 | 1095 | ||
1208 | /* enable usp in mode1 register */ | 1096 | /* enable usp in mode1 register */ |
1209 | if (sirfport->uart_reg->uart_type == SIRF_USP_UART) | 1097 | if (sirfport->uart_reg->uart_type == SIRF_USP_UART) |
1210 | wr_regl(port, ureg->sirfsoc_mode1, SIRFSOC_USP_EN | | 1098 | wr_regl(&sirfport->port, ureg->sirfsoc_mode1, SIRFSOC_USP_EN | |
1211 | SIRFSOC_USP_ENDIAN_CTRL_LSBF); | 1099 | SIRFSOC_USP_ENDIAN_CTRL_LSBF); |
1212 | if (options) | 1100 | if (options) |
1213 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1101 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
1214 | port->cons = co; | 1102 | sirfport->port.cons = co; |
1215 | 1103 | ||
1216 | /* default console tx/rx transfer using io mode */ | 1104 | /* default console tx/rx transfer using io mode */ |
1217 | sirfport->rx_dma_chan = NULL; | 1105 | sirfport->rx_dma_chan = NULL; |
1218 | sirfport->tx_dma_chan = NULL; | 1106 | sirfport->tx_dma_chan = NULL; |
1219 | return uart_set_options(port, co, baud, parity, bits, flow); | 1107 | return uart_set_options(&sirfport->port, co, baud, parity, bits, flow); |
1220 | } | 1108 | } |
1221 | 1109 | ||
1222 | static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch) | 1110 | static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch) |
@@ -1224,8 +1112,8 @@ static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch) | |||
1224 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 1112 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
1225 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 1113 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
1226 | struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; | 1114 | struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; |
1227 | while (rd_regl(port, | 1115 | while (rd_regl(port, ureg->sirfsoc_tx_fifo_status) & |
1228 | ureg->sirfsoc_tx_fifo_status) & ufifo_st->ff_full(port->line)) | 1116 | ufifo_st->ff_full(port)) |
1229 | cpu_relax(); | 1117 | cpu_relax(); |
1230 | wr_regl(port, ureg->sirfsoc_tx_fifo_data, ch); | 1118 | wr_regl(port, ureg->sirfsoc_tx_fifo_data, ch); |
1231 | } | 1119 | } |
@@ -1233,8 +1121,10 @@ static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch) | |||
1233 | static void sirfsoc_uart_console_write(struct console *co, const char *s, | 1121 | static void sirfsoc_uart_console_write(struct console *co, const char *s, |
1234 | unsigned int count) | 1122 | unsigned int count) |
1235 | { | 1123 | { |
1236 | struct uart_port *port = &sirfsoc_uart_ports[co->index].port; | 1124 | struct sirfsoc_uart_port *sirfport = sirf_ports[co->index]; |
1237 | uart_console_write(port, s, count, sirfsoc_uart_console_putchar); | 1125 | |
1126 | uart_console_write(&sirfport->port, s, count, | ||
1127 | sirfsoc_uart_console_putchar); | ||
1238 | } | 1128 | } |
1239 | 1129 | ||
1240 | static struct console sirfsoc_uart_console = { | 1130 | static struct console sirfsoc_uart_console = { |
@@ -1269,10 +1159,75 @@ static struct uart_driver sirfsoc_uart_drv = { | |||
1269 | #endif | 1159 | #endif |
1270 | }; | 1160 | }; |
1271 | 1161 | ||
1272 | static const struct of_device_id sirfsoc_uart_ids[] = { | 1162 | static enum hrtimer_restart |
1163 | sirfsoc_uart_rx_dma_hrtimer_callback(struct hrtimer *hrt) | ||
1164 | { | ||
1165 | struct sirfsoc_uart_port *sirfport; | ||
1166 | struct uart_port *port; | ||
1167 | int count, inserted; | ||
1168 | struct dma_tx_state tx_state; | ||
1169 | struct tty_struct *tty; | ||
1170 | struct sirfsoc_register *ureg; | ||
1171 | struct circ_buf *xmit; | ||
1172 | |||
1173 | sirfport = container_of(hrt, struct sirfsoc_uart_port, hrt); | ||
1174 | port = &sirfport->port; | ||
1175 | inserted = 0; | ||
1176 | tty = port->state->port.tty; | ||
1177 | ureg = &sirfport->uart_reg->uart_reg; | ||
1178 | xmit = &sirfport->rx_dma_items.xmit; | ||
1179 | dmaengine_tx_status(sirfport->rx_dma_chan, | ||
1180 | sirfport->rx_dma_items.cookie, &tx_state); | ||
1181 | xmit->head = SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue; | ||
1182 | count = CIRC_CNT_TO_END(xmit->head, xmit->tail, | ||
1183 | SIRFSOC_RX_DMA_BUF_SIZE); | ||
1184 | while (count > 0) { | ||
1185 | inserted = tty_insert_flip_string(tty->port, | ||
1186 | (const unsigned char *)&xmit->buf[xmit->tail], count); | ||
1187 | if (!inserted) | ||
1188 | goto next_hrt; | ||
1189 | port->icount.rx += inserted; | ||
1190 | xmit->tail = (xmit->tail + inserted) & | ||
1191 | (SIRFSOC_RX_DMA_BUF_SIZE - 1); | ||
1192 | count = CIRC_CNT_TO_END(xmit->head, xmit->tail, | ||
1193 | SIRFSOC_RX_DMA_BUF_SIZE); | ||
1194 | tty_flip_buffer_push(tty->port); | ||
1195 | } | ||
1196 | /* | ||
1197 | * if RX DMA buffer data have all push into tty buffer, and there is | ||
1198 | * only little data(less than a dma transfer unit) left in rxfifo, | ||
1199 | * fetch it out in pio mode and switch back to dma immediately | ||
1200 | */ | ||
1201 | if (!inserted && !count && | ||
1202 | ((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & | ||
1203 | SIRFUART_RX_FIFO_MASK) > 0)) { | ||
1204 | /* switch to pio mode */ | ||
1205 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | ||
1206 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | | ||
1207 | SIRFUART_IO_MODE); | ||
1208 | while ((rd_regl(port, ureg->sirfsoc_rx_fifo_status) & | ||
1209 | SIRFUART_RX_FIFO_MASK) > 0) { | ||
1210 | if (sirfsoc_uart_pio_rx_chars(port, 16) > 0) | ||
1211 | tty_flip_buffer_push(tty->port); | ||
1212 | } | ||
1213 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); | ||
1214 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); | ||
1215 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); | ||
1216 | /* switch back to dma mode */ | ||
1217 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | ||
1218 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & | ||
1219 | ~SIRFUART_IO_MODE); | ||
1220 | } | ||
1221 | next_hrt: | ||
1222 | hrtimer_forward_now(hrt, ns_to_ktime(sirfport->rx_period_time)); | ||
1223 | return HRTIMER_RESTART; | ||
1224 | } | ||
1225 | |||
1226 | static struct of_device_id sirfsoc_uart_ids[] = { | ||
1273 | { .compatible = "sirf,prima2-uart", .data = &sirfsoc_uart,}, | 1227 | { .compatible = "sirf,prima2-uart", .data = &sirfsoc_uart,}, |
1274 | { .compatible = "sirf,atlas7-uart", .data = &sirfsoc_uart}, | 1228 | { .compatible = "sirf,atlas7-uart", .data = &sirfsoc_uart}, |
1275 | { .compatible = "sirf,prima2-usp-uart", .data = &sirfsoc_usp}, | 1229 | { .compatible = "sirf,prima2-usp-uart", .data = &sirfsoc_usp}, |
1230 | { .compatible = "sirf,atlas7-usp-uart", .data = &sirfsoc_usp}, | ||
1276 | {} | 1231 | {} |
1277 | }; | 1232 | }; |
1278 | MODULE_DEVICE_TABLE(of, sirfsoc_uart_ids); | 1233 | MODULE_DEVICE_TABLE(of, sirfsoc_uart_ids); |
@@ -1283,7 +1238,6 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
1283 | struct uart_port *port; | 1238 | struct uart_port *port; |
1284 | struct resource *res; | 1239 | struct resource *res; |
1285 | int ret; | 1240 | int ret; |
1286 | int i, j; | ||
1287 | struct dma_slave_config slv_cfg = { | 1241 | struct dma_slave_config slv_cfg = { |
1288 | .src_maxburst = 2, | 1242 | .src_maxburst = 2, |
1289 | }; | 1243 | }; |
@@ -1293,16 +1247,15 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
1293 | const struct of_device_id *match; | 1247 | const struct of_device_id *match; |
1294 | 1248 | ||
1295 | match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node); | 1249 | match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node); |
1296 | if (of_property_read_u32(pdev->dev.of_node, "cell-index", &pdev->id)) { | 1250 | sirfport = devm_kzalloc(&pdev->dev, sizeof(*sirfport), GFP_KERNEL); |
1297 | dev_err(&pdev->dev, | 1251 | if (!sirfport) { |
1298 | "Unable to find cell-index in uart node.\n"); | 1252 | ret = -ENOMEM; |
1299 | ret = -EFAULT; | ||
1300 | goto err; | 1253 | goto err; |
1301 | } | 1254 | } |
1302 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) | 1255 | sirfport->port.line = of_alias_get_id(pdev->dev.of_node, "serial"); |
1303 | pdev->id += ((struct sirfsoc_uart_register *) | 1256 | sirf_ports[sirfport->port.line] = sirfport; |
1304 | match->data)->uart_param.register_uart_nr; | 1257 | sirfport->port.iotype = UPIO_MEM; |
1305 | sirfport = &sirfsoc_uart_ports[pdev->id]; | 1258 | sirfport->port.flags = UPF_BOOT_AUTOCONF; |
1306 | port = &sirfport->port; | 1259 | port = &sirfport->port; |
1307 | port->dev = &pdev->dev; | 1260 | port->dev = &pdev->dev; |
1308 | port->private_data = sirfport; | 1261 | port->private_data = sirfport; |
@@ -1310,9 +1263,12 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
1310 | 1263 | ||
1311 | sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node, | 1264 | sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node, |
1312 | "sirf,uart-has-rtscts"); | 1265 | "sirf,uart-has-rtscts"); |
1313 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart")) | 1266 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart") || |
1267 | of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart")) | ||
1314 | sirfport->uart_reg->uart_type = SIRF_REAL_UART; | 1268 | sirfport->uart_reg->uart_type = SIRF_REAL_UART; |
1315 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) { | 1269 | if (of_device_is_compatible(pdev->dev.of_node, |
1270 | "sirf,prima2-usp-uart") || of_device_is_compatible( | ||
1271 | pdev->dev.of_node, "sirf,atlas7-usp-uart")) { | ||
1316 | sirfport->uart_reg->uart_type = SIRF_USP_UART; | 1272 | sirfport->uart_reg->uart_type = SIRF_USP_UART; |
1317 | if (!sirfport->hw_flow_ctrl) | 1273 | if (!sirfport->hw_flow_ctrl) |
1318 | goto usp_no_flow_control; | 1274 | goto usp_no_flow_control; |
@@ -1350,7 +1306,8 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
1350 | gpio_direction_output(sirfport->rts_gpio, 1); | 1306 | gpio_direction_output(sirfport->rts_gpio, 1); |
1351 | } | 1307 | } |
1352 | usp_no_flow_control: | 1308 | usp_no_flow_control: |
1353 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart")) | 1309 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart") || |
1310 | of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-usp-uart")) | ||
1354 | sirfport->is_atlas7 = true; | 1311 | sirfport->is_atlas7 = true; |
1355 | 1312 | ||
1356 | if (of_property_read_u32(pdev->dev.of_node, | 1313 | if (of_property_read_u32(pdev->dev.of_node, |
@@ -1368,12 +1325,9 @@ usp_no_flow_control: | |||
1368 | ret = -EFAULT; | 1325 | ret = -EFAULT; |
1369 | goto err; | 1326 | goto err; |
1370 | } | 1327 | } |
1371 | tasklet_init(&sirfport->rx_dma_complete_tasklet, | ||
1372 | sirfsoc_uart_rx_dma_complete_tl, (unsigned long)sirfport); | ||
1373 | tasklet_init(&sirfport->rx_tmo_process_tasklet, | ||
1374 | sirfsoc_rx_tmo_process_tl, (unsigned long)sirfport); | ||
1375 | port->mapbase = res->start; | 1328 | port->mapbase = res->start; |
1376 | port->membase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | 1329 | port->membase = devm_ioremap(&pdev->dev, |
1330 | res->start, resource_size(res)); | ||
1377 | if (!port->membase) { | 1331 | if (!port->membase) { |
1378 | dev_err(&pdev->dev, "Cannot remap resource.\n"); | 1332 | dev_err(&pdev->dev, "Cannot remap resource.\n"); |
1379 | ret = -ENOMEM; | 1333 | ret = -ENOMEM; |
@@ -1393,20 +1347,6 @@ usp_no_flow_control: | |||
1393 | goto err; | 1347 | goto err; |
1394 | } | 1348 | } |
1395 | port->uartclk = clk_get_rate(sirfport->clk); | 1349 | port->uartclk = clk_get_rate(sirfport->clk); |
1396 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-bt-uart")) { | ||
1397 | sirfport->clk_general = devm_clk_get(&pdev->dev, "general"); | ||
1398 | if (IS_ERR(sirfport->clk_general)) { | ||
1399 | ret = PTR_ERR(sirfport->clk_general); | ||
1400 | goto err; | ||
1401 | } | ||
1402 | sirfport->clk_noc = devm_clk_get(&pdev->dev, "noc"); | ||
1403 | if (IS_ERR(sirfport->clk_noc)) { | ||
1404 | ret = PTR_ERR(sirfport->clk_noc); | ||
1405 | goto err; | ||
1406 | } | ||
1407 | sirfport->is_bt_uart = true; | ||
1408 | } else | ||
1409 | sirfport->is_bt_uart = false; | ||
1410 | 1350 | ||
1411 | port->ops = &sirfsoc_uart_ops; | 1351 | port->ops = &sirfsoc_uart_ops; |
1412 | spin_lock_init(&port->lock); | 1352 | spin_lock_init(&port->lock); |
@@ -1419,30 +1359,32 @@ usp_no_flow_control: | |||
1419 | } | 1359 | } |
1420 | 1360 | ||
1421 | sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx"); | 1361 | sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx"); |
1422 | for (i = 0; sirfport->rx_dma_chan && i < SIRFSOC_RX_LOOP_BUF_CNT; i++) { | 1362 | sirfport->rx_dma_items.xmit.buf = |
1423 | sirfport->rx_dma_items[i].xmit.buf = | 1363 | dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, |
1424 | dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | 1364 | &sirfport->rx_dma_items.dma_addr, GFP_KERNEL); |
1425 | &sirfport->rx_dma_items[i].dma_addr, GFP_KERNEL); | 1365 | if (!sirfport->rx_dma_items.xmit.buf) { |
1426 | if (!sirfport->rx_dma_items[i].xmit.buf) { | 1366 | dev_err(port->dev, "Uart alloc bufa failed\n"); |
1427 | dev_err(port->dev, "Uart alloc bufa failed\n"); | 1367 | ret = -ENOMEM; |
1428 | ret = -ENOMEM; | 1368 | goto alloc_coherent_err; |
1429 | goto alloc_coherent_err; | ||
1430 | } | ||
1431 | sirfport->rx_dma_items[i].xmit.head = | ||
1432 | sirfport->rx_dma_items[i].xmit.tail = 0; | ||
1433 | } | 1369 | } |
1370 | sirfport->rx_dma_items.xmit.head = | ||
1371 | sirfport->rx_dma_items.xmit.tail = 0; | ||
1434 | if (sirfport->rx_dma_chan) | 1372 | if (sirfport->rx_dma_chan) |
1435 | dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg); | 1373 | dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg); |
1436 | sirfport->tx_dma_chan = dma_request_slave_channel(port->dev, "tx"); | 1374 | sirfport->tx_dma_chan = dma_request_slave_channel(port->dev, "tx"); |
1437 | if (sirfport->tx_dma_chan) | 1375 | if (sirfport->tx_dma_chan) |
1438 | dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg); | 1376 | dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg); |
1377 | if (sirfport->rx_dma_chan) { | ||
1378 | hrtimer_init(&sirfport->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
1379 | sirfport->hrt.function = sirfsoc_uart_rx_dma_hrtimer_callback; | ||
1380 | sirfport->is_hrt_enabled = false; | ||
1381 | } | ||
1439 | 1382 | ||
1440 | return 0; | 1383 | return 0; |
1441 | alloc_coherent_err: | 1384 | alloc_coherent_err: |
1442 | for (j = 0; j < i; j++) | 1385 | dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, |
1443 | dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | 1386 | sirfport->rx_dma_items.xmit.buf, |
1444 | sirfport->rx_dma_items[j].xmit.buf, | 1387 | sirfport->rx_dma_items.dma_addr); |
1445 | sirfport->rx_dma_items[j].dma_addr); | ||
1446 | dma_release_channel(sirfport->rx_dma_chan); | 1388 | dma_release_channel(sirfport->rx_dma_chan); |
1447 | err: | 1389 | err: |
1448 | return ret; | 1390 | return ret; |
@@ -1454,13 +1396,11 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) | |||
1454 | struct uart_port *port = &sirfport->port; | 1396 | struct uart_port *port = &sirfport->port; |
1455 | uart_remove_one_port(&sirfsoc_uart_drv, port); | 1397 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
1456 | if (sirfport->rx_dma_chan) { | 1398 | if (sirfport->rx_dma_chan) { |
1457 | int i; | ||
1458 | dmaengine_terminate_all(sirfport->rx_dma_chan); | 1399 | dmaengine_terminate_all(sirfport->rx_dma_chan); |
1459 | dma_release_channel(sirfport->rx_dma_chan); | 1400 | dma_release_channel(sirfport->rx_dma_chan); |
1460 | for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) | 1401 | dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, |
1461 | dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | 1402 | sirfport->rx_dma_items.xmit.buf, |
1462 | sirfport->rx_dma_items[i].xmit.buf, | 1403 | sirfport->rx_dma_items.dma_addr); |
1463 | sirfport->rx_dma_items[i].dma_addr); | ||
1464 | } | 1404 | } |
1465 | if (sirfport->tx_dma_chan) { | 1405 | if (sirfport->tx_dma_chan) { |
1466 | dmaengine_terminate_all(sirfport->tx_dma_chan); | 1406 | dmaengine_terminate_all(sirfport->tx_dma_chan); |
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 727eb6b88fff..eb162b012eec 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -6,11 +6,11 @@ | |||
6 | * Licensed under GPLv2 or later. | 6 | * Licensed under GPLv2 or later. |
7 | */ | 7 | */ |
8 | #include <linux/bitops.h> | 8 | #include <linux/bitops.h> |
9 | #include <linux/log2.h> | ||
10 | #include <linux/hrtimer.h> | ||
9 | struct sirfsoc_uart_param { | 11 | struct sirfsoc_uart_param { |
10 | const char *uart_name; | 12 | const char *uart_name; |
11 | const char *port_name; | 13 | const char *port_name; |
12 | u32 uart_nr; | ||
13 | u32 register_uart_nr; | ||
14 | }; | 14 | }; |
15 | 15 | ||
16 | struct sirfsoc_register { | 16 | struct sirfsoc_register { |
@@ -21,6 +21,7 @@ struct sirfsoc_register { | |||
21 | u32 sirfsoc_tx_rx_en; | 21 | u32 sirfsoc_tx_rx_en; |
22 | u32 sirfsoc_int_en_reg; | 22 | u32 sirfsoc_int_en_reg; |
23 | u32 sirfsoc_int_st_reg; | 23 | u32 sirfsoc_int_st_reg; |
24 | u32 sirfsoc_int_en_clr_reg; | ||
24 | u32 sirfsoc_tx_dma_io_ctrl; | 25 | u32 sirfsoc_tx_dma_io_ctrl; |
25 | u32 sirfsoc_tx_dma_io_len; | 26 | u32 sirfsoc_tx_dma_io_len; |
26 | u32 sirfsoc_tx_fifo_ctrl; | 27 | u32 sirfsoc_tx_fifo_ctrl; |
@@ -45,8 +46,8 @@ struct sirfsoc_register { | |||
45 | u32 sirfsoc_async_param_reg; | 46 | u32 sirfsoc_async_param_reg; |
46 | }; | 47 | }; |
47 | 48 | ||
48 | typedef u32 (*fifo_full_mask)(int line); | 49 | typedef u32 (*fifo_full_mask)(struct uart_port *port); |
49 | typedef u32 (*fifo_empty_mask)(int line); | 50 | typedef u32 (*fifo_empty_mask)(struct uart_port *port); |
50 | 51 | ||
51 | struct sirfsoc_fifo_status { | 52 | struct sirfsoc_fifo_status { |
52 | fifo_full_mask ff_full; | 53 | fifo_full_mask ff_full; |
@@ -105,21 +106,20 @@ struct sirfsoc_uart_register { | |||
105 | enum sirfsoc_uart_type uart_type; | 106 | enum sirfsoc_uart_type uart_type; |
106 | }; | 107 | }; |
107 | 108 | ||
108 | u32 usp_ff_full(int line) | 109 | u32 uart_usp_ff_full_mask(struct uart_port *port) |
109 | { | 110 | { |
110 | return 0x80; | 111 | u32 full_bit; |
111 | } | 112 | |
112 | u32 usp_ff_empty(int line) | 113 | full_bit = ilog2(port->fifosize); |
113 | { | 114 | return (1 << full_bit); |
114 | return 0x100; | ||
115 | } | ||
116 | u32 uart_ff_full(int line) | ||
117 | { | ||
118 | return (line == 1) ? (0x20) : (0x80); | ||
119 | } | 115 | } |
120 | u32 uart_ff_empty(int line) | 116 | |
117 | u32 uart_usp_ff_empty_mask(struct uart_port *port) | ||
121 | { | 118 | { |
122 | return (line == 1) ? (0x40) : (0x100); | 119 | u32 empty_bit; |
120 | |||
121 | empty_bit = ilog2(port->fifosize) + 1; | ||
122 | return (1 << empty_bit); | ||
123 | } | 123 | } |
124 | struct sirfsoc_uart_register sirfsoc_usp = { | 124 | struct sirfsoc_uart_register sirfsoc_usp = { |
125 | .uart_reg = { | 125 | .uart_reg = { |
@@ -145,6 +145,7 @@ struct sirfsoc_uart_register sirfsoc_usp = { | |||
145 | .sirfsoc_rx_fifo_op = 0x0130, | 145 | .sirfsoc_rx_fifo_op = 0x0130, |
146 | .sirfsoc_rx_fifo_status = 0x0134, | 146 | .sirfsoc_rx_fifo_status = 0x0134, |
147 | .sirfsoc_rx_fifo_data = 0x0138, | 147 | .sirfsoc_rx_fifo_data = 0x0138, |
148 | .sirfsoc_int_en_clr_reg = 0x140, | ||
148 | }, | 149 | }, |
149 | .uart_int_en = { | 150 | .uart_int_en = { |
150 | .sirfsoc_rx_done_en = BIT(0), | 151 | .sirfsoc_rx_done_en = BIT(0), |
@@ -177,14 +178,12 @@ struct sirfsoc_uart_register sirfsoc_usp = { | |||
177 | .sirfsoc_rxd_brk = BIT(15), | 178 | .sirfsoc_rxd_brk = BIT(15), |
178 | }, | 179 | }, |
179 | .fifo_status = { | 180 | .fifo_status = { |
180 | .ff_full = usp_ff_full, | 181 | .ff_full = uart_usp_ff_full_mask, |
181 | .ff_empty = usp_ff_empty, | 182 | .ff_empty = uart_usp_ff_empty_mask, |
182 | }, | 183 | }, |
183 | .uart_param = { | 184 | .uart_param = { |
184 | .uart_name = "ttySiRF", | 185 | .uart_name = "ttySiRF", |
185 | .port_name = "sirfsoc-uart", | 186 | .port_name = "sirfsoc-uart", |
186 | .uart_nr = 2, | ||
187 | .register_uart_nr = 3, | ||
188 | }, | 187 | }, |
189 | }; | 188 | }; |
190 | 189 | ||
@@ -195,6 +194,7 @@ struct sirfsoc_uart_register sirfsoc_uart = { | |||
195 | .sirfsoc_divisor = 0x0050, | 194 | .sirfsoc_divisor = 0x0050, |
196 | .sirfsoc_int_en_reg = 0x0054, | 195 | .sirfsoc_int_en_reg = 0x0054, |
197 | .sirfsoc_int_st_reg = 0x0058, | 196 | .sirfsoc_int_st_reg = 0x0058, |
197 | .sirfsoc_int_en_clr_reg = 0x0060, | ||
198 | .sirfsoc_tx_dma_io_ctrl = 0x0100, | 198 | .sirfsoc_tx_dma_io_ctrl = 0x0100, |
199 | .sirfsoc_tx_dma_io_len = 0x0104, | 199 | .sirfsoc_tx_dma_io_len = 0x0104, |
200 | .sirfsoc_tx_fifo_ctrl = 0x0108, | 200 | .sirfsoc_tx_fifo_ctrl = 0x0108, |
@@ -249,14 +249,12 @@ struct sirfsoc_uart_register sirfsoc_uart = { | |||
249 | .sirfsoc_rts = BIT(15), | 249 | .sirfsoc_rts = BIT(15), |
250 | }, | 250 | }, |
251 | .fifo_status = { | 251 | .fifo_status = { |
252 | .ff_full = uart_ff_full, | 252 | .ff_full = uart_usp_ff_full_mask, |
253 | .ff_empty = uart_ff_empty, | 253 | .ff_empty = uart_usp_ff_empty_mask, |
254 | }, | 254 | }, |
255 | .uart_param = { | 255 | .uart_param = { |
256 | .uart_name = "ttySiRF", | 256 | .uart_name = "ttySiRF", |
257 | .port_name = "sirfsoc_uart", | 257 | .port_name = "sirfsoc_uart", |
258 | .uart_nr = 3, | ||
259 | .register_uart_nr = 0, | ||
260 | }, | 258 | }, |
261 | }; | 259 | }; |
262 | /* uart io ctrl */ | 260 | /* uart io ctrl */ |
@@ -296,10 +294,10 @@ struct sirfsoc_uart_register sirfsoc_uart = { | |||
296 | 294 | ||
297 | #define SIRFUART_IO_MODE BIT(0) | 295 | #define SIRFUART_IO_MODE BIT(0) |
298 | #define SIRFUART_DMA_MODE 0x0 | 296 | #define SIRFUART_DMA_MODE 0x0 |
297 | #define SIRFUART_RX_DMA_FLUSH 0x4 | ||
299 | 298 | ||
300 | /* Macro Specific*/ | ||
301 | #define SIRFUART_INT_EN_CLR 0x0060 | ||
302 | /* Baud Rate Calculation */ | 299 | /* Baud Rate Calculation */ |
300 | #define SIRF_USP_MIN_SAMPLE_DIV 0x1 | ||
303 | #define SIRF_MIN_SAMPLE_DIV 0xf | 301 | #define SIRF_MIN_SAMPLE_DIV 0xf |
304 | #define SIRF_MAX_SAMPLE_DIV 0x3f | 302 | #define SIRF_MAX_SAMPLE_DIV 0x3f |
305 | #define SIRF_IOCLK_DIV_MAX 0xffff | 303 | #define SIRF_IOCLK_DIV_MAX 0xffff |
@@ -326,55 +324,54 @@ struct sirfsoc_uart_register sirfsoc_uart = { | |||
326 | #define SIRFSOC_USP_RX_CLK_DIVISOR_OFFSET 24 | 324 | #define SIRFSOC_USP_RX_CLK_DIVISOR_OFFSET 24 |
327 | #define SIRFSOC_USP_ASYNC_DIV2_MASK 0x3f | 325 | #define SIRFSOC_USP_ASYNC_DIV2_MASK 0x3f |
328 | #define SIRFSOC_USP_ASYNC_DIV2_OFFSET 16 | 326 | #define SIRFSOC_USP_ASYNC_DIV2_OFFSET 16 |
329 | 327 | #define SIRFSOC_USP_LOOP_BACK_CTRL BIT(2) | |
330 | /* USP-UART Common */ | 328 | /* USP-UART Common */ |
331 | #define SIRFSOC_UART_RX_TIMEOUT(br, to) (((br) * (((to) + 999) / 1000)) / 1000) | 329 | #define SIRFSOC_UART_RX_TIMEOUT(br, to) (((br) * (((to) + 999) / 1000)) / 1000) |
332 | #define SIRFUART_RECV_TIMEOUT_VALUE(x) \ | 330 | #define SIRFUART_RECV_TIMEOUT_VALUE(x) \ |
333 | (((x) > 0xFFFF) ? 0xFFFF : ((x) & 0xFFFF)) | 331 | (((x) > 0xFFFF) ? 0xFFFF : ((x) & 0xFFFF)) |
334 | #define SIRFUART_RECV_TIMEOUT(port, x) \ | 332 | #define SIRFUART_USP_RECV_TIMEOUT(x) (x & 0xFFFF) |
335 | (((port)->line > 2) ? (x & 0xFFFF) : ((x) & 0xFFFF) << 16) | 333 | #define SIRFUART_UART_RECV_TIMEOUT(x) ((x & 0xFFFF) << 16) |
336 | 334 | ||
337 | #define SIRFUART_FIFO_THD(port) ((port->line) == 1 ? 16 : 64) | 335 | #define SIRFUART_FIFO_THD(port) (port->fifosize >> 1) |
338 | #define SIRFUART_ERR_INT_STAT(port, unit_st) \ | 336 | #define SIRFUART_ERR_INT_STAT(unit_st, uart_type) \ |
339 | (uint_st->sirfsoc_rx_oflow | \ | 337 | (uint_st->sirfsoc_rx_oflow | \ |
340 | uint_st->sirfsoc_frm_err | \ | 338 | uint_st->sirfsoc_frm_err | \ |
341 | uint_st->sirfsoc_rxd_brk | \ | 339 | uint_st->sirfsoc_rxd_brk | \ |
342 | ((port->line > 2) ? 0 : uint_st->sirfsoc_parity_err)) | 340 | ((uart_type != SIRF_REAL_UART) ? \ |
343 | #define SIRFUART_RX_IO_INT_EN(port, uint_en) \ | 341 | 0 : uint_st->sirfsoc_parity_err)) |
344 | (uint_en->sirfsoc_rx_timeout_en |\ | 342 | #define SIRFUART_RX_IO_INT_EN(uint_en, uart_type) \ |
343 | (uint_en->sirfsoc_rx_done_en |\ | ||
345 | uint_en->sirfsoc_rxfifo_thd_en |\ | 344 | uint_en->sirfsoc_rxfifo_thd_en |\ |
346 | uint_en->sirfsoc_rxfifo_full_en |\ | 345 | uint_en->sirfsoc_rxfifo_full_en |\ |
347 | uint_en->sirfsoc_frm_err_en |\ | 346 | uint_en->sirfsoc_frm_err_en |\ |
348 | uint_en->sirfsoc_rx_oflow_en |\ | 347 | uint_en->sirfsoc_rx_oflow_en |\ |
349 | uint_en->sirfsoc_rxd_brk_en |\ | 348 | uint_en->sirfsoc_rxd_brk_en |\ |
350 | ((port->line > 2) ? 0 : uint_en->sirfsoc_parity_err_en)) | 349 | ((uart_type != SIRF_REAL_UART) ? \ |
350 | 0 : uint_en->sirfsoc_parity_err_en)) | ||
351 | #define SIRFUART_RX_IO_INT_ST(uint_st) \ | 351 | #define SIRFUART_RX_IO_INT_ST(uint_st) \ |
352 | (uint_st->sirfsoc_rx_timeout |\ | 352 | (uint_st->sirfsoc_rxfifo_thd |\ |
353 | uint_st->sirfsoc_rxfifo_thd |\ | 353 | uint_st->sirfsoc_rxfifo_full|\ |
354 | uint_st->sirfsoc_rxfifo_full) | 354 | uint_st->sirfsoc_rx_done |\ |
355 | uint_st->sirfsoc_rx_timeout) | ||
355 | #define SIRFUART_CTS_INT_ST(uint_st) (uint_st->sirfsoc_cts) | 356 | #define SIRFUART_CTS_INT_ST(uint_st) (uint_st->sirfsoc_cts) |
356 | #define SIRFUART_RX_DMA_INT_EN(port, uint_en) \ | 357 | #define SIRFUART_RX_DMA_INT_EN(uint_en, uart_type) \ |
357 | (uint_en->sirfsoc_rx_timeout_en |\ | 358 | (uint_en->sirfsoc_frm_err_en |\ |
358 | uint_en->sirfsoc_frm_err_en |\ | ||
359 | uint_en->sirfsoc_rx_oflow_en |\ | 359 | uint_en->sirfsoc_rx_oflow_en |\ |
360 | uint_en->sirfsoc_rxd_brk_en |\ | 360 | uint_en->sirfsoc_rxd_brk_en |\ |
361 | ((port->line > 2) ? 0 : uint_en->sirfsoc_parity_err_en)) | 361 | ((uart_type != SIRF_REAL_UART) ? \ |
362 | 0 : uint_en->sirfsoc_parity_err_en)) | ||
362 | /* Generic Definitions */ | 363 | /* Generic Definitions */ |
363 | #define SIRFSOC_UART_NAME "ttySiRF" | 364 | #define SIRFSOC_UART_NAME "ttySiRF" |
364 | #define SIRFSOC_UART_MAJOR 0 | 365 | #define SIRFSOC_UART_MAJOR 0 |
365 | #define SIRFSOC_UART_MINOR 0 | 366 | #define SIRFSOC_UART_MINOR 0 |
366 | #define SIRFUART_PORT_NAME "sirfsoc-uart" | 367 | #define SIRFUART_PORT_NAME "sirfsoc-uart" |
367 | #define SIRFUART_MAP_SIZE 0x200 | 368 | #define SIRFUART_MAP_SIZE 0x200 |
368 | #define SIRFSOC_UART_NR 6 | 369 | #define SIRFSOC_UART_NR 11 |
369 | #define SIRFSOC_PORT_TYPE 0xa5 | 370 | #define SIRFSOC_PORT_TYPE 0xa5 |
370 | 371 | ||
371 | /* Uart Common Use Macro*/ | 372 | /* Uart Common Use Macro*/ |
372 | #define SIRFSOC_RX_DMA_BUF_SIZE 256 | 373 | #define SIRFSOC_RX_DMA_BUF_SIZE (1024 * 32) |
373 | #define BYTES_TO_ALIGN(dma_addr) ((unsigned long)(dma_addr) & 0x3) | 374 | #define BYTES_TO_ALIGN(dma_addr) ((unsigned long)(dma_addr) & 0x3) |
374 | #define LOOP_DMA_BUFA_FILL 1 | ||
375 | #define LOOP_DMA_BUFB_FILL 2 | ||
376 | #define TX_TRAN_PIO 1 | ||
377 | #define TX_TRAN_DMA 2 | ||
378 | /* Uart Fifo Level Chk */ | 375 | /* Uart Fifo Level Chk */ |
379 | #define SIRFUART_TX_FIFO_SC_OFFSET 0 | 376 | #define SIRFUART_TX_FIFO_SC_OFFSET 0 |
380 | #define SIRFUART_TX_FIFO_LC_OFFSET 10 | 377 | #define SIRFUART_TX_FIFO_LC_OFFSET 10 |
@@ -389,8 +386,8 @@ struct sirfsoc_uart_register sirfsoc_uart = { | |||
389 | #define SIRFUART_RX_FIFO_CHK_SC SIRFUART_TX_FIFO_CHK_SC | 386 | #define SIRFUART_RX_FIFO_CHK_SC SIRFUART_TX_FIFO_CHK_SC |
390 | #define SIRFUART_RX_FIFO_CHK_LC SIRFUART_TX_FIFO_CHK_LC | 387 | #define SIRFUART_RX_FIFO_CHK_LC SIRFUART_TX_FIFO_CHK_LC |
391 | #define SIRFUART_RX_FIFO_CHK_HC SIRFUART_TX_FIFO_CHK_HC | 388 | #define SIRFUART_RX_FIFO_CHK_HC SIRFUART_TX_FIFO_CHK_HC |
389 | #define SIRFUART_RX_FIFO_MASK 0x7f | ||
392 | /* Indicate how many buffers used */ | 390 | /* Indicate how many buffers used */ |
393 | #define SIRFSOC_RX_LOOP_BUF_CNT 2 | ||
394 | 391 | ||
395 | /* For Fast Baud Rate Calculation */ | 392 | /* For Fast Baud Rate Calculation */ |
396 | struct sirfsoc_baudrate_to_regv { | 393 | struct sirfsoc_baudrate_to_regv { |
@@ -404,7 +401,7 @@ enum sirfsoc_tx_state { | |||
404 | TX_DMA_PAUSE, | 401 | TX_DMA_PAUSE, |
405 | }; | 402 | }; |
406 | 403 | ||
407 | struct sirfsoc_loop_buffer { | 404 | struct sirfsoc_rx_buffer { |
408 | struct circ_buf xmit; | 405 | struct circ_buf xmit; |
409 | dma_cookie_t cookie; | 406 | dma_cookie_t cookie; |
410 | struct dma_async_tx_descriptor *desc; | 407 | struct dma_async_tx_descriptor *desc; |
@@ -417,10 +414,6 @@ struct sirfsoc_uart_port { | |||
417 | 414 | ||
418 | struct uart_port port; | 415 | struct uart_port port; |
419 | struct clk *clk; | 416 | struct clk *clk; |
420 | /* UART6 for BT usage in A7DA platform need multi-clock source */ | ||
421 | bool is_bt_uart; | ||
422 | struct clk *clk_general; | ||
423 | struct clk *clk_noc; | ||
424 | /* for SiRFatlas7, there are SET/CLR for UART_INT_EN */ | 417 | /* for SiRFatlas7, there are SET/CLR for UART_INT_EN */ |
425 | bool is_atlas7; | 418 | bool is_atlas7; |
426 | struct sirfsoc_uart_register *uart_reg; | 419 | struct sirfsoc_uart_register *uart_reg; |
@@ -428,17 +421,16 @@ struct sirfsoc_uart_port { | |||
428 | struct dma_chan *tx_dma_chan; | 421 | struct dma_chan *tx_dma_chan; |
429 | dma_addr_t tx_dma_addr; | 422 | dma_addr_t tx_dma_addr; |
430 | struct dma_async_tx_descriptor *tx_dma_desc; | 423 | struct dma_async_tx_descriptor *tx_dma_desc; |
431 | struct tasklet_struct rx_dma_complete_tasklet; | ||
432 | struct tasklet_struct rx_tmo_process_tasklet; | ||
433 | unsigned int rx_io_count; | 424 | unsigned int rx_io_count; |
434 | unsigned long transfer_size; | 425 | unsigned long transfer_size; |
435 | enum sirfsoc_tx_state tx_dma_state; | 426 | enum sirfsoc_tx_state tx_dma_state; |
436 | unsigned int cts_gpio; | 427 | unsigned int cts_gpio; |
437 | unsigned int rts_gpio; | 428 | unsigned int rts_gpio; |
438 | 429 | ||
439 | struct sirfsoc_loop_buffer rx_dma_items[SIRFSOC_RX_LOOP_BUF_CNT]; | 430 | struct sirfsoc_rx_buffer rx_dma_items; |
440 | int rx_completed; | 431 | struct hrtimer hrt; |
441 | int rx_issued; | 432 | bool is_hrt_enabled; |
433 | unsigned long rx_period_time; | ||
442 | }; | 434 | }; |
443 | 435 | ||
444 | /* Register Access Control */ | 436 | /* Register Access Control */ |
@@ -447,10 +439,6 @@ struct sirfsoc_uart_port { | |||
447 | #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) | 439 | #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) |
448 | 440 | ||
449 | /* UART Port Mask */ | 441 | /* UART Port Mask */ |
450 | #define SIRFUART_FIFOLEVEL_MASK(port) ((port->line == 1) ? (0x1f) : (0x7f)) | 442 | #define SIRFUART_FIFOLEVEL_MASK(port) ((port->fifosize - 1) & 0xFFF) |
451 | #define SIRFUART_FIFOFULL_MASK(port) ((port->line == 1) ? (0x20) : (0x80)) | 443 | #define SIRFUART_FIFOFULL_MASK(port) (port->fifosize & 0xFFF) |
452 | #define SIRFUART_FIFOEMPTY_MASK(port) ((port->line == 1) ? (0x40) : (0x100)) | 444 | #define SIRFUART_FIFOEMPTY_MASK(port) ((port->fifosize & 0xFFF) << 1) |
453 | |||
454 | /* I/O Mode */ | ||
455 | #define SIRFSOC_UART_IO_RX_MAX_CNT 256 | ||
456 | #define SIRFSOC_UART_IO_TX_REASONABLE_CNT 256 | ||
diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 582d2729f700..3866516c2926 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c | |||
@@ -716,7 +716,7 @@ static int sprd_probe(struct platform_device *pdev) | |||
716 | up->flags = UPF_BOOT_AUTOCONF; | 716 | up->flags = UPF_BOOT_AUTOCONF; |
717 | 717 | ||
718 | clk = devm_clk_get(&pdev->dev, NULL); | 718 | clk = devm_clk_get(&pdev->dev, NULL); |
719 | if (!IS_ERR(clk)) | 719 | if (!IS_ERR_OR_NULL(clk)) |
720 | up->uartclk = clk_get_rate(clk); | 720 | up->uartclk = clk_get_rate(clk); |
721 | 721 | ||
722 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 722 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c new file mode 100644 index 000000000000..4a6eab6da63e --- /dev/null +++ b/drivers/tty/serial/stm32-usart.c | |||
@@ -0,0 +1,739 @@ | |||
1 | /* | ||
2 | * Copyright (C) Maxime Coquelin 2015 | ||
3 | * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> | ||
4 | * License terms: GNU General Public License (GPL), version 2 | ||
5 | * | ||
6 | * Inspired by st-asc.c from STMicroelectronics (c) | ||
7 | */ | ||
8 | |||
9 | #if defined(CONFIG_SERIAL_STM32_USART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
10 | #define SUPPORT_SYSRQ | ||
11 | #endif | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/serial.h> | ||
15 | #include <linux/console.h> | ||
16 | #include <linux/sysrq.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/tty.h> | ||
21 | #include <linux/tty_flip.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/pm_runtime.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/of_platform.h> | ||
27 | #include <linux/serial_core.h> | ||
28 | #include <linux/clk.h> | ||
29 | |||
30 | #define DRIVER_NAME "stm32-usart" | ||
31 | |||
32 | /* Register offsets */ | ||
33 | #define USART_SR 0x00 | ||
34 | #define USART_DR 0x04 | ||
35 | #define USART_BRR 0x08 | ||
36 | #define USART_CR1 0x0c | ||
37 | #define USART_CR2 0x10 | ||
38 | #define USART_CR3 0x14 | ||
39 | #define USART_GTPR 0x18 | ||
40 | |||
41 | /* USART_SR */ | ||
42 | #define USART_SR_PE BIT(0) | ||
43 | #define USART_SR_FE BIT(1) | ||
44 | #define USART_SR_NF BIT(2) | ||
45 | #define USART_SR_ORE BIT(3) | ||
46 | #define USART_SR_IDLE BIT(4) | ||
47 | #define USART_SR_RXNE BIT(5) | ||
48 | #define USART_SR_TC BIT(6) | ||
49 | #define USART_SR_TXE BIT(7) | ||
50 | #define USART_SR_LBD BIT(8) | ||
51 | #define USART_SR_CTS BIT(9) | ||
52 | #define USART_SR_ERR_MASK (USART_SR_LBD | USART_SR_ORE | \ | ||
53 | USART_SR_FE | USART_SR_PE) | ||
54 | /* Dummy bits */ | ||
55 | #define USART_SR_DUMMY_RX BIT(16) | ||
56 | |||
57 | /* USART_DR */ | ||
58 | #define USART_DR_MASK GENMASK(8, 0) | ||
59 | |||
60 | /* USART_BRR */ | ||
61 | #define USART_BRR_DIV_F_MASK GENMASK(3, 0) | ||
62 | #define USART_BRR_DIV_M_MASK GENMASK(15, 4) | ||
63 | #define USART_BRR_DIV_M_SHIFT 4 | ||
64 | |||
65 | /* USART_CR1 */ | ||
66 | #define USART_CR1_SBK BIT(0) | ||
67 | #define USART_CR1_RWU BIT(1) | ||
68 | #define USART_CR1_RE BIT(2) | ||
69 | #define USART_CR1_TE BIT(3) | ||
70 | #define USART_CR1_IDLEIE BIT(4) | ||
71 | #define USART_CR1_RXNEIE BIT(5) | ||
72 | #define USART_CR1_TCIE BIT(6) | ||
73 | #define USART_CR1_TXEIE BIT(7) | ||
74 | #define USART_CR1_PEIE BIT(8) | ||
75 | #define USART_CR1_PS BIT(9) | ||
76 | #define USART_CR1_PCE BIT(10) | ||
77 | #define USART_CR1_WAKE BIT(11) | ||
78 | #define USART_CR1_M BIT(12) | ||
79 | #define USART_CR1_UE BIT(13) | ||
80 | #define USART_CR1_OVER8 BIT(15) | ||
81 | #define USART_CR1_IE_MASK GENMASK(8, 4) | ||
82 | |||
83 | /* USART_CR2 */ | ||
84 | #define USART_CR2_ADD_MASK GENMASK(3, 0) | ||
85 | #define USART_CR2_LBDL BIT(5) | ||
86 | #define USART_CR2_LBDIE BIT(6) | ||
87 | #define USART_CR2_LBCL BIT(8) | ||
88 | #define USART_CR2_CPHA BIT(9) | ||
89 | #define USART_CR2_CPOL BIT(10) | ||
90 | #define USART_CR2_CLKEN BIT(11) | ||
91 | #define USART_CR2_STOP_2B BIT(13) | ||
92 | #define USART_CR2_STOP_MASK GENMASK(13, 12) | ||
93 | #define USART_CR2_LINEN BIT(14) | ||
94 | |||
95 | /* USART_CR3 */ | ||
96 | #define USART_CR3_EIE BIT(0) | ||
97 | #define USART_CR3_IREN BIT(1) | ||
98 | #define USART_CR3_IRLP BIT(2) | ||
99 | #define USART_CR3_HDSEL BIT(3) | ||
100 | #define USART_CR3_NACK BIT(4) | ||
101 | #define USART_CR3_SCEN BIT(5) | ||
102 | #define USART_CR3_DMAR BIT(6) | ||
103 | #define USART_CR3_DMAT BIT(7) | ||
104 | #define USART_CR3_RTSE BIT(8) | ||
105 | #define USART_CR3_CTSE BIT(9) | ||
106 | #define USART_CR3_CTSIE BIT(10) | ||
107 | #define USART_CR3_ONEBIT BIT(11) | ||
108 | |||
109 | /* USART_GTPR */ | ||
110 | #define USART_GTPR_PSC_MASK GENMASK(7, 0) | ||
111 | #define USART_GTPR_GT_MASK GENMASK(15, 8) | ||
112 | |||
113 | #define DRIVER_NAME "stm32-usart" | ||
114 | #define STM32_SERIAL_NAME "ttyS" | ||
115 | #define STM32_MAX_PORTS 6 | ||
116 | |||
117 | struct stm32_port { | ||
118 | struct uart_port port; | ||
119 | struct clk *clk; | ||
120 | bool hw_flow_control; | ||
121 | }; | ||
122 | |||
123 | static struct stm32_port stm32_ports[STM32_MAX_PORTS]; | ||
124 | static struct uart_driver stm32_usart_driver; | ||
125 | |||
126 | static void stm32_stop_tx(struct uart_port *port); | ||
127 | |||
128 | static inline struct stm32_port *to_stm32_port(struct uart_port *port) | ||
129 | { | ||
130 | return container_of(port, struct stm32_port, port); | ||
131 | } | ||
132 | |||
133 | static void stm32_set_bits(struct uart_port *port, u32 reg, u32 bits) | ||
134 | { | ||
135 | u32 val; | ||
136 | |||
137 | val = readl_relaxed(port->membase + reg); | ||
138 | val |= bits; | ||
139 | writel_relaxed(val, port->membase + reg); | ||
140 | } | ||
141 | |||
142 | static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits) | ||
143 | { | ||
144 | u32 val; | ||
145 | |||
146 | val = readl_relaxed(port->membase + reg); | ||
147 | val &= ~bits; | ||
148 | writel_relaxed(val, port->membase + reg); | ||
149 | } | ||
150 | |||
151 | static void stm32_receive_chars(struct uart_port *port) | ||
152 | { | ||
153 | struct tty_port *tport = &port->state->port; | ||
154 | unsigned long c; | ||
155 | u32 sr; | ||
156 | char flag; | ||
157 | |||
158 | if (port->irq_wake) | ||
159 | pm_wakeup_event(tport->tty->dev, 0); | ||
160 | |||
161 | while ((sr = readl_relaxed(port->membase + USART_SR)) & USART_SR_RXNE) { | ||
162 | sr |= USART_SR_DUMMY_RX; | ||
163 | c = readl_relaxed(port->membase + USART_DR); | ||
164 | flag = TTY_NORMAL; | ||
165 | port->icount.rx++; | ||
166 | |||
167 | if (sr & USART_SR_ERR_MASK) { | ||
168 | if (sr & USART_SR_LBD) { | ||
169 | port->icount.brk++; | ||
170 | if (uart_handle_break(port)) | ||
171 | continue; | ||
172 | } else if (sr & USART_SR_ORE) { | ||
173 | port->icount.overrun++; | ||
174 | } else if (sr & USART_SR_PE) { | ||
175 | port->icount.parity++; | ||
176 | } else if (sr & USART_SR_FE) { | ||
177 | port->icount.frame++; | ||
178 | } | ||
179 | |||
180 | sr &= port->read_status_mask; | ||
181 | |||
182 | if (sr & USART_SR_LBD) | ||
183 | flag = TTY_BREAK; | ||
184 | else if (sr & USART_SR_PE) | ||
185 | flag = TTY_PARITY; | ||
186 | else if (sr & USART_SR_FE) | ||
187 | flag = TTY_FRAME; | ||
188 | } | ||
189 | |||
190 | if (uart_handle_sysrq_char(port, c)) | ||
191 | continue; | ||
192 | uart_insert_char(port, sr, USART_SR_ORE, c, flag); | ||
193 | } | ||
194 | |||
195 | spin_unlock(&port->lock); | ||
196 | tty_flip_buffer_push(tport); | ||
197 | spin_lock(&port->lock); | ||
198 | } | ||
199 | |||
200 | static void stm32_transmit_chars(struct uart_port *port) | ||
201 | { | ||
202 | struct circ_buf *xmit = &port->state->xmit; | ||
203 | |||
204 | if (port->x_char) { | ||
205 | writel_relaxed(port->x_char, port->membase + USART_DR); | ||
206 | port->x_char = 0; | ||
207 | port->icount.tx++; | ||
208 | return; | ||
209 | } | ||
210 | |||
211 | if (uart_tx_stopped(port)) { | ||
212 | stm32_stop_tx(port); | ||
213 | return; | ||
214 | } | ||
215 | |||
216 | if (uart_circ_empty(xmit)) { | ||
217 | stm32_stop_tx(port); | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | writel_relaxed(xmit->buf[xmit->tail], port->membase + USART_DR); | ||
222 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
223 | port->icount.tx++; | ||
224 | |||
225 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
226 | uart_write_wakeup(port); | ||
227 | |||
228 | if (uart_circ_empty(xmit)) | ||
229 | stm32_stop_tx(port); | ||
230 | } | ||
231 | |||
232 | static irqreturn_t stm32_interrupt(int irq, void *ptr) | ||
233 | { | ||
234 | struct uart_port *port = ptr; | ||
235 | u32 sr; | ||
236 | |||
237 | spin_lock(&port->lock); | ||
238 | |||
239 | sr = readl_relaxed(port->membase + USART_SR); | ||
240 | |||
241 | if (sr & USART_SR_RXNE) | ||
242 | stm32_receive_chars(port); | ||
243 | |||
244 | if (sr & USART_SR_TXE) | ||
245 | stm32_transmit_chars(port); | ||
246 | |||
247 | spin_unlock(&port->lock); | ||
248 | |||
249 | return IRQ_HANDLED; | ||
250 | } | ||
251 | |||
252 | static unsigned int stm32_tx_empty(struct uart_port *port) | ||
253 | { | ||
254 | return readl_relaxed(port->membase + USART_SR) & USART_SR_TXE; | ||
255 | } | ||
256 | |||
257 | static void stm32_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
258 | { | ||
259 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) | ||
260 | stm32_set_bits(port, USART_CR3, USART_CR3_RTSE); | ||
261 | else | ||
262 | stm32_clr_bits(port, USART_CR3, USART_CR3_RTSE); | ||
263 | } | ||
264 | |||
265 | static unsigned int stm32_get_mctrl(struct uart_port *port) | ||
266 | { | ||
267 | /* This routine is used to get signals of: DCD, DSR, RI, and CTS */ | ||
268 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
269 | } | ||
270 | |||
271 | /* Transmit stop */ | ||
272 | static void stm32_stop_tx(struct uart_port *port) | ||
273 | { | ||
274 | stm32_clr_bits(port, USART_CR1, USART_CR1_TXEIE); | ||
275 | } | ||
276 | |||
277 | /* There are probably characters waiting to be transmitted. */ | ||
278 | static void stm32_start_tx(struct uart_port *port) | ||
279 | { | ||
280 | struct circ_buf *xmit = &port->state->xmit; | ||
281 | |||
282 | if (uart_circ_empty(xmit)) | ||
283 | return; | ||
284 | |||
285 | stm32_set_bits(port, USART_CR1, USART_CR1_TXEIE | USART_CR1_TE); | ||
286 | } | ||
287 | |||
288 | /* Throttle the remote when input buffer is about to overflow. */ | ||
289 | static void stm32_throttle(struct uart_port *port) | ||
290 | { | ||
291 | unsigned long flags; | ||
292 | |||
293 | spin_lock_irqsave(&port->lock, flags); | ||
294 | stm32_clr_bits(port, USART_CR1, USART_CR1_RXNEIE); | ||
295 | spin_unlock_irqrestore(&port->lock, flags); | ||
296 | } | ||
297 | |||
298 | /* Unthrottle the remote, the input buffer can now accept data. */ | ||
299 | static void stm32_unthrottle(struct uart_port *port) | ||
300 | { | ||
301 | unsigned long flags; | ||
302 | |||
303 | spin_lock_irqsave(&port->lock, flags); | ||
304 | stm32_set_bits(port, USART_CR1, USART_CR1_RXNEIE); | ||
305 | spin_unlock_irqrestore(&port->lock, flags); | ||
306 | } | ||
307 | |||
308 | /* Receive stop */ | ||
309 | static void stm32_stop_rx(struct uart_port *port) | ||
310 | { | ||
311 | stm32_clr_bits(port, USART_CR1, USART_CR1_RXNEIE); | ||
312 | } | ||
313 | |||
314 | /* Handle breaks - ignored by us */ | ||
315 | static void stm32_break_ctl(struct uart_port *port, int break_state) | ||
316 | { | ||
317 | } | ||
318 | |||
319 | static int stm32_startup(struct uart_port *port) | ||
320 | { | ||
321 | const char *name = to_platform_device(port->dev)->name; | ||
322 | u32 val; | ||
323 | int ret; | ||
324 | |||
325 | ret = request_irq(port->irq, stm32_interrupt, IRQF_NO_SUSPEND, | ||
326 | name, port); | ||
327 | if (ret) | ||
328 | return ret; | ||
329 | |||
330 | val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; | ||
331 | stm32_set_bits(port, USART_CR1, val); | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static void stm32_shutdown(struct uart_port *port) | ||
337 | { | ||
338 | u32 val; | ||
339 | |||
340 | val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; | ||
341 | stm32_set_bits(port, USART_CR1, val); | ||
342 | |||
343 | free_irq(port->irq, port); | ||
344 | } | ||
345 | |||
346 | static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, | ||
347 | struct ktermios *old) | ||
348 | { | ||
349 | struct stm32_port *stm32_port = to_stm32_port(port); | ||
350 | unsigned int baud; | ||
351 | u32 usartdiv, mantissa, fraction, oversampling; | ||
352 | tcflag_t cflag = termios->c_cflag; | ||
353 | u32 cr1, cr2, cr3; | ||
354 | unsigned long flags; | ||
355 | |||
356 | if (!stm32_port->hw_flow_control) | ||
357 | cflag &= ~CRTSCTS; | ||
358 | |||
359 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 8); | ||
360 | |||
361 | spin_lock_irqsave(&port->lock, flags); | ||
362 | |||
363 | /* Stop serial port and reset value */ | ||
364 | writel_relaxed(0, port->membase + USART_CR1); | ||
365 | |||
366 | cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_RXNEIE; | ||
367 | cr2 = 0; | ||
368 | cr3 = 0; | ||
369 | |||
370 | if (cflag & CSTOPB) | ||
371 | cr2 |= USART_CR2_STOP_2B; | ||
372 | |||
373 | if (cflag & PARENB) { | ||
374 | cr1 |= USART_CR1_PCE; | ||
375 | if ((cflag & CSIZE) == CS8) | ||
376 | cr1 |= USART_CR1_M; | ||
377 | } | ||
378 | |||
379 | if (cflag & PARODD) | ||
380 | cr1 |= USART_CR1_PS; | ||
381 | |||
382 | port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS); | ||
383 | if (cflag & CRTSCTS) { | ||
384 | port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; | ||
385 | cr3 |= USART_CR3_CTSE; | ||
386 | } | ||
387 | |||
388 | usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud); | ||
389 | |||
390 | /* | ||
391 | * The USART supports 16 or 8 times oversampling. | ||
392 | * By default we prefer 16 times oversampling, so that the receiver | ||
393 | * has a better tolerance to clock deviations. | ||
394 | * 8 times oversampling is only used to achieve higher speeds. | ||
395 | */ | ||
396 | if (usartdiv < 16) { | ||
397 | oversampling = 8; | ||
398 | stm32_set_bits(port, USART_CR1, USART_CR1_OVER8); | ||
399 | } else { | ||
400 | oversampling = 16; | ||
401 | stm32_clr_bits(port, USART_CR1, USART_CR1_OVER8); | ||
402 | } | ||
403 | |||
404 | mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT; | ||
405 | fraction = usartdiv % oversampling; | ||
406 | writel_relaxed(mantissa | fraction, port->membase + USART_BRR); | ||
407 | |||
408 | uart_update_timeout(port, cflag, baud); | ||
409 | |||
410 | port->read_status_mask = USART_SR_ORE; | ||
411 | if (termios->c_iflag & INPCK) | ||
412 | port->read_status_mask |= USART_SR_PE | USART_SR_FE; | ||
413 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) | ||
414 | port->read_status_mask |= USART_SR_LBD; | ||
415 | |||
416 | /* Characters to ignore */ | ||
417 | port->ignore_status_mask = 0; | ||
418 | if (termios->c_iflag & IGNPAR) | ||
419 | port->ignore_status_mask = USART_SR_PE | USART_SR_FE; | ||
420 | if (termios->c_iflag & IGNBRK) { | ||
421 | port->ignore_status_mask |= USART_SR_LBD; | ||
422 | /* | ||
423 | * If we're ignoring parity and break indicators, | ||
424 | * ignore overruns too (for real raw support). | ||
425 | */ | ||
426 | if (termios->c_iflag & IGNPAR) | ||
427 | port->ignore_status_mask |= USART_SR_ORE; | ||
428 | } | ||
429 | |||
430 | /* Ignore all characters if CREAD is not set */ | ||
431 | if ((termios->c_cflag & CREAD) == 0) | ||
432 | port->ignore_status_mask |= USART_SR_DUMMY_RX; | ||
433 | |||
434 | writel_relaxed(cr3, port->membase + USART_CR3); | ||
435 | writel_relaxed(cr2, port->membase + USART_CR2); | ||
436 | writel_relaxed(cr1, port->membase + USART_CR1); | ||
437 | |||
438 | spin_unlock_irqrestore(&port->lock, flags); | ||
439 | } | ||
440 | |||
441 | static const char *stm32_type(struct uart_port *port) | ||
442 | { | ||
443 | return (port->type == PORT_STM32) ? DRIVER_NAME : NULL; | ||
444 | } | ||
445 | |||
446 | static void stm32_release_port(struct uart_port *port) | ||
447 | { | ||
448 | } | ||
449 | |||
450 | static int stm32_request_port(struct uart_port *port) | ||
451 | { | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static void stm32_config_port(struct uart_port *port, int flags) | ||
456 | { | ||
457 | if (flags & UART_CONFIG_TYPE) | ||
458 | port->type = PORT_STM32; | ||
459 | } | ||
460 | |||
461 | static int | ||
462 | stm32_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
463 | { | ||
464 | /* No user changeable parameters */ | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | |||
468 | static void stm32_pm(struct uart_port *port, unsigned int state, | ||
469 | unsigned int oldstate) | ||
470 | { | ||
471 | struct stm32_port *stm32port = container_of(port, | ||
472 | struct stm32_port, port); | ||
473 | unsigned long flags = 0; | ||
474 | |||
475 | switch (state) { | ||
476 | case UART_PM_STATE_ON: | ||
477 | clk_prepare_enable(stm32port->clk); | ||
478 | break; | ||
479 | case UART_PM_STATE_OFF: | ||
480 | spin_lock_irqsave(&port->lock, flags); | ||
481 | stm32_clr_bits(port, USART_CR1, USART_CR1_UE); | ||
482 | spin_unlock_irqrestore(&port->lock, flags); | ||
483 | clk_disable_unprepare(stm32port->clk); | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | static const struct uart_ops stm32_uart_ops = { | ||
489 | .tx_empty = stm32_tx_empty, | ||
490 | .set_mctrl = stm32_set_mctrl, | ||
491 | .get_mctrl = stm32_get_mctrl, | ||
492 | .stop_tx = stm32_stop_tx, | ||
493 | .start_tx = stm32_start_tx, | ||
494 | .throttle = stm32_throttle, | ||
495 | .unthrottle = stm32_unthrottle, | ||
496 | .stop_rx = stm32_stop_rx, | ||
497 | .break_ctl = stm32_break_ctl, | ||
498 | .startup = stm32_startup, | ||
499 | .shutdown = stm32_shutdown, | ||
500 | .set_termios = stm32_set_termios, | ||
501 | .pm = stm32_pm, | ||
502 | .type = stm32_type, | ||
503 | .release_port = stm32_release_port, | ||
504 | .request_port = stm32_request_port, | ||
505 | .config_port = stm32_config_port, | ||
506 | .verify_port = stm32_verify_port, | ||
507 | }; | ||
508 | |||
509 | static int stm32_init_port(struct stm32_port *stm32port, | ||
510 | struct platform_device *pdev) | ||
511 | { | ||
512 | struct uart_port *port = &stm32port->port; | ||
513 | struct resource *res; | ||
514 | int ret; | ||
515 | |||
516 | port->iotype = UPIO_MEM; | ||
517 | port->flags = UPF_BOOT_AUTOCONF; | ||
518 | port->ops = &stm32_uart_ops; | ||
519 | port->dev = &pdev->dev; | ||
520 | port->irq = platform_get_irq(pdev, 0); | ||
521 | |||
522 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
523 | port->membase = devm_ioremap_resource(&pdev->dev, res); | ||
524 | if (IS_ERR(port->membase)) | ||
525 | return PTR_ERR(port->membase); | ||
526 | port->mapbase = res->start; | ||
527 | |||
528 | spin_lock_init(&port->lock); | ||
529 | |||
530 | stm32port->clk = devm_clk_get(&pdev->dev, NULL); | ||
531 | if (IS_ERR(stm32port->clk)) | ||
532 | return PTR_ERR(stm32port->clk); | ||
533 | |||
534 | /* Ensure that clk rate is correct by enabling the clk */ | ||
535 | ret = clk_prepare_enable(stm32port->clk); | ||
536 | if (ret) | ||
537 | return ret; | ||
538 | |||
539 | stm32port->port.uartclk = clk_get_rate(stm32port->clk); | ||
540 | if (!stm32port->port.uartclk) | ||
541 | ret = -EINVAL; | ||
542 | |||
543 | clk_disable_unprepare(stm32port->clk); | ||
544 | |||
545 | return ret; | ||
546 | } | ||
547 | |||
548 | static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev) | ||
549 | { | ||
550 | struct device_node *np = pdev->dev.of_node; | ||
551 | int id; | ||
552 | |||
553 | if (!np) | ||
554 | return NULL; | ||
555 | |||
556 | id = of_alias_get_id(np, "serial"); | ||
557 | if (id < 0) | ||
558 | id = 0; | ||
559 | |||
560 | if (WARN_ON(id >= STM32_MAX_PORTS)) | ||
561 | return NULL; | ||
562 | |||
563 | stm32_ports[id].hw_flow_control = of_property_read_bool(np, | ||
564 | "auto-flow-control"); | ||
565 | stm32_ports[id].port.line = id; | ||
566 | return &stm32_ports[id]; | ||
567 | } | ||
568 | |||
569 | #ifdef CONFIG_OF | ||
570 | static const struct of_device_id stm32_match[] = { | ||
571 | { .compatible = "st,stm32-usart", }, | ||
572 | { .compatible = "st,stm32-uart", }, | ||
573 | {}, | ||
574 | }; | ||
575 | |||
576 | MODULE_DEVICE_TABLE(of, stm32_match); | ||
577 | #endif | ||
578 | |||
579 | static int stm32_serial_probe(struct platform_device *pdev) | ||
580 | { | ||
581 | int ret; | ||
582 | struct stm32_port *stm32port; | ||
583 | |||
584 | stm32port = stm32_of_get_stm32_port(pdev); | ||
585 | if (!stm32port) | ||
586 | return -ENODEV; | ||
587 | |||
588 | ret = stm32_init_port(stm32port, pdev); | ||
589 | if (ret) | ||
590 | return ret; | ||
591 | |||
592 | ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port); | ||
593 | if (ret) | ||
594 | return ret; | ||
595 | |||
596 | platform_set_drvdata(pdev, &stm32port->port); | ||
597 | |||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static int stm32_serial_remove(struct platform_device *pdev) | ||
602 | { | ||
603 | struct uart_port *port = platform_get_drvdata(pdev); | ||
604 | |||
605 | return uart_remove_one_port(&stm32_usart_driver, port); | ||
606 | } | ||
607 | |||
608 | |||
609 | #ifdef CONFIG_SERIAL_STM32_CONSOLE | ||
610 | static void stm32_console_putchar(struct uart_port *port, int ch) | ||
611 | { | ||
612 | while (!(readl_relaxed(port->membase + USART_SR) & USART_SR_TXE)) | ||
613 | cpu_relax(); | ||
614 | |||
615 | writel_relaxed(ch, port->membase + USART_DR); | ||
616 | } | ||
617 | |||
618 | static void stm32_console_write(struct console *co, const char *s, unsigned cnt) | ||
619 | { | ||
620 | struct uart_port *port = &stm32_ports[co->index].port; | ||
621 | unsigned long flags; | ||
622 | u32 old_cr1, new_cr1; | ||
623 | int locked = 1; | ||
624 | |||
625 | local_irq_save(flags); | ||
626 | if (port->sysrq) | ||
627 | locked = 0; | ||
628 | else if (oops_in_progress) | ||
629 | locked = spin_trylock(&port->lock); | ||
630 | else | ||
631 | spin_lock(&port->lock); | ||
632 | |||
633 | /* Save and disable interrupts */ | ||
634 | old_cr1 = readl_relaxed(port->membase + USART_CR1); | ||
635 | new_cr1 = old_cr1 & ~USART_CR1_IE_MASK; | ||
636 | writel_relaxed(new_cr1, port->membase + USART_CR1); | ||
637 | |||
638 | uart_console_write(port, s, cnt, stm32_console_putchar); | ||
639 | |||
640 | /* Restore interrupt state */ | ||
641 | writel_relaxed(old_cr1, port->membase + USART_CR1); | ||
642 | |||
643 | if (locked) | ||
644 | spin_unlock(&port->lock); | ||
645 | local_irq_restore(flags); | ||
646 | } | ||
647 | |||
648 | static int stm32_console_setup(struct console *co, char *options) | ||
649 | { | ||
650 | struct stm32_port *stm32port; | ||
651 | int baud = 9600; | ||
652 | int bits = 8; | ||
653 | int parity = 'n'; | ||
654 | int flow = 'n'; | ||
655 | |||
656 | if (co->index >= STM32_MAX_PORTS) | ||
657 | return -ENODEV; | ||
658 | |||
659 | stm32port = &stm32_ports[co->index]; | ||
660 | |||
661 | /* | ||
662 | * This driver does not support early console initialization | ||
663 | * (use ARM early printk support instead), so we only expect | ||
664 | * this to be called during the uart port registration when the | ||
665 | * driver gets probed and the port should be mapped at that point. | ||
666 | */ | ||
667 | if (stm32port->port.mapbase == 0 || stm32port->port.membase == NULL) | ||
668 | return -ENXIO; | ||
669 | |||
670 | if (options) | ||
671 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
672 | |||
673 | return uart_set_options(&stm32port->port, co, baud, parity, bits, flow); | ||
674 | } | ||
675 | |||
676 | static struct console stm32_console = { | ||
677 | .name = STM32_SERIAL_NAME, | ||
678 | .device = uart_console_device, | ||
679 | .write = stm32_console_write, | ||
680 | .setup = stm32_console_setup, | ||
681 | .flags = CON_PRINTBUFFER, | ||
682 | .index = -1, | ||
683 | .data = &stm32_usart_driver, | ||
684 | }; | ||
685 | |||
686 | #define STM32_SERIAL_CONSOLE (&stm32_console) | ||
687 | |||
688 | #else | ||
689 | #define STM32_SERIAL_CONSOLE NULL | ||
690 | #endif /* CONFIG_SERIAL_STM32_CONSOLE */ | ||
691 | |||
692 | static struct uart_driver stm32_usart_driver = { | ||
693 | .driver_name = DRIVER_NAME, | ||
694 | .dev_name = STM32_SERIAL_NAME, | ||
695 | .major = 0, | ||
696 | .minor = 0, | ||
697 | .nr = STM32_MAX_PORTS, | ||
698 | .cons = STM32_SERIAL_CONSOLE, | ||
699 | }; | ||
700 | |||
701 | static struct platform_driver stm32_serial_driver = { | ||
702 | .probe = stm32_serial_probe, | ||
703 | .remove = stm32_serial_remove, | ||
704 | .driver = { | ||
705 | .name = DRIVER_NAME, | ||
706 | .of_match_table = of_match_ptr(stm32_match), | ||
707 | }, | ||
708 | }; | ||
709 | |||
710 | static int __init usart_init(void) | ||
711 | { | ||
712 | static char banner[] __initdata = "STM32 USART driver initialized"; | ||
713 | int ret; | ||
714 | |||
715 | pr_info("%s\n", banner); | ||
716 | |||
717 | ret = uart_register_driver(&stm32_usart_driver); | ||
718 | if (ret) | ||
719 | return ret; | ||
720 | |||
721 | ret = platform_driver_register(&stm32_serial_driver); | ||
722 | if (ret) | ||
723 | uart_unregister_driver(&stm32_usart_driver); | ||
724 | |||
725 | return ret; | ||
726 | } | ||
727 | |||
728 | static void __exit usart_exit(void) | ||
729 | { | ||
730 | platform_driver_unregister(&stm32_serial_driver); | ||
731 | uart_unregister_driver(&stm32_usart_driver); | ||
732 | } | ||
733 | |||
734 | module_init(usart_init); | ||
735 | module_exit(usart_exit); | ||
736 | |||
737 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
738 | MODULE_DESCRIPTION("STMicroelectronics STM32 serial port driver"); | ||
739 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 3ddbac767db3..009e0dbc12d2 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -1075,7 +1075,8 @@ static void cdns_uart_console_putchar(struct uart_port *port, int ch) | |||
1075 | writel(ch, port->membase + CDNS_UART_FIFO_OFFSET); | 1075 | writel(ch, port->membase + CDNS_UART_FIFO_OFFSET); |
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | static void cdns_early_write(struct console *con, const char *s, unsigned n) | 1078 | static void __init cdns_early_write(struct console *con, const char *s, |
1079 | unsigned n) | ||
1079 | { | 1080 | { |
1080 | struct earlycon_device *dev = con->data; | 1081 | struct earlycon_device *dev = con->data; |
1081 | 1082 | ||
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index b7991707ffc0..2fac7123b274 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -4410,7 +4410,8 @@ static void synclink_cleanup(void) | |||
4410 | printk("Unloading %s: %s\n", driver_name, driver_version); | 4410 | printk("Unloading %s: %s\n", driver_name, driver_version); |
4411 | 4411 | ||
4412 | if (serial_driver) { | 4412 | if (serial_driver) { |
4413 | if ((rc = tty_unregister_driver(serial_driver))) | 4413 | rc = tty_unregister_driver(serial_driver); |
4414 | if (rc) | ||
4414 | printk("%s(%d) failed to unregister tty driver err=%d\n", | 4415 | printk("%s(%d) failed to unregister tty driver err=%d\n", |
4415 | __FILE__,__LINE__,rc); | 4416 | __FILE__,__LINE__,rc); |
4416 | put_tty_driver(serial_driver); | 4417 | put_tty_driver(serial_driver); |
@@ -7751,7 +7752,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
7751 | printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name); | 7752 | printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name); |
7752 | 7753 | ||
7753 | /* generic HDLC layer open processing */ | 7754 | /* generic HDLC layer open processing */ |
7754 | if ((rc = hdlc_open(dev))) | 7755 | rc = hdlc_open(dev); |
7756 | if (rc) | ||
7755 | return rc; | 7757 | return rc; |
7756 | 7758 | ||
7757 | /* arbitrate between network and tty opens */ | 7759 | /* arbitrate between network and tty opens */ |
@@ -8018,7 +8020,8 @@ static int hdlcdev_init(struct mgsl_struct *info) | |||
8018 | 8020 | ||
8019 | /* allocate and initialize network and HDLC layer objects */ | 8021 | /* allocate and initialize network and HDLC layer objects */ |
8020 | 8022 | ||
8021 | if (!(dev = alloc_hdlcdev(info))) { | 8023 | dev = alloc_hdlcdev(info); |
8024 | if (!dev) { | ||
8022 | printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__); | 8025 | printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__); |
8023 | return -ENOMEM; | 8026 | return -ENOMEM; |
8024 | } | 8027 | } |
@@ -8039,7 +8042,8 @@ static int hdlcdev_init(struct mgsl_struct *info) | |||
8039 | hdlc->xmit = hdlcdev_xmit; | 8042 | hdlc->xmit = hdlcdev_xmit; |
8040 | 8043 | ||
8041 | /* register objects with HDLC layer */ | 8044 | /* register objects with HDLC layer */ |
8042 | if ((rc = register_hdlc_device(dev))) { | 8045 | rc = register_hdlc_device(dev); |
8046 | if (rc) { | ||
8043 | printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); | 8047 | printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); |
8044 | free_netdev(dev); | 8048 | free_netdev(dev); |
8045 | return rc; | 8049 | return rc; |
@@ -8075,7 +8079,8 @@ static int synclink_init_one (struct pci_dev *dev, | |||
8075 | return -EIO; | 8079 | return -EIO; |
8076 | } | 8080 | } |
8077 | 8081 | ||
8078 | if (!(info = mgsl_allocate_device())) { | 8082 | info = mgsl_allocate_device(); |
8083 | if (!info) { | ||
8079 | printk("can't allocate device instance data.\n"); | 8084 | printk("can't allocate device instance data.\n"); |
8080 | return -EIO; | 8085 | return -EIO; |
8081 | } | 8086 | } |
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 0e8c39b6ccd4..0ea8eee00178 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -1539,7 +1539,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
1539 | DBGINFO(("%s hdlcdev_open\n", dev->name)); | 1539 | DBGINFO(("%s hdlcdev_open\n", dev->name)); |
1540 | 1540 | ||
1541 | /* generic HDLC layer open processing */ | 1541 | /* generic HDLC layer open processing */ |
1542 | if ((rc = hdlc_open(dev))) | 1542 | rc = hdlc_open(dev); |
1543 | if (rc) | ||
1543 | return rc; | 1544 | return rc; |
1544 | 1545 | ||
1545 | /* arbitrate between network and tty opens */ | 1546 | /* arbitrate between network and tty opens */ |
@@ -1803,7 +1804,8 @@ static int hdlcdev_init(struct slgt_info *info) | |||
1803 | 1804 | ||
1804 | /* allocate and initialize network and HDLC layer objects */ | 1805 | /* allocate and initialize network and HDLC layer objects */ |
1805 | 1806 | ||
1806 | if (!(dev = alloc_hdlcdev(info))) { | 1807 | dev = alloc_hdlcdev(info); |
1808 | if (!dev) { | ||
1807 | printk(KERN_ERR "%s hdlc device alloc failure\n", info->device_name); | 1809 | printk(KERN_ERR "%s hdlc device alloc failure\n", info->device_name); |
1808 | return -ENOMEM; | 1810 | return -ENOMEM; |
1809 | } | 1811 | } |
@@ -1824,7 +1826,8 @@ static int hdlcdev_init(struct slgt_info *info) | |||
1824 | hdlc->xmit = hdlcdev_xmit; | 1826 | hdlc->xmit = hdlcdev_xmit; |
1825 | 1827 | ||
1826 | /* register objects with HDLC layer */ | 1828 | /* register objects with HDLC layer */ |
1827 | if ((rc = register_hdlc_device(dev))) { | 1829 | rc = register_hdlc_device(dev); |
1830 | if (rc) { | ||
1828 | printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); | 1831 | printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); |
1829 | free_netdev(dev); | 1832 | free_netdev(dev); |
1830 | return rc; | 1833 | return rc; |
@@ -1879,7 +1882,8 @@ static void rx_async(struct slgt_info *info) | |||
1879 | 1882 | ||
1880 | stat = 0; | 1883 | stat = 0; |
1881 | 1884 | ||
1882 | if ((status = *(p+1) & (BIT1 + BIT0))) { | 1885 | status = *(p + 1) & (BIT1 + BIT0); |
1886 | if (status) { | ||
1883 | if (status & BIT1) | 1887 | if (status & BIT1) |
1884 | icount->parity++; | 1888 | icount->parity++; |
1885 | else if (status & BIT0) | 1889 | else if (status & BIT0) |
@@ -3755,7 +3759,8 @@ static void slgt_cleanup(void) | |||
3755 | if (serial_driver) { | 3759 | if (serial_driver) { |
3756 | for (info=slgt_device_list ; info != NULL ; info=info->next_device) | 3760 | for (info=slgt_device_list ; info != NULL ; info=info->next_device) |
3757 | tty_unregister_device(serial_driver, info->line); | 3761 | tty_unregister_device(serial_driver, info->line); |
3758 | if ((rc = tty_unregister_driver(serial_driver))) | 3762 | rc = tty_unregister_driver(serial_driver); |
3763 | if (rc) | ||
3759 | DBGERR(("tty_unregister_driver error=%d\n", rc)); | 3764 | DBGERR(("tty_unregister_driver error=%d\n", rc)); |
3760 | put_tty_driver(serial_driver); | 3765 | put_tty_driver(serial_driver); |
3761 | } | 3766 | } |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index c3f90910fed9..08633a8139ff 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
@@ -1655,7 +1655,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
1655 | printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name); | 1655 | printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name); |
1656 | 1656 | ||
1657 | /* generic HDLC layer open processing */ | 1657 | /* generic HDLC layer open processing */ |
1658 | if ((rc = hdlc_open(dev))) | 1658 | rc = hdlc_open(dev); |
1659 | if (rc) | ||
1659 | return rc; | 1660 | return rc; |
1660 | 1661 | ||
1661 | /* arbitrate between network and tty opens */ | 1662 | /* arbitrate between network and tty opens */ |
@@ -1922,7 +1923,8 @@ static int hdlcdev_init(SLMP_INFO *info) | |||
1922 | 1923 | ||
1923 | /* allocate and initialize network and HDLC layer objects */ | 1924 | /* allocate and initialize network and HDLC layer objects */ |
1924 | 1925 | ||
1925 | if (!(dev = alloc_hdlcdev(info))) { | 1926 | dev = alloc_hdlcdev(info); |
1927 | if (!dev) { | ||
1926 | printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__); | 1928 | printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__); |
1927 | return -ENOMEM; | 1929 | return -ENOMEM; |
1928 | } | 1930 | } |
@@ -1943,7 +1945,8 @@ static int hdlcdev_init(SLMP_INFO *info) | |||
1943 | hdlc->xmit = hdlcdev_xmit; | 1945 | hdlc->xmit = hdlcdev_xmit; |
1944 | 1946 | ||
1945 | /* register objects with HDLC layer */ | 1947 | /* register objects with HDLC layer */ |
1946 | if ((rc = register_hdlc_device(dev))) { | 1948 | rc = register_hdlc_device(dev); |
1949 | if (rc) { | ||
1947 | printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); | 1950 | printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); |
1948 | free_netdev(dev); | 1951 | free_netdev(dev); |
1949 | return rc; | 1952 | return rc; |
@@ -3920,7 +3923,8 @@ static void synclinkmp_cleanup(void) | |||
3920 | printk("Unloading %s %s\n", driver_name, driver_version); | 3923 | printk("Unloading %s %s\n", driver_name, driver_version); |
3921 | 3924 | ||
3922 | if (serial_driver) { | 3925 | if (serial_driver) { |
3923 | if ((rc = tty_unregister_driver(serial_driver))) | 3926 | rc = tty_unregister_driver(serial_driver); |
3927 | if (rc) | ||
3924 | printk("%s(%d) failed to unregister tty driver err=%d\n", | 3928 | printk("%s(%d) failed to unregister tty driver err=%d\n", |
3925 | __FILE__,__LINE__,rc); | 3929 | __FILE__,__LINE__,rc); |
3926 | put_tty_driver(serial_driver); | 3930 | put_tty_driver(serial_driver); |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 2f78b77f0f81..4cf263d7dffc 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -286,7 +286,8 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, | |||
286 | change = (b->flags & TTYB_NORMAL) && (~flags & TTYB_NORMAL); | 286 | change = (b->flags & TTYB_NORMAL) && (~flags & TTYB_NORMAL); |
287 | if (change || left < size) { | 287 | if (change || left < size) { |
288 | /* This is the slow path - looking for new buffers to use */ | 288 | /* This is the slow path - looking for new buffers to use */ |
289 | if ((n = tty_buffer_alloc(port, size)) != NULL) { | 289 | n = tty_buffer_alloc(port, size); |
290 | if (n != NULL) { | ||
290 | n->flags = flags; | 291 | n->flags = flags; |
291 | buf->tail = n; | 292 | buf->tail = n; |
292 | b->commit = b->used; | 293 | b->commit = b->used; |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e5695467598f..57fc6ee12332 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -235,7 +235,6 @@ static void tty_del_file(struct file *file) | |||
235 | /** | 235 | /** |
236 | * tty_name - return tty naming | 236 | * tty_name - return tty naming |
237 | * @tty: tty structure | 237 | * @tty: tty structure |
238 | * @buf: buffer for output | ||
239 | * | 238 | * |
240 | * Convert a tty structure into a name. The name reflects the kernel | 239 | * Convert a tty structure into a name. The name reflects the kernel |
241 | * naming policy and if udev is in use may not reflect user space | 240 | * naming policy and if udev is in use may not reflect user space |
@@ -243,13 +242,11 @@ static void tty_del_file(struct file *file) | |||
243 | * Locking: none | 242 | * Locking: none |
244 | */ | 243 | */ |
245 | 244 | ||
246 | char *tty_name(struct tty_struct *tty, char *buf) | 245 | const char *tty_name(const struct tty_struct *tty) |
247 | { | 246 | { |
248 | if (!tty) /* Hmm. NULL pointer. That's fun. */ | 247 | if (!tty) /* Hmm. NULL pointer. That's fun. */ |
249 | strcpy(buf, "NULL tty"); | 248 | return "NULL tty"; |
250 | else | 249 | return tty->name; |
251 | strcpy(buf, tty->name); | ||
252 | return buf; | ||
253 | } | 250 | } |
254 | 251 | ||
255 | EXPORT_SYMBOL(tty_name); | 252 | EXPORT_SYMBOL(tty_name); |
@@ -770,8 +767,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
770 | void tty_hangup(struct tty_struct *tty) | 767 | void tty_hangup(struct tty_struct *tty) |
771 | { | 768 | { |
772 | #ifdef TTY_DEBUG_HANGUP | 769 | #ifdef TTY_DEBUG_HANGUP |
773 | char buf[64]; | 770 | printk(KERN_DEBUG "%s hangup...\n", tty_name(tty)); |
774 | printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf)); | ||
775 | #endif | 771 | #endif |
776 | schedule_work(&tty->hangup_work); | 772 | schedule_work(&tty->hangup_work); |
777 | } | 773 | } |
@@ -790,9 +786,7 @@ EXPORT_SYMBOL(tty_hangup); | |||
790 | void tty_vhangup(struct tty_struct *tty) | 786 | void tty_vhangup(struct tty_struct *tty) |
791 | { | 787 | { |
792 | #ifdef TTY_DEBUG_HANGUP | 788 | #ifdef TTY_DEBUG_HANGUP |
793 | char buf[64]; | 789 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty)); |
794 | |||
795 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); | ||
796 | #endif | 790 | #endif |
797 | __tty_hangup(tty, 0); | 791 | __tty_hangup(tty, 0); |
798 | } | 792 | } |
@@ -831,9 +825,7 @@ void tty_vhangup_self(void) | |||
831 | static void tty_vhangup_session(struct tty_struct *tty) | 825 | static void tty_vhangup_session(struct tty_struct *tty) |
832 | { | 826 | { |
833 | #ifdef TTY_DEBUG_HANGUP | 827 | #ifdef TTY_DEBUG_HANGUP |
834 | char buf[64]; | 828 | printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty)); |
835 | |||
836 | printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty, buf)); | ||
837 | #endif | 829 | #endif |
838 | __tty_hangup(tty, 1); | 830 | __tty_hangup(tty, 1); |
839 | } | 831 | } |
@@ -1769,7 +1761,6 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1769 | struct tty_struct *o_tty = NULL; | 1761 | struct tty_struct *o_tty = NULL; |
1770 | int do_sleep, final; | 1762 | int do_sleep, final; |
1771 | int idx; | 1763 | int idx; |
1772 | char buf[64]; | ||
1773 | long timeout = 0; | 1764 | long timeout = 0; |
1774 | int once = 1; | 1765 | int once = 1; |
1775 | 1766 | ||
@@ -1793,7 +1784,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1793 | 1784 | ||
1794 | #ifdef TTY_DEBUG_HANGUP | 1785 | #ifdef TTY_DEBUG_HANGUP |
1795 | printk(KERN_DEBUG "%s: %s (tty count=%d)...\n", __func__, | 1786 | printk(KERN_DEBUG "%s: %s (tty count=%d)...\n", __func__, |
1796 | tty_name(tty, buf), tty->count); | 1787 | tty_name(tty), tty->count); |
1797 | #endif | 1788 | #endif |
1798 | 1789 | ||
1799 | if (tty->ops->close) | 1790 | if (tty->ops->close) |
@@ -1844,7 +1835,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1844 | if (once) { | 1835 | if (once) { |
1845 | once = 0; | 1836 | once = 0; |
1846 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1837 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1847 | __func__, tty_name(tty, buf)); | 1838 | __func__, tty_name(tty)); |
1848 | } | 1839 | } |
1849 | schedule_timeout_killable(timeout); | 1840 | schedule_timeout_killable(timeout); |
1850 | if (timeout < 120 * HZ) | 1841 | if (timeout < 120 * HZ) |
@@ -1856,13 +1847,13 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1856 | if (o_tty) { | 1847 | if (o_tty) { |
1857 | if (--o_tty->count < 0) { | 1848 | if (--o_tty->count < 0) { |
1858 | printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n", | 1849 | printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n", |
1859 | __func__, o_tty->count, tty_name(o_tty, buf)); | 1850 | __func__, o_tty->count, tty_name(o_tty)); |
1860 | o_tty->count = 0; | 1851 | o_tty->count = 0; |
1861 | } | 1852 | } |
1862 | } | 1853 | } |
1863 | if (--tty->count < 0) { | 1854 | if (--tty->count < 0) { |
1864 | printk(KERN_WARNING "%s: bad tty->count (%d) for %s\n", | 1855 | printk(KERN_WARNING "%s: bad tty->count (%d) for %s\n", |
1865 | __func__, tty->count, tty_name(tty, buf)); | 1856 | __func__, tty->count, tty_name(tty)); |
1866 | tty->count = 0; | 1857 | tty->count = 0; |
1867 | } | 1858 | } |
1868 | 1859 | ||
@@ -1905,7 +1896,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1905 | return 0; | 1896 | return 0; |
1906 | 1897 | ||
1907 | #ifdef TTY_DEBUG_HANGUP | 1898 | #ifdef TTY_DEBUG_HANGUP |
1908 | printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty, buf)); | 1899 | printk(KERN_DEBUG "%s: %s: final close\n", __func__, tty_name(tty)); |
1909 | #endif | 1900 | #endif |
1910 | /* | 1901 | /* |
1911 | * Ask the line discipline code to release its structures | 1902 | * Ask the line discipline code to release its structures |
@@ -1916,7 +1907,8 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1916 | tty_flush_works(tty); | 1907 | tty_flush_works(tty); |
1917 | 1908 | ||
1918 | #ifdef TTY_DEBUG_HANGUP | 1909 | #ifdef TTY_DEBUG_HANGUP |
1919 | printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, tty_name(tty, buf)); | 1910 | printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, |
1911 | tty_name(tty)); | ||
1920 | #endif | 1912 | #endif |
1921 | /* | 1913 | /* |
1922 | * The release_tty function takes care of the details of clearing | 1914 | * The release_tty function takes care of the details of clearing |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 8e53fe469664..5232fb60b0b1 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -211,9 +211,7 @@ int tty_unthrottle_safe(struct tty_struct *tty) | |||
211 | void tty_wait_until_sent(struct tty_struct *tty, long timeout) | 211 | void tty_wait_until_sent(struct tty_struct *tty, long timeout) |
212 | { | 212 | { |
213 | #ifdef TTY_DEBUG_WAIT_UNTIL_SENT | 213 | #ifdef TTY_DEBUG_WAIT_UNTIL_SENT |
214 | char buf[64]; | 214 | printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty)); |
215 | |||
216 | printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf)); | ||
217 | #endif | 215 | #endif |
218 | if (!timeout) | 216 | if (!timeout) |
219 | timeout = MAX_SCHEDULE_TIMEOUT; | 217 | timeout = MAX_SCHEDULE_TIMEOUT; |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 3737f55272d2..c07fb5d9bcf9 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -22,9 +22,8 @@ | |||
22 | #undef LDISC_DEBUG_HANGUP | 22 | #undef LDISC_DEBUG_HANGUP |
23 | 23 | ||
24 | #ifdef LDISC_DEBUG_HANGUP | 24 | #ifdef LDISC_DEBUG_HANGUP |
25 | #define tty_ldisc_debug(tty, f, args...) ({ \ | 25 | #define tty_ldisc_debug(tty, f, args...) ({ \ |
26 | char __b[64]; \ | 26 | printk(KERN_DEBUG "%s: %s: " f, __func__, tty_name(tty), ##args); \ |
27 | printk(KERN_DEBUG "%s: %s: " f, __func__, tty_name(tty, __b), ##args); \ | ||
28 | }) | 27 | }) |
29 | #else | 28 | #else |
30 | #define tty_ldisc_debug(tty, f, args...) | 29 | #define tty_ldisc_debug(tty, f, args...) |
@@ -483,7 +482,6 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld) | |||
483 | 482 | ||
484 | static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | 483 | static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) |
485 | { | 484 | { |
486 | char buf[64]; | ||
487 | struct tty_ldisc *new_ldisc; | 485 | struct tty_ldisc *new_ldisc; |
488 | int r; | 486 | int r; |
489 | 487 | ||
@@ -504,7 +502,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | |||
504 | if (r < 0) | 502 | if (r < 0) |
505 | panic("Couldn't open N_TTY ldisc for " | 503 | panic("Couldn't open N_TTY ldisc for " |
506 | "%s --- error %d.", | 504 | "%s --- error %d.", |
507 | tty_name(tty, buf), r); | 505 | tty_name(tty), r); |
508 | } | 506 | } |
509 | } | 507 | } |
510 | 508 | ||
diff --git a/drivers/tty/tty_ldsem.c b/drivers/tty/tty_ldsem.c index 0ffb0cbe2823..ad7eba5ca380 100644 --- a/drivers/tty/tty_ldsem.c +++ b/drivers/tty/tty_ldsem.c | |||
@@ -299,7 +299,8 @@ down_write_failed(struct ld_semaphore *sem, long count, long timeout) | |||
299 | timeout = schedule_timeout(timeout); | 299 | timeout = schedule_timeout(timeout); |
300 | raw_spin_lock_irq(&sem->wait_lock); | 300 | raw_spin_lock_irq(&sem->wait_lock); |
301 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 301 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); |
302 | if ((locked = writer_trylock(sem))) | 302 | locked = writer_trylock(sem); |
303 | if (locked) | ||
303 | break; | 304 | break; |
304 | } | 305 | } |
305 | 306 | ||
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 59b25e039968..c8c91f0476a2 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c | |||
@@ -261,19 +261,22 @@ u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode) | |||
261 | int m; | 261 | int m; |
262 | if (glyph < 0 || glyph >= MAX_GLYPH) | 262 | if (glyph < 0 || glyph >= MAX_GLYPH) |
263 | return 0; | 263 | return 0; |
264 | else if (!(p = *conp->vc_uni_pagedir_loc)) | 264 | else { |
265 | return glyph; | 265 | p = *conp->vc_uni_pagedir_loc; |
266 | else if (use_unicode) { | 266 | if (!p) |
267 | if (!p->inverse_trans_unicode) | ||
268 | return glyph; | 267 | return glyph; |
269 | else | 268 | else if (use_unicode) { |
270 | return p->inverse_trans_unicode[glyph]; | 269 | if (!p->inverse_trans_unicode) |
271 | } else { | 270 | return glyph; |
272 | m = inv_translate[conp->vc_num]; | 271 | else |
273 | if (!p->inverse_translations[m]) | 272 | return p->inverse_trans_unicode[glyph]; |
274 | return glyph; | 273 | } else { |
275 | else | 274 | m = inv_translate[conp->vc_num]; |
276 | return p->inverse_translations[m][glyph]; | 275 | if (!p->inverse_translations[m]) |
276 | return glyph; | ||
277 | else | ||
278 | return p->inverse_translations[m][glyph]; | ||
279 | } | ||
277 | } | 280 | } |
278 | } | 281 | } |
279 | EXPORT_SYMBOL_GPL(inverse_translate); | 282 | EXPORT_SYMBOL_GPL(inverse_translate); |
@@ -397,7 +400,8 @@ static void con_release_unimap(struct uni_pagedir *p) | |||
397 | 400 | ||
398 | if (p == dflt) dflt = NULL; | 401 | if (p == dflt) dflt = NULL; |
399 | for (i = 0; i < 32; i++) { | 402 | for (i = 0; i < 32; i++) { |
400 | if ((p1 = p->uni_pgdir[i]) != NULL) { | 403 | p1 = p->uni_pgdir[i]; |
404 | if (p1 != NULL) { | ||
401 | for (j = 0; j < 32; j++) | 405 | for (j = 0; j < 32; j++) |
402 | kfree(p1[j]); | 406 | kfree(p1[j]); |
403 | kfree(p1); | 407 | kfree(p1); |
@@ -473,14 +477,16 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos) | |||
473 | int i, n; | 477 | int i, n; |
474 | u16 **p1, *p2; | 478 | u16 **p1, *p2; |
475 | 479 | ||
476 | if (!(p1 = p->uni_pgdir[n = unicode >> 11])) { | 480 | p1 = p->uni_pgdir[n = unicode >> 11]; |
481 | if (!p1) { | ||
477 | p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL); | 482 | p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL); |
478 | if (!p1) return -ENOMEM; | 483 | if (!p1) return -ENOMEM; |
479 | for (i = 0; i < 32; i++) | 484 | for (i = 0; i < 32; i++) |
480 | p1[i] = NULL; | 485 | p1[i] = NULL; |
481 | } | 486 | } |
482 | 487 | ||
483 | if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) { | 488 | p2 = p1[n = (unicode >> 6) & 0x1f]; |
489 | if (!p2) { | ||
484 | p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL); | 490 | p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL); |
485 | if (!p2) return -ENOMEM; | 491 | if (!p2) return -ENOMEM; |
486 | memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */ | 492 | memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */ |
@@ -569,10 +575,12 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) | |||
569 | * entries from "p" (old) to "q" (new). | 575 | * entries from "p" (old) to "q" (new). |
570 | */ | 576 | */ |
571 | l = 0; /* unicode value */ | 577 | l = 0; /* unicode value */ |
572 | for (i = 0; i < 32; i++) | 578 | for (i = 0; i < 32; i++) { |
573 | if ((p1 = p->uni_pgdir[i])) | 579 | p1 = p->uni_pgdir[i]; |
574 | for (j = 0; j < 32; j++) | 580 | if (p1) |
575 | if ((p2 = p1[j])) { | 581 | for (j = 0; j < 32; j++) { |
582 | p2 = p1[j]; | ||
583 | if (p2) { | ||
576 | for (k = 0; k < 64; k++, l++) | 584 | for (k = 0; k < 64; k++, l++) |
577 | if (p2[k] != 0xffff) { | 585 | if (p2[k] != 0xffff) { |
578 | /* | 586 | /* |
@@ -593,9 +601,11 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) | |||
593 | /* Account for row of 64 empty entries */ | 601 | /* Account for row of 64 empty entries */ |
594 | l += 64; | 602 | l += 64; |
595 | } | 603 | } |
604 | } | ||
596 | else | 605 | else |
597 | /* Account for empty table */ | 606 | /* Account for empty table */ |
598 | l += 32 * 64; | 607 | l += 32 * 64; |
608 | } | ||
599 | 609 | ||
600 | /* | 610 | /* |
601 | * Finished copying font table, set vc_uni_pagedir to new table | 611 | * Finished copying font table, set vc_uni_pagedir to new table |
@@ -735,10 +745,12 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni | |||
735 | ect = 0; | 745 | ect = 0; |
736 | if (*vc->vc_uni_pagedir_loc) { | 746 | if (*vc->vc_uni_pagedir_loc) { |
737 | p = *vc->vc_uni_pagedir_loc; | 747 | p = *vc->vc_uni_pagedir_loc; |
738 | for (i = 0; i < 32; i++) | 748 | for (i = 0; i < 32; i++) { |
739 | if ((p1 = p->uni_pgdir[i])) | 749 | p1 = p->uni_pgdir[i]; |
740 | for (j = 0; j < 32; j++) | 750 | if (p1) |
741 | if ((p2 = *(p1++))) | 751 | for (j = 0; j < 32; j++) { |
752 | p2 = *(p1++); | ||
753 | if (p2) | ||
742 | for (k = 0; k < 64; k++) { | 754 | for (k = 0; k < 64; k++) { |
743 | if (*p2 < MAX_GLYPH && ect++ < ct) { | 755 | if (*p2 < MAX_GLYPH && ect++ < ct) { |
744 | __put_user((u_short)((i<<11)+(j<<6)+k), | 756 | __put_user((u_short)((i<<11)+(j<<6)+k), |
@@ -749,6 +761,8 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni | |||
749 | } | 761 | } |
750 | p2++; | 762 | p2++; |
751 | } | 763 | } |
764 | } | ||
765 | } | ||
752 | } | 766 | } |
753 | __put_user(ect, uct); | 767 | __put_user(ect, uct); |
754 | console_unlock(); | 768 | console_unlock(); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4a24eb2b0ede..8fe52989b380 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -108,6 +108,7 @@ | |||
108 | #define CON_DRIVER_FLAG_MODULE 1 | 108 | #define CON_DRIVER_FLAG_MODULE 1 |
109 | #define CON_DRIVER_FLAG_INIT 2 | 109 | #define CON_DRIVER_FLAG_INIT 2 |
110 | #define CON_DRIVER_FLAG_ATTR 4 | 110 | #define CON_DRIVER_FLAG_ATTR 4 |
111 | #define CON_DRIVER_FLAG_ZOMBIE 8 | ||
111 | 112 | ||
112 | struct con_driver { | 113 | struct con_driver { |
113 | const struct consw *con; | 114 | const struct consw *con; |
@@ -135,6 +136,7 @@ const struct consw *conswitchp; | |||
135 | */ | 136 | */ |
136 | #define DEFAULT_BELL_PITCH 750 | 137 | #define DEFAULT_BELL_PITCH 750 |
137 | #define DEFAULT_BELL_DURATION (HZ/8) | 138 | #define DEFAULT_BELL_DURATION (HZ/8) |
139 | #define DEFAULT_CURSOR_BLINK_MS 200 | ||
138 | 140 | ||
139 | struct vc vc_cons [MAX_NR_CONSOLES]; | 141 | struct vc vc_cons [MAX_NR_CONSOLES]; |
140 | 142 | ||
@@ -153,6 +155,7 @@ static int set_vesa_blanking(char __user *p); | |||
153 | static void set_cursor(struct vc_data *vc); | 155 | static void set_cursor(struct vc_data *vc); |
154 | static void hide_cursor(struct vc_data *vc); | 156 | static void hide_cursor(struct vc_data *vc); |
155 | static void console_callback(struct work_struct *ignored); | 157 | static void console_callback(struct work_struct *ignored); |
158 | static void con_driver_unregister_callback(struct work_struct *ignored); | ||
156 | static void blank_screen_t(unsigned long dummy); | 159 | static void blank_screen_t(unsigned long dummy); |
157 | static void set_palette(struct vc_data *vc); | 160 | static void set_palette(struct vc_data *vc); |
158 | 161 | ||
@@ -182,6 +185,7 @@ static int blankinterval = 10*60; | |||
182 | core_param(consoleblank, blankinterval, int, 0444); | 185 | core_param(consoleblank, blankinterval, int, 0444); |
183 | 186 | ||
184 | static DECLARE_WORK(console_work, console_callback); | 187 | static DECLARE_WORK(console_work, console_callback); |
188 | static DECLARE_WORK(con_driver_unregister_work, con_driver_unregister_callback); | ||
185 | 189 | ||
186 | /* | 190 | /* |
187 | * fg_console is the current virtual console, | 191 | * fg_console is the current virtual console, |
@@ -1590,6 +1594,13 @@ static void setterm_command(struct vc_data *vc) | |||
1590 | case 15: /* activate the previous console */ | 1594 | case 15: /* activate the previous console */ |
1591 | set_console(last_console); | 1595 | set_console(last_console); |
1592 | break; | 1596 | break; |
1597 | case 16: /* set cursor blink duration in msec */ | ||
1598 | if (vc->vc_npar >= 1 && vc->vc_par[1] >= 50 && | ||
1599 | vc->vc_par[1] <= USHRT_MAX) | ||
1600 | vc->vc_cur_blink_ms = vc->vc_par[1]; | ||
1601 | else | ||
1602 | vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS; | ||
1603 | break; | ||
1593 | } | 1604 | } |
1594 | } | 1605 | } |
1595 | 1606 | ||
@@ -1717,6 +1728,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
1717 | 1728 | ||
1718 | vc->vc_bell_pitch = DEFAULT_BELL_PITCH; | 1729 | vc->vc_bell_pitch = DEFAULT_BELL_PITCH; |
1719 | vc->vc_bell_duration = DEFAULT_BELL_DURATION; | 1730 | vc->vc_bell_duration = DEFAULT_BELL_DURATION; |
1731 | vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS; | ||
1720 | 1732 | ||
1721 | gotoxy(vc, 0, 0); | 1733 | gotoxy(vc, 0, 0); |
1722 | save_cur(vc); | 1734 | save_cur(vc); |
@@ -3192,22 +3204,6 @@ err: | |||
3192 | 3204 | ||
3193 | 3205 | ||
3194 | #ifdef CONFIG_VT_HW_CONSOLE_BINDING | 3206 | #ifdef CONFIG_VT_HW_CONSOLE_BINDING |
3195 | static int con_is_graphics(const struct consw *csw, int first, int last) | ||
3196 | { | ||
3197 | int i, retval = 0; | ||
3198 | |||
3199 | for (i = first; i <= last; i++) { | ||
3200 | struct vc_data *vc = vc_cons[i].d; | ||
3201 | |||
3202 | if (vc && vc->vc_mode == KD_GRAPHICS) { | ||
3203 | retval = 1; | ||
3204 | break; | ||
3205 | } | ||
3206 | } | ||
3207 | |||
3208 | return retval; | ||
3209 | } | ||
3210 | |||
3211 | /* unlocked version of unbind_con_driver() */ | 3207 | /* unlocked version of unbind_con_driver() */ |
3212 | int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt) | 3208 | int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt) |
3213 | { | 3209 | { |
@@ -3293,8 +3289,7 @@ static int vt_bind(struct con_driver *con) | |||
3293 | const struct consw *defcsw = NULL, *csw = NULL; | 3289 | const struct consw *defcsw = NULL, *csw = NULL; |
3294 | int i, more = 1, first = -1, last = -1, deflt = 0; | 3290 | int i, more = 1, first = -1, last = -1, deflt = 0; |
3295 | 3291 | ||
3296 | if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) || | 3292 | if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE)) |
3297 | con_is_graphics(con->con, con->first, con->last)) | ||
3298 | goto err; | 3293 | goto err; |
3299 | 3294 | ||
3300 | csw = con->con; | 3295 | csw = con->con; |
@@ -3345,8 +3340,7 @@ static int vt_unbind(struct con_driver *con) | |||
3345 | int i, more = 1, first = -1, last = -1, deflt = 0; | 3340 | int i, more = 1, first = -1, last = -1, deflt = 0; |
3346 | int ret; | 3341 | int ret; |
3347 | 3342 | ||
3348 | if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) || | 3343 | if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE)) |
3349 | con_is_graphics(con->con, con->first, con->last)) | ||
3350 | goto err; | 3344 | goto err; |
3351 | 3345 | ||
3352 | csw = con->con; | 3346 | csw = con->con; |
@@ -3596,7 +3590,8 @@ static int do_register_con_driver(const struct consw *csw, int first, int last) | |||
3596 | for (i = 0; i < MAX_NR_CON_DRIVER; i++) { | 3590 | for (i = 0; i < MAX_NR_CON_DRIVER; i++) { |
3597 | con_driver = ®istered_con_driver[i]; | 3591 | con_driver = ®istered_con_driver[i]; |
3598 | 3592 | ||
3599 | if (con_driver->con == NULL) { | 3593 | if (con_driver->con == NULL && |
3594 | !(con_driver->flag & CON_DRIVER_FLAG_ZOMBIE)) { | ||
3600 | con_driver->con = csw; | 3595 | con_driver->con = csw; |
3601 | con_driver->desc = desc; | 3596 | con_driver->desc = desc; |
3602 | con_driver->node = i; | 3597 | con_driver->node = i; |
@@ -3658,16 +3653,20 @@ int do_unregister_con_driver(const struct consw *csw) | |||
3658 | struct con_driver *con_driver = ®istered_con_driver[i]; | 3653 | struct con_driver *con_driver = ®istered_con_driver[i]; |
3659 | 3654 | ||
3660 | if (con_driver->con == csw) { | 3655 | if (con_driver->con == csw) { |
3661 | vtconsole_deinit_device(con_driver); | 3656 | /* |
3662 | device_destroy(vtconsole_class, | 3657 | * Defer the removal of the sysfs entries since that |
3663 | MKDEV(0, con_driver->node)); | 3658 | * will acquire the kernfs s_active lock and we can't |
3659 | * acquire this lock while holding the console lock: | ||
3660 | * the unbind sysfs entry imposes already the opposite | ||
3661 | * order. Reset con already here to prevent any later | ||
3662 | * lookup to succeed and mark this slot as zombie, so | ||
3663 | * it won't get reused until we complete the removal | ||
3664 | * in the deferred work. | ||
3665 | */ | ||
3664 | con_driver->con = NULL; | 3666 | con_driver->con = NULL; |
3665 | con_driver->desc = NULL; | 3667 | con_driver->flag = CON_DRIVER_FLAG_ZOMBIE; |
3666 | con_driver->dev = NULL; | 3668 | schedule_work(&con_driver_unregister_work); |
3667 | con_driver->node = 0; | 3669 | |
3668 | con_driver->flag = 0; | ||
3669 | con_driver->first = 0; | ||
3670 | con_driver->last = 0; | ||
3671 | return 0; | 3670 | return 0; |
3672 | } | 3671 | } |
3673 | } | 3672 | } |
@@ -3676,6 +3675,39 @@ int do_unregister_con_driver(const struct consw *csw) | |||
3676 | } | 3675 | } |
3677 | EXPORT_SYMBOL_GPL(do_unregister_con_driver); | 3676 | EXPORT_SYMBOL_GPL(do_unregister_con_driver); |
3678 | 3677 | ||
3678 | static void con_driver_unregister_callback(struct work_struct *ignored) | ||
3679 | { | ||
3680 | int i; | ||
3681 | |||
3682 | console_lock(); | ||
3683 | |||
3684 | for (i = 0; i < MAX_NR_CON_DRIVER; i++) { | ||
3685 | struct con_driver *con_driver = ®istered_con_driver[i]; | ||
3686 | |||
3687 | if (!(con_driver->flag & CON_DRIVER_FLAG_ZOMBIE)) | ||
3688 | continue; | ||
3689 | |||
3690 | console_unlock(); | ||
3691 | |||
3692 | vtconsole_deinit_device(con_driver); | ||
3693 | device_destroy(vtconsole_class, MKDEV(0, con_driver->node)); | ||
3694 | |||
3695 | console_lock(); | ||
3696 | |||
3697 | if (WARN_ON_ONCE(con_driver->con)) | ||
3698 | con_driver->con = NULL; | ||
3699 | con_driver->desc = NULL; | ||
3700 | con_driver->dev = NULL; | ||
3701 | con_driver->node = 0; | ||
3702 | WARN_ON_ONCE(con_driver->flag != CON_DRIVER_FLAG_ZOMBIE); | ||
3703 | con_driver->flag = 0; | ||
3704 | con_driver->first = 0; | ||
3705 | con_driver->last = 0; | ||
3706 | } | ||
3707 | |||
3708 | console_unlock(); | ||
3709 | } | ||
3710 | |||
3679 | /* | 3711 | /* |
3680 | * If we support more console drivers, this function is used | 3712 | * If we support more console drivers, this function is used |
3681 | * when a driver wants to take over some existing consoles | 3713 | * when a driver wants to take over some existing consoles |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index b97210671a81..658c34bb9076 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -402,7 +402,7 @@ static void cursor_timer_handler(unsigned long dev_addr) | |||
402 | struct fbcon_ops *ops = info->fbcon_par; | 402 | struct fbcon_ops *ops = info->fbcon_par; |
403 | 403 | ||
404 | queue_work(system_power_efficient_wq, &info->queue); | 404 | queue_work(system_power_efficient_wq, &info->queue); |
405 | mod_timer(&ops->cursor_timer, jiffies + HZ/5); | 405 | mod_timer(&ops->cursor_timer, jiffies + ops->cur_blink_jiffies); |
406 | } | 406 | } |
407 | 407 | ||
408 | static void fbcon_add_cursor_timer(struct fb_info *info) | 408 | static void fbcon_add_cursor_timer(struct fb_info *info) |
@@ -417,7 +417,7 @@ static void fbcon_add_cursor_timer(struct fb_info *info) | |||
417 | 417 | ||
418 | init_timer(&ops->cursor_timer); | 418 | init_timer(&ops->cursor_timer); |
419 | ops->cursor_timer.function = cursor_timer_handler; | 419 | ops->cursor_timer.function = cursor_timer_handler; |
420 | ops->cursor_timer.expires = jiffies + HZ / 5; | 420 | ops->cursor_timer.expires = jiffies + ops->cur_blink_jiffies; |
421 | ops->cursor_timer.data = (unsigned long ) info; | 421 | ops->cursor_timer.data = (unsigned long ) info; |
422 | add_timer(&ops->cursor_timer); | 422 | add_timer(&ops->cursor_timer); |
423 | ops->flags |= FBCON_FLAGS_CURSOR_TIMER; | 423 | ops->flags |= FBCON_FLAGS_CURSOR_TIMER; |
@@ -1309,6 +1309,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode) | |||
1309 | if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1) | 1309 | if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1) |
1310 | return; | 1310 | return; |
1311 | 1311 | ||
1312 | ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms); | ||
1312 | if (vc->vc_cursor_type & 0x10) | 1313 | if (vc->vc_cursor_type & 0x10) |
1313 | fbcon_del_cursor_timer(info); | 1314 | fbcon_del_cursor_timer(info); |
1314 | else | 1315 | else |
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index 6bd2e0c7f209..7aaa4eabbba0 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h | |||
@@ -70,6 +70,7 @@ struct fbcon_ops { | |||
70 | struct fb_cursor cursor_state; | 70 | struct fb_cursor cursor_state; |
71 | struct display *p; | 71 | struct display *p; |
72 | int currcon; /* Current VC. */ | 72 | int currcon; /* Current VC. */ |
73 | int cur_blink_jiffies; | ||
73 | int cursor_flash; | 74 | int cursor_flash; |
74 | int cursor_reset; | 75 | int cursor_reset; |
75 | int blank_state; | 76 | int blank_state; |
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index e859c98d1767..e329ee2667e1 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h | |||
@@ -104,6 +104,7 @@ struct vc_data { | |||
104 | unsigned int vc_resize_user; /* resize request from user */ | 104 | unsigned int vc_resize_user; /* resize request from user */ |
105 | unsigned int vc_bell_pitch; /* Console bell pitch */ | 105 | unsigned int vc_bell_pitch; /* Console bell pitch */ |
106 | unsigned int vc_bell_duration; /* Console bell duration */ | 106 | unsigned int vc_bell_duration; /* Console bell duration */ |
107 | unsigned short vc_cur_blink_ms; /* Cursor blink duration */ | ||
107 | struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ | 108 | struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ |
108 | struct uni_pagedir *vc_uni_pagedir; | 109 | struct uni_pagedir *vc_uni_pagedir; |
109 | struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ | 110 | struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ |
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 78097e7a330a..ba82c07feb95 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define _LINUX_SERIAL_8250_H | 12 | #define _LINUX_SERIAL_8250_H |
13 | 13 | ||
14 | #include <linux/serial_core.h> | 14 | #include <linux/serial_core.h> |
15 | #include <linux/serial_reg.h> | ||
15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
16 | 17 | ||
17 | /* | 18 | /* |
@@ -137,6 +138,8 @@ extern int early_serial_setup(struct uart_port *port); | |||
137 | 138 | ||
138 | extern unsigned int serial8250_early_in(struct uart_port *port, int offset); | 139 | extern unsigned int serial8250_early_in(struct uart_port *port, int offset); |
139 | extern void serial8250_early_out(struct uart_port *port, int offset, int value); | 140 | extern void serial8250_early_out(struct uart_port *port, int offset, int value); |
141 | extern int early_serial8250_setup(struct earlycon_device *device, | ||
142 | const char *options); | ||
140 | extern void serial8250_do_set_termios(struct uart_port *port, | 143 | extern void serial8250_do_set_termios(struct uart_port *port, |
141 | struct ktermios *termios, struct ktermios *old); | 144 | struct ktermios *termios, struct ktermios *old); |
142 | extern int serial8250_do_startup(struct uart_port *port); | 145 | extern int serial8250_do_startup(struct uart_port *port); |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 025dad9dcde4..297d4fa1cfe5 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #define uart_console(port) \ | 35 | #define uart_console(port) \ |
36 | ((port)->cons && (port)->cons->index == (port)->line) | 36 | ((port)->cons && (port)->cons->index == (port)->line) |
37 | #else | 37 | #else |
38 | #define uart_console(port) (0) | 38 | #define uart_console(port) ({ (void)port; 0; }) |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | struct uart_port; | 41 | struct uart_port; |
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 6c5e3bb282b0..7c536ac5be05 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __LINUX_SERIAL_SCI_H | 1 | #ifndef __LINUX_SERIAL_SCI_H |
2 | #define __LINUX_SERIAL_SCI_H | 2 | #define __LINUX_SERIAL_SCI_H |
3 | 3 | ||
4 | #include <linux/bitops.h> | ||
4 | #include <linux/serial_core.h> | 5 | #include <linux/serial_core.h> |
5 | #include <linux/sh_dma.h> | 6 | #include <linux/sh_dma.h> |
6 | 7 | ||
@@ -10,59 +11,16 @@ | |||
10 | 11 | ||
11 | #define SCIx_NOT_SUPPORTED (-1) | 12 | #define SCIx_NOT_SUPPORTED (-1) |
12 | 13 | ||
13 | /* SCSMR (Serial Mode Register) */ | ||
14 | #define SCSMR_CHR (1 << 6) /* 7-bit Character Length */ | ||
15 | #define SCSMR_PE (1 << 5) /* Parity Enable */ | ||
16 | #define SCSMR_ODD (1 << 4) /* Odd Parity */ | ||
17 | #define SCSMR_STOP (1 << 3) /* Stop Bit Length */ | ||
18 | #define SCSMR_CKS 0x0003 /* Clock Select */ | ||
19 | |||
20 | /* Serial Control Register (@ = not supported by all parts) */ | 14 | /* Serial Control Register (@ = not supported by all parts) */ |
21 | #define SCSCR_TIE (1 << 7) /* Transmit Interrupt Enable */ | 15 | #define SCSCR_TIE BIT(7) /* Transmit Interrupt Enable */ |
22 | #define SCSCR_RIE (1 << 6) /* Receive Interrupt Enable */ | 16 | #define SCSCR_RIE BIT(6) /* Receive Interrupt Enable */ |
23 | #define SCSCR_TE (1 << 5) /* Transmit Enable */ | 17 | #define SCSCR_TE BIT(5) /* Transmit Enable */ |
24 | #define SCSCR_RE (1 << 4) /* Receive Enable */ | 18 | #define SCSCR_RE BIT(4) /* Receive Enable */ |
25 | #define SCSCR_REIE (1 << 3) /* Receive Error Interrupt Enable @ */ | 19 | #define SCSCR_REIE BIT(3) /* Receive Error Interrupt Enable @ */ |
26 | #define SCSCR_TOIE (1 << 2) /* Timeout Interrupt Enable @ */ | 20 | #define SCSCR_TOIE BIT(2) /* Timeout Interrupt Enable @ */ |
27 | #define SCSCR_CKE1 (1 << 1) /* Clock Enable 1 */ | 21 | #define SCSCR_CKE1 BIT(1) /* Clock Enable 1 */ |
28 | #define SCSCR_CKE0 (1 << 0) /* Clock Enable 0 */ | 22 | #define SCSCR_CKE0 BIT(0) /* Clock Enable 0 */ |
29 | /* SCIFA/SCIFB only */ | 23 | |
30 | #define SCSCR_TDRQE (1 << 15) /* Tx Data Transfer Request Enable */ | ||
31 | #define SCSCR_RDRQE (1 << 14) /* Rx Data Transfer Request Enable */ | ||
32 | |||
33 | /* SCxSR (Serial Status Register) on SCI */ | ||
34 | #define SCI_TDRE 0x80 /* Transmit Data Register Empty */ | ||
35 | #define SCI_RDRF 0x40 /* Receive Data Register Full */ | ||
36 | #define SCI_ORER 0x20 /* Overrun Error */ | ||
37 | #define SCI_FER 0x10 /* Framing Error */ | ||
38 | #define SCI_PER 0x08 /* Parity Error */ | ||
39 | #define SCI_TEND 0x04 /* Transmit End */ | ||
40 | |||
41 | #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) | ||
42 | |||
43 | /* SCxSR (Serial Status Register) on SCIF, HSCIF */ | ||
44 | #define SCIF_ER 0x0080 /* Receive Error */ | ||
45 | #define SCIF_TEND 0x0040 /* Transmission End */ | ||
46 | #define SCIF_TDFE 0x0020 /* Transmit FIFO Data Empty */ | ||
47 | #define SCIF_BRK 0x0010 /* Break Detect */ | ||
48 | #define SCIF_FER 0x0008 /* Framing Error */ | ||
49 | #define SCIF_PER 0x0004 /* Parity Error */ | ||
50 | #define SCIF_RDF 0x0002 /* Receive FIFO Data Full */ | ||
51 | #define SCIF_DR 0x0001 /* Receive Data Ready */ | ||
52 | |||
53 | #define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK) | ||
54 | |||
55 | /* SCFCR (FIFO Control Register) */ | ||
56 | #define SCFCR_LOOP (1 << 0) /* Loopback Test */ | ||
57 | |||
58 | /* SCSPTR (Serial Port Register), optional */ | ||
59 | #define SCSPTR_RTSIO (1 << 7) /* Serial Port RTS Pin Input/Output */ | ||
60 | #define SCSPTR_CTSIO (1 << 5) /* Serial Port CTS Pin Input/Output */ | ||
61 | #define SCSPTR_SPB2IO (1 << 1) /* Serial Port Break Input/Output */ | ||
62 | #define SCSPTR_SPB2DT (1 << 0) /* Serial Port Break Data */ | ||
63 | |||
64 | /* HSSRR HSCIF */ | ||
65 | #define HSCIF_SRE 0x8000 /* Sampling Rate Register Enable */ | ||
66 | 24 | ||
67 | enum { | 25 | enum { |
68 | SCIx_PROBE_REGTYPE, | 26 | SCIx_PROBE_REGTYPE, |
@@ -82,28 +40,6 @@ enum { | |||
82 | SCIx_NR_REGTYPES, | 40 | SCIx_NR_REGTYPES, |
83 | }; | 41 | }; |
84 | 42 | ||
85 | /* | ||
86 | * SCI register subset common for all port types. | ||
87 | * Not all registers will exist on all parts. | ||
88 | */ | ||
89 | enum { | ||
90 | SCSMR, /* Serial Mode Register */ | ||
91 | SCBRR, /* Bit Rate Register */ | ||
92 | SCSCR, /* Serial Control Register */ | ||
93 | SCxSR, /* Serial Status Register */ | ||
94 | SCFCR, /* FIFO Control Register */ | ||
95 | SCFDR, /* FIFO Data Count Register */ | ||
96 | SCxTDR, /* Transmit (FIFO) Data Register */ | ||
97 | SCxRDR, /* Receive (FIFO) Data Register */ | ||
98 | SCLSR, /* Line Status Register */ | ||
99 | SCTFDR, /* Transmit FIFO Data Count Register */ | ||
100 | SCRFDR, /* Receive FIFO Data Count Register */ | ||
101 | SCSPTR, /* Serial Port Register */ | ||
102 | HSSRR, /* Sampling Rate Register */ | ||
103 | |||
104 | SCIx_NR_REGS, | ||
105 | }; | ||
106 | |||
107 | struct device; | 43 | struct device; |
108 | 44 | ||
109 | struct plat_sci_port_ops { | 45 | struct plat_sci_port_ops { |
@@ -113,7 +49,7 @@ struct plat_sci_port_ops { | |||
113 | /* | 49 | /* |
114 | * Port-specific capabilities | 50 | * Port-specific capabilities |
115 | */ | 51 | */ |
116 | #define SCIx_HAVE_RTSCTS (1 << 0) | 52 | #define SCIx_HAVE_RTSCTS BIT(0) |
117 | 53 | ||
118 | /* | 54 | /* |
119 | * Platform device specific platform_data struct | 55 | * Platform device specific platform_data struct |
diff --git a/include/linux/tty.h b/include/linux/tty.h index d76631f615c2..ad6c8913aa3e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -422,7 +422,7 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) | |||
422 | 422 | ||
423 | extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, | 423 | extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, |
424 | const char *routine); | 424 | const char *routine); |
425 | extern char *tty_name(struct tty_struct *tty, char *buf); | 425 | extern const char *tty_name(const struct tty_struct *tty); |
426 | extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); | 426 | extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); |
427 | extern int tty_check_change(struct tty_struct *tty); | 427 | extern int tty_check_change(struct tty_struct *tty); |
428 | extern void __stop_tty(struct tty_struct *tty); | 428 | extern void __stop_tty(struct tty_struct *tty); |
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index baa7c80da6af..c1c23f19d4a2 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild | |||
@@ -138,6 +138,7 @@ header-y += genetlink.h | |||
138 | header-y += gen_stats.h | 138 | header-y += gen_stats.h |
139 | header-y += gfs2_ondisk.h | 139 | header-y += gfs2_ondisk.h |
140 | header-y += gigaset_dev.h | 140 | header-y += gigaset_dev.h |
141 | header-y += gsmmux.h | ||
141 | header-y += hdlcdrv.h | 142 | header-y += hdlcdrv.h |
142 | header-y += hdlc.h | 143 | header-y += hdlc.h |
143 | header-y += hdreg.h | 144 | header-y += hdreg.h |
diff --git a/include/linux/gsmmux.h b/include/uapi/linux/gsmmux.h index c25e9477f7c3..c06742d52856 100644 --- a/include/linux/gsmmux.h +++ b/include/uapi/linux/gsmmux.h | |||
@@ -1,6 +1,9 @@ | |||
1 | #ifndef _LINUX_GSMMUX_H | 1 | #ifndef _LINUX_GSMMUX_H |
2 | #define _LINUX_GSMMUX_H | 2 | #define _LINUX_GSMMUX_H |
3 | 3 | ||
4 | #include <linux/if.h> | ||
5 | #include <linux/ioctl.h> | ||
6 | |||
4 | struct gsm_config | 7 | struct gsm_config |
5 | { | 8 | { |
6 | unsigned int adaption; | 9 | unsigned int adaption; |
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index b2122813f18a..93ba148f923e 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h | |||
@@ -258,4 +258,7 @@ | |||
258 | /* Cris v10 / v32 SoC */ | 258 | /* Cris v10 / v32 SoC */ |
259 | #define PORT_CRIS 112 | 259 | #define PORT_CRIS 112 |
260 | 260 | ||
261 | /* STM32 USART */ | ||
262 | #define PORT_STM32 113 | ||
263 | |||
261 | #endif /* _UAPILINUX_SERIAL_CORE_H */ | 264 | #endif /* _UAPILINUX_SERIAL_CORE_H */ |
diff --git a/include/uapi/linux/tty_flags.h b/include/uapi/linux/tty_flags.h index fae4864737fa..072e41e45ee2 100644 --- a/include/uapi/linux/tty_flags.h +++ b/include/uapi/linux/tty_flags.h | |||
@@ -15,7 +15,7 @@ | |||
15 | #define ASYNCB_FOURPORT 1 /* Set OU1, OUT2 per AST Fourport settings */ | 15 | #define ASYNCB_FOURPORT 1 /* Set OU1, OUT2 per AST Fourport settings */ |
16 | #define ASYNCB_SAK 2 /* Secure Attention Key (Orange book) */ | 16 | #define ASYNCB_SAK 2 /* Secure Attention Key (Orange book) */ |
17 | #define ASYNCB_SPLIT_TERMIOS 3 /* [x] Separate termios for dialin/callout */ | 17 | #define ASYNCB_SPLIT_TERMIOS 3 /* [x] Separate termios for dialin/callout */ |
18 | #define ASYNCB_SPD_HI 4 /* Use 56000 instead of 38400 bps */ | 18 | #define ASYNCB_SPD_HI 4 /* Use 57600 instead of 38400 bps */ |
19 | #define ASYNCB_SPD_VHI 5 /* Use 115200 instead of 38400 bps */ | 19 | #define ASYNCB_SPD_VHI 5 /* Use 115200 instead of 38400 bps */ |
20 | #define ASYNCB_SKIP_TEST 6 /* Skip UART test during autoconfiguration */ | 20 | #define ASYNCB_SKIP_TEST 6 /* Skip UART test during autoconfiguration */ |
21 | #define ASYNCB_AUTO_IRQ 7 /* Do automatic IRQ during | 21 | #define ASYNCB_AUTO_IRQ 7 /* Do automatic IRQ during |