Pull tty / serial updates from Greg KH: "Here is the big set of tty/serial driver updates for 6.4-rc1. Nothing major, just lots of tiny, constant, forward development. This includes: - obligatory n_gsm updates and feature additions - 8250_em driver updates - sh-sci driver updates - dts cleanups and updates - general cleanups and improvements by Ilpo and Jiri - other small serial driver core fixes and driver updates All of these have been in linux-next for a while with no reported problems" * tag 'tty-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (87 commits) n_gsm: Use array_index_nospec() with index that comes from userspace tty: vt: drop checks for undefined VT_SINGLE_DRIVER tty: vt: distribute EXPORT_SYMBOL() tty: vt: simplify some cases in tioclinux() tty: vt: reformat tioclinux() tty: serial: sh-sci: Fix end of transmission on SCI tty: serial: sh-sci: Add support for tx end interrupt handling tty: serial: sh-sci: Fix TE setting on SCI IP tty: serial: sh-sci: Add RZ/G2L SCIFA DMA rx support tty: serial: sh-sci: Add RZ/G2L SCIFA DMA tx support serial: max310x: fix IO data corruption in batched operations serial: core: Disable uart_start() on uart_remove_one_port() serial: 8250: Reinit port->pm on port specific driver unbind serial: 8250: Add missing wakeup event reporting tty: serial: fsl_lpuart: use UARTMODIR register bits for lpuart32 platform tty: serial: fsl_lpuart: adjust buffer length to the intended size serial: fix TIOCSRS485 locking serial: make SiFive serial drivers depend on ARCH_ symbols tty: synclink_gt: don't allocate and pass dummy flags tty: serial: simplify qcom_geni_serial_send_chunk_fifo() ...
Unified · Split
| @@ -33,8 +33,11 @@ The format of this option is:: · 32 unmodified lines | |||
| 33 | 9600n8. The maximum baudrate is 115200. | 33 | 9600n8. The maximum baudrate is 115200. |
| 34 | 34 | ||
| 35 | You can specify multiple console= options on the kernel command line. | 35 | You can specify multiple console= options on the kernel command line. |
| 36 | Output will appear on all of them. The last device will be used when | 36 | |
| 37 | you open ``/dev/console``. So, for example:: | 37 | The behavior is well defined when each device type is mentioned only once. |
| 38 | In this case, the output will appear on all requested consoles. And | ||
| 39 | the last device will be used when you open ``/dev/console``. | ||
| 40 | So, for example:: | ||
| 38 | 41 | ||
| 39 | console=ttyS1,9600 console=tty0 | 42 | console=ttyS1,9600 console=tty0 |
| 40 | 43 | ||
| @@ -42,7 +45,34 @@ defines that opening ``/dev/console`` will get you the current foreground · 1 unmodified line | |||
| 42 | virtual console, and kernel messages will appear on both the VGA | 45 | virtual console, and kernel messages will appear on both the VGA |
| 43 | console and the 2nd serial port (ttyS1 or COM2) at 9600 baud. | 46 | console and the 2nd serial port (ttyS1 or COM2) at 9600 baud. |
| 44 | 47 | ||
| 45 | Note that you can only define one console per device type (serial, video). | 48 | The behavior is more complicated when the same device type is defined more |
| 49 | times. In this case, there are the following two rules: | ||
| 50 | |||
| 51 | 1. The output will appear only on the first device of each defined type. | ||
| 52 | |||
| 53 | 2. ``/dev/console`` will be associated with the first registered device. | ||
| 54 | Where the registration order depends on how kernel initializes various | ||
| 55 | subsystems. | ||
| 56 | |||
| 57 | This rule is used also when the last console= parameter is not used | ||
| 58 | for other reasons. For example, because of a typo or because | ||
| 59 | the hardware is not available. | ||
| 60 | |||
| 61 | The result might be surprising. For example, the following two command | ||
| 62 | lines have the same result: | ||
| 63 | |||
| 64 | console=ttyS1,9600 console=tty0 console=tty1 | ||
| 65 | console=tty0 console=ttyS1,9600 console=tty1 | ||
| 66 | |||
| 67 | The kernel messages are printed only on ``tty0`` and ``ttyS1``. And | ||
| 68 | ``/dev/console`` gets associated with ``tty0``. It is because kernel | ||
| 69 | tries to register graphical consoles before serial ones. It does it | ||
| 70 | because of the default behavior when no console device is specified, | ||
| 71 | see below. | ||
| 72 | |||
| 73 | Note that the last ``console=tty1`` parameter still makes a difference. | ||
| 74 | The kernel command line is used also by systemd. It would use the last | ||
| 75 | defined ``tty1`` as the login console. | ||
| 46 | 76 | ||
| 47 | If no console device is specified, the first device found capable of | 77 | If no console device is specified, the first device found capable of |
| 48 | acting as a system console will be used. At this time, the system | 78 | acting as a system console will be used. At this time, the system |
| @@ -2,8 +2,8 @@ · 1 unmodified line | |||
| 2 | # Copyright 2019 BayLibre, SAS | 2 | # Copyright 2019 BayLibre, SAS |
| 3 | %YAML 1.2 | 3 | %YAML 1.2 |
| 4 | --- | 4 | --- |
| 5 | $id: "http://devicetree.org/schemas/serial/amlogic,meson-uart.yaml#" | 5 | $id: http://devicetree.org/schemas/serial/amlogic,meson-uart.yaml# |
| 6 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 6 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 7 | 7 | ||
| 8 | title: Amlogic Meson SoC UART Serial Interface | 8 | title: Amlogic Meson SoC UART Serial Interface |
| 9 | 9 | ||
| @@ -34,6 +34,11 @@ properties: · 24 unmodified lines | |||
| 34 | - amlogic,meson-gx-uart | 34 | - amlogic,meson-gx-uart |
| 35 | - amlogic,meson-s4-uart | 35 | - amlogic,meson-s4-uart |
| 36 | - const: amlogic,meson-ao-uart | 36 | - const: amlogic,meson-ao-uart |
| 37 | - description: Always-on power domain UART controller on G12A SoCs | ||
| 38 | items: | ||
| 39 | - const: amlogic,meson-g12a-uart | ||
| 40 | - const: amlogic,meson-gx-uart | ||
| 41 | - const: amlogic,meson-ao-uart | ||
| 37 | - description: Everything-Else power domain UART controller | 42 | - description: Everything-Else power domain UART controller |
| 38 | enum: | 43 | enum: |
| 39 | - amlogic,meson6-uart | 44 | - amlogic,meson6-uart |
| @@ -41,6 +46,10 @@ properties: · 1 unmodified line | |||
| 41 | - amlogic,meson8b-uart | 46 | - amlogic,meson8b-uart |
| 42 | - amlogic,meson-gx-uart | 47 | - amlogic,meson-gx-uart |
| 43 | - amlogic,meson-s4-uart | 48 | - amlogic,meson-s4-uart |
| 49 | - description: Everything-Else power domain UART controller on G12A SoCs | ||
| 50 | items: | ||
| 51 | - const: amlogic,meson-g12a-uart | ||
| 52 | - const: amlogic,meson-gx-uart | ||
| 44 | 53 | ||
| 45 | reg: | 54 | reg: |
| 46 | maxItems: 1 | 55 | maxItems: 1 |
| @@ -49,6 +49,24 @@ properties: · 48 unmodified lines | |||
| 49 | reg: | 49 | reg: |
| 50 | maxItems: 1 | 50 | maxItems: 1 |
| 51 | 51 | ||
| 52 | clocks: | ||
| 53 | maxItems: 2 | ||
| 54 | |||
| 55 | clock-names: | ||
| 56 | items: | ||
| 57 | - const: ipg | ||
| 58 | - const: per | ||
| 59 | |||
| 60 | dmas: | ||
| 61 | items: | ||
| 62 | - description: DMA controller phandle and request line for RX | ||
| 63 | - description: DMA controller phandle and request line for TX | ||
| 64 | |||
| 65 | dma-names: | ||
| 66 | items: | ||
| 67 | - const: rx | ||
| 68 | - const: tx | ||
| 69 | |||
| 52 | interrupts: | 70 | interrupts: |
| 53 | maxItems: 1 | 71 | maxItems: 1 |
| 54 | 72 | ||
| @@ -86,12 +104,16 @@ properties: · 31 unmodified lines | |||
| 86 | required: | 104 | required: |
| 87 | - compatible | 105 | - compatible |
| 88 | - reg | 106 | - reg |
| 107 | - clocks | ||
| 108 | - clock-names | ||
| 89 | - interrupts | 109 | - interrupts |
| 90 | 110 | ||
| 91 | unevaluatedProperties: false | 111 | unevaluatedProperties: false |
| 92 | 112 | ||
| 93 | examples: | 113 | examples: |
| 94 | - | | 114 | - | |
| 115 | #include <dt-bindings/clock/imx5-clock.h> | ||
| 116 | |||
| 95 | aliases { | 117 | aliases { |
| 96 | serial0 = &uart1; | 118 | serial0 = &uart1; |
| 97 | }; | 119 | }; |
| @@ -100,6 +122,11 @@ examples: · 2 unmodified lines | |||
| 100 | compatible = "fsl,imx51-uart", "fsl,imx21-uart"; | 122 | compatible = "fsl,imx51-uart", "fsl,imx21-uart"; |
| 101 | reg = <0x73fbc000 0x4000>; | 123 | reg = <0x73fbc000 0x4000>; |
| 102 | interrupts = <31>; | 124 | interrupts = <31>; |
| 125 | clocks = <&clks IMX5_CLK_UART1_IPG_GATE>, | ||
| 126 | <&clks IMX5_CLK_UART1_PER_GATE>; | ||
| 127 | clock-names = "ipg", "per"; | ||
| 128 | dmas = <&sdma 18 4 1>, <&sdma 19 4 2>; | ||
| 129 | dma-names = "rx", "tx"; | ||
| 103 | uart-has-rtscts; | 130 | uart-has-rtscts; |
| 104 | fsl,dte-mode; | 131 | fsl,dte-mode; |
| 105 | }; | 132 | }; |
| @@ -65,6 +65,9 @@ properties: · 64 unmodified lines | |||
| 65 | - const: rx | 65 | - const: rx |
| 66 | - const: tx | 66 | - const: tx |
| 67 | 67 | ||
| 68 | power-domains: | ||
| 69 | maxItems: 1 | ||
| 70 | |||
| 68 | required: | 71 | required: |
| 69 | - compatible | 72 | - compatible |
| 70 | - reg | 73 | - reg |
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: "http://devicetree.org/schemas/serial/qcom,serial-geni-qcom.yaml#" | 4 | $id: http://devicetree.org/schemas/serial/qcom,serial-geni-qcom.yaml# |
| 5 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Qualcomm Geni based QUP UART interface | 7 | title: Qualcomm Geni based QUP UART interface |
| 8 | 8 | ||
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: "http://devicetree.org/schemas/serial/renesas,em-uart.yaml#" | 4 | $id: http://devicetree.org/schemas/serial/renesas,em-uart.yaml# |
| 5 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Renesas EMMA Mobile UART Interface | 7 | title: Renesas EMMA Mobile UART Interface |
| 8 | 8 | ||
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: "http://devicetree.org/schemas/serial/renesas,hscif.yaml#" | 4 | $id: http://devicetree.org/schemas/serial/renesas,hscif.yaml# |
| 5 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Renesas High Speed Serial Communication Interface with FIFO (HSCIF) | 7 | title: Renesas High Speed Serial Communication Interface with FIFO (HSCIF) |
| 8 | 8 | ||
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: "http://devicetree.org/schemas/serial/renesas,sci.yaml#" | 4 | $id: http://devicetree.org/schemas/serial/renesas,sci.yaml# |
| 5 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Renesas Serial Communication Interface | 7 | title: Renesas Serial Communication Interface |
| 8 | 8 | ||
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: "http://devicetree.org/schemas/serial/renesas,scif.yaml#" | 4 | $id: http://devicetree.org/schemas/serial/renesas,scif.yaml# |
| 5 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Renesas Serial Communication Interface with FIFO (SCIF) | 7 | title: Renesas Serial Communication Interface with FIFO (SCIF) |
| 8 | 8 | ||
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: "http://devicetree.org/schemas/serial/renesas,scifa.yaml#" | 4 | $id: http://devicetree.org/schemas/serial/renesas,scifa.yaml# |
| 5 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Renesas Serial Communications Interface with FIFO A (SCIFA) | 7 | title: Renesas Serial Communications Interface with FIFO A (SCIFA) |
| 8 | 8 | ||
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: "http://devicetree.org/schemas/serial/renesas,scifb.yaml#" | 4 | $id: http://devicetree.org/schemas/serial/renesas,scifb.yaml# |
| 5 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Renesas Serial Communications Interface with FIFO B (SCIFB) | 7 | title: Renesas Serial Communications Interface with FIFO B (SCIFB) |
| 8 | 8 | ||
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 | 2 | %YAML 1.2 |
| 3 | --- | 3 | --- |
| 4 | $id: "http://devicetree.org/schemas/serial/serial.yaml#" | 4 | $id: http://devicetree.org/schemas/serial/serial.yaml# |
| 5 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | ||
| 7 | title: Serial Interface Generic | 7 | title: Serial Interface Generic |
| 8 | 8 | ||
| @@ -68,12 +68,12 @@ properties: · 67 unmodified lines | |||
| 68 | - const: apb_pclk | 68 | - const: apb_pclk |
| 69 | 69 | ||
| 70 | dmas: | 70 | dmas: |
| 71 | minItems: 2 | 71 | maxItems: 2 |
| 72 | 72 | ||
| 73 | dma-names: | 73 | dma-names: |
| 74 | items: | 74 | items: |
| 75 | - const: rx | ||
| 76 | - const: tx | 75 | - const: tx |
| 76 | - const: rx | ||
| 77 | 77 | ||
| 78 | snps,uart-16550-compatible: | 78 | snps,uart-16550-compatible: |
| 79 | description: reflects the value of UART_16550_COMPATIBLE configuration | 79 | description: reflects the value of UART_16550_COMPATIBLE configuration |
| @@ -2,8 +2,8 @@ · 1 unmodified line | |||
| 2 | # Copyright 2019 Unisoc Inc. | 2 | # Copyright 2019 Unisoc Inc. |
| 3 | %YAML 1.2 | 3 | %YAML 1.2 |
| 4 | --- | 4 | --- |
| 5 | $id: "http://devicetree.org/schemas/serial/sprd-uart.yaml#" | 5 | $id: http://devicetree.org/schemas/serial/sprd-uart.yaml# |
| 6 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 6 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 7 | 7 | ||
| 8 | title: Spreadtrum serial UART | 8 | title: Spreadtrum serial UART |
| 9 | 9 | ||
| @@ -2,8 +2,8 @@ · 1 unmodified line | |||
| 2 | # Copyright (C) Sunplus Co., Ltd. 2021 | 2 | # Copyright (C) Sunplus Co., Ltd. 2021 |
| 3 | %YAML 1.2 | 3 | %YAML 1.2 |
| 4 | --- | 4 | --- |
| 5 | $id: "http://devicetree.org/schemas/serial/sunplus,sp7021-uart.yaml#" | 5 | $id: http://devicetree.org/schemas/serial/sunplus,sp7021-uart.yaml# |
| 6 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | 6 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 7 | 7 | ||
| 8 | title: Sunplus SoC SP7021 UART Controller | 8 | title: Sunplus SoC SP7021 UART Controller |
| 9 | 9 | ||
| @@ -29,6 +29,8 @@ Config Initiator · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl. | 30 | #. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl. |
| 31 | 31 | ||
| 32 | #. Configure DLCs using ``GSMIOC_GETCONF_DLCI``/``GSMIOC_SETCONF_DLCI`` ioctl for non-defaults. | ||
| 33 | |||
| 32 | #. Obtain base gsmtty number for the used serial port. | 34 | #. Obtain base gsmtty number for the used serial port. |
| 33 | 35 | ||
| 34 | Major parts of the initialization program | 36 | Major parts of the initialization program |
| @@ -45,6 +47,7 @@ Config Initiator · 10 unmodified lines | |||
| 45 | int ldisc = N_GSM0710; | 47 | int ldisc = N_GSM0710; |
| 46 | struct gsm_config c; | 48 | struct gsm_config c; |
| 47 | struct gsm_config_ext ce; | 49 | struct gsm_config_ext ce; |
| 50 | struct gsm_dlci_config dc; | ||
| 48 | struct termios configuration; | 51 | struct termios configuration; |
| 49 | uint32_t first; | 52 | uint32_t first; |
| 50 | 53 | ||
| @@ -81,6 +84,13 @@ Config Initiator · 30 unmodified lines | |||
| 81 | c.mtu = 127; | 84 | c.mtu = 127; |
| 82 | /* set the new configuration */ | 85 | /* set the new configuration */ |
| 83 | ioctl(fd, GSMIOC_SETCONF, &c); | 86 | ioctl(fd, GSMIOC_SETCONF, &c); |
| 87 | /* get DLC 1 configuration */ | ||
| 88 | dc.channel = 1; | ||
| 89 | ioctl(fd, GSMIOC_GETCONF_DLCI, &dc); | ||
| 90 | /* the first user channel gets a higher priority */ | ||
| 91 | dc.priority = 1; | ||
| 92 | /* set the new DLC 1 specific configuration */ | ||
| 93 | ioctl(fd, GSMIOC_SETCONF_DLCI, &dc); | ||
| 84 | /* get first gsmtty device node */ | 94 | /* get first gsmtty device node */ |
| 85 | ioctl(fd, GSMIOC_GETFIRST, &first); | 95 | ioctl(fd, GSMIOC_GETFIRST, &first); |
| 86 | printf("first muxed line: /dev/gsmtty%i\n", first); | 96 | printf("first muxed line: /dev/gsmtty%i\n", first); |
| @@ -120,6 +130,8 @@ Config Requester · 33 unmodified lines | |||
| 120 | 130 | ||
| 121 | #. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl. | 131 | #. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl. |
| 122 | 132 | ||
| 133 | #. Configure DLCs using ``GSMIOC_GETCONF_DLCI``/``GSMIOC_SETCONF_DLCI`` ioctl for non-defaults. | ||
| 134 | |||
| 123 | #. Obtain base gsmtty number for the used serial port:: | 135 | #. Obtain base gsmtty number for the used serial port:: |
| 124 | 136 | ||
| 125 | #include <stdio.h> | 137 | #include <stdio.h> |
| @@ -132,6 +144,7 @@ Config Requester · 6 unmodified lines | |||
| 132 | int ldisc = N_GSM0710; | 144 | int ldisc = N_GSM0710; |
| 133 | struct gsm_config c; | 145 | struct gsm_config c; |
| 134 | struct gsm_config_ext ce; | 146 | struct gsm_config_ext ce; |
| 147 | struct gsm_dlci_config dc; | ||
| 135 | struct termios configuration; | 148 | struct termios configuration; |
| 136 | uint32_t first; | 149 | uint32_t first; |
| 137 | 150 | ||
| @@ -161,6 +174,13 @@ Config Requester · 23 unmodified lines | |||
| 161 | c.mtu = 127; | 174 | c.mtu = 127; |
| 162 | /* set the new configuration */ | 175 | /* set the new configuration */ |
| 163 | ioctl(fd, GSMIOC_SETCONF, &c); | 176 | ioctl(fd, GSMIOC_SETCONF, &c); |
| 177 | /* get DLC 1 configuration */ | ||
| 178 | dc.channel = 1; | ||
| 179 | ioctl(fd, GSMIOC_GETCONF_DLCI, &dc); | ||
| 180 | /* the first user channel gets a higher priority */ | ||
| 181 | dc.priority = 1; | ||
| 182 | /* set the new DLC 1 specific configuration */ | ||
| 183 | ioctl(fd, GSMIOC_SETCONF_DLCI, &dc); | ||
| 164 | /* get first gsmtty device node */ | 184 | /* get first gsmtty device node */ |
| 165 | ioctl(fd, GSMIOC_GETFIRST, &first); | 185 | ioctl(fd, GSMIOC_GETFIRST, &first); |
| 166 | printf("first muxed line: /dev/gsmtty%i\n", first); | 186 | printf("first muxed line: /dev/gsmtty%i\n", first); |
| @@ -2045,7 +2045,8 @@ · 2044 unmodified lines | |||
| 2045 | }; | 2045 | }; |
| 2046 | 2046 | ||
| 2047 | uart_AO: serial@3000 { | 2047 | uart_AO: serial@3000 { |
| 2048 | compatible = "amlogic,meson-gx-uart", | 2048 | compatible = "amlogic,meson-g12a-uart", |
| 2049 | "amlogic,meson-gx-uart", | ||
| 2049 | "amlogic,meson-ao-uart"; | 2050 | "amlogic,meson-ao-uart"; |
| 2050 | reg = <0x0 0x3000 0x0 0x18>; | 2051 | reg = <0x0 0x3000 0x0 0x18>; |
| 2051 | interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>; | 2052 | interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>; |
| @@ -2055,7 +2056,8 @@ · 3 unmodified lines | |||
| 2055 | }; | 2056 | }; |
| 2056 | 2057 | ||
| 2057 | uart_AO_B: serial@4000 { | 2058 | uart_AO_B: serial@4000 { |
| 2058 | compatible = "amlogic,meson-gx-uart", | 2059 | compatible = "amlogic,meson-g12a-uart", |
| 2060 | "amlogic,meson-gx-uart", | ||
| 2059 | "amlogic,meson-ao-uart"; | 2061 | "amlogic,meson-ao-uart"; |
| 2060 | reg = <0x0 0x4000 0x0 0x18>; | 2062 | reg = <0x0 0x4000 0x0 0x18>; |
| 2061 | interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>; | 2063 | interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>; |
| @@ -2292,7 +2294,8 @@ · 230 unmodified lines | |||
| 2292 | }; | 2294 | }; |
| 2293 | 2295 | ||
| 2294 | uart_C: serial@22000 { | 2296 | uart_C: serial@22000 { |
| 2295 | compatible = "amlogic,meson-gx-uart"; | 2297 | compatible = "amlogic,meson-g12a-uart", |
| 2298 | "amlogic,meson-gx-uart"; | ||
| 2296 | reg = <0x0 0x22000 0x0 0x18>; | 2299 | reg = <0x0 0x22000 0x0 0x18>; |
| 2297 | interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>; | 2300 | interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>; |
| 2298 | clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; | 2301 | clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; |
| @@ -2301,7 +2304,8 @@ · 2 unmodified lines | |||
| 2301 | }; | 2304 | }; |
| 2302 | 2305 | ||
| 2303 | uart_B: serial@23000 { | 2306 | uart_B: serial@23000 { |
| 2304 | compatible = "amlogic,meson-gx-uart"; | 2307 | compatible = "amlogic,meson-g12a-uart", |
| 2308 | "amlogic,meson-gx-uart"; | ||
| 2305 | reg = <0x0 0x23000 0x0 0x18>; | 2309 | reg = <0x0 0x23000 0x0 0x18>; |
| 2306 | interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>; | 2310 | interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>; |
| 2307 | clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; | 2311 | clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; |
| @@ -2310,7 +2314,8 @@ · 2 unmodified lines | |||
| 2310 | }; | 2314 | }; |
| 2311 | 2315 | ||
| 2312 | uart_A: serial@24000 { | 2316 | uart_A: serial@24000 { |
| 2313 | compatible = "amlogic,meson-gx-uart"; | 2317 | compatible = "amlogic,meson-g12a-uart", |
| 2318 | "amlogic,meson-gx-uart"; | ||
| 2314 | reg = <0x0 0x24000 0x0 0x18>; | 2319 | reg = <0x0 0x24000 0x0 0x18>; |
| 2315 | interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>; | 2320 | interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>; |
| 2316 | clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; | 2321 | clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; |
| @@ -1060,7 +1060,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) · 1059 unmodified lines | |||
| 1060 | if (info->serial_signals & SerialSignal_CTS) { | 1060 | if (info->serial_signals & SerialSignal_CTS) { |
| 1061 | if (debug_level >= DEBUG_LEVEL_ISR) | 1061 | if (debug_level >= DEBUG_LEVEL_ISR) |
| 1062 | printk("CTS tx start..."); | 1062 | printk("CTS tx start..."); |
| 1063 | tty->hw_stopped = 0; | 1063 | tty->hw_stopped = false; |
| 1064 | tx_start(info, tty); | 1064 | tx_start(info, tty); |
| 1065 | info->pending_bh |= BH_TRANSMIT; | 1065 | info->pending_bh |= BH_TRANSMIT; |
| 1066 | return; | 1066 | return; |
| @@ -1069,7 +1069,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) · 2 unmodified lines | |||
| 1069 | if (!(info->serial_signals & SerialSignal_CTS)) { | 1069 | if (!(info->serial_signals & SerialSignal_CTS)) { |
| 1070 | if (debug_level >= DEBUG_LEVEL_ISR) | 1070 | if (debug_level >= DEBUG_LEVEL_ISR) |
| 1071 | printk("CTS tx stop..."); | 1071 | printk("CTS tx stop..."); |
| 1072 | tty->hw_stopped = 1; | 1072 | tty->hw_stopped = true; |
| 1073 | tx_stop(info); | 1073 | tx_stop(info); |
| 1074 | } | 1074 | } |
| 1075 | } | 1075 | } |
| @@ -2312,7 +2312,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, · 1236 unmodified lines | |||
| 2312 | 2312 | ||
| 2313 | /* Handle turning off CRTSCTS */ | 2313 | /* Handle turning off CRTSCTS */ |
| 2314 | if (old_termios->c_cflag & CRTSCTS && !C_CRTSCTS(tty)) { | 2314 | if (old_termios->c_cflag & CRTSCTS && !C_CRTSCTS(tty)) { |
| 2315 | tty->hw_stopped = 0; | 2315 | tty->hw_stopped = false; |
| 2316 | tx_release(tty); | 2316 | tx_release(tty); |
| 2317 | } | 2317 | } |
| 2318 | } | 2318 | } |
| @@ -478,13 +478,13 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port) · 477 unmodified lines | |||
| 478 | int cts = (status & UART_MSR_CTS); | 478 | int cts = (status & UART_MSR_CTS); |
| 479 | if (tty->hw_stopped) { | 479 | if (tty->hw_stopped) { |
| 480 | if (cts) { | 480 | if (cts) { |
| 481 | tty->hw_stopped = 0; | 481 | tty->hw_stopped = false; |
| 482 | sdio_uart_start_tx(port); | 482 | sdio_uart_start_tx(port); |
| 483 | tty_wakeup(tty); | 483 | tty_wakeup(tty); |
| 484 | } | 484 | } |
| 485 | } else { | 485 | } else { |
| 486 | if (!cts) { | 486 | if (!cts) { |
| 487 | tty->hw_stopped = 1; | 487 | tty->hw_stopped = true; |
| 488 | sdio_uart_stop_tx(port); | 488 | sdio_uart_stop_tx(port); |
| 489 | } | 489 | } |
| 490 | } | 490 | } |
| @@ -633,7 +633,7 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty) · 142 unmodified lines | |||
| 633 | 633 | ||
| 634 | if (C_CRTSCTS(tty)) | 634 | if (C_CRTSCTS(tty)) |
| 635 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) | 635 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) |
| 636 | tty->hw_stopped = 1; | 636 | tty->hw_stopped = true; |
| 637 | 637 | ||
| 638 | clear_bit(TTY_IO_ERROR, &tty->flags); | 638 | clear_bit(TTY_IO_ERROR, &tty->flags); |
| 639 | 639 | ||
| @@ -882,14 +882,14 @@ static void sdio_uart_set_termios(struct tty_struct *tty, · 242 unmodified lines | |||
| 882 | 882 | ||
| 883 | /* Handle turning off CRTSCTS */ | 883 | /* Handle turning off CRTSCTS */ |
| 884 | if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { | 884 | if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { |
| 885 | tty->hw_stopped = 0; | 885 | tty->hw_stopped = false; |
| 886 | sdio_uart_start_tx(port); | 886 | sdio_uart_start_tx(port); |
| 887 | } | 887 | } |
| 888 | 888 | ||
| 889 | /* Handle turning on CRTSCTS */ | 889 | /* Handle turning on CRTSCTS */ |
| 890 | if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { | 890 | if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { |
| 891 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) { | 891 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) { |
| 892 | tty->hw_stopped = 1; | 892 | tty->hw_stopped = true; |
| 893 | sdio_uart_stop_tx(port); | 893 | sdio_uart_stop_tx(port); |
| 894 | } | 894 | } |
| 895 | } | 895 | } |
| @@ -160,7 +160,7 @@ config LEGACY_TIOCSTI · 159 unmodified lines | |||
| 160 | a dangerous legacy operation, and can be disabled on most | 160 | a dangerous legacy operation, and can be disabled on most |
| 161 | systems. | 161 | systems. |
| 162 | 162 | ||
| 163 | Say 'Y here only if you have confirmed that your system's | 163 | Say Y here only if you have confirmed that your system's |
| 164 | userspace depends on this functionality to continue operating | 164 | userspace depends on this functionality to continue operating |
| 165 | normally. | 165 | normally. |
| 166 | 166 | ||
| @@ -347,7 +347,7 @@ static void check_modem_status(struct serial_state *info) · 346 unmodified lines | |||
| 347 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) | 347 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) |
| 348 | printk("CTS tx start..."); | 348 | printk("CTS tx start..."); |
| 349 | #endif | 349 | #endif |
| 350 | port->tty->hw_stopped = 0; | 350 | port->tty->hw_stopped = false; |
| 351 | info->IER |= UART_IER_THRI; | 351 | info->IER |= UART_IER_THRI; |
| 352 | amiga_custom.intena = IF_SETCLR | IF_TBE; | 352 | amiga_custom.intena = IF_SETCLR | IF_TBE; |
| 353 | mb(); | 353 | mb(); |
| @@ -362,7 +362,7 @@ static void check_modem_status(struct serial_state *info) · 8 unmodified lines | |||
| 362 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) | 362 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) |
| 363 | printk("CTS tx stop..."); | 363 | printk("CTS tx stop..."); |
| 364 | #endif | 364 | #endif |
| 365 | port->tty->hw_stopped = 1; | 365 | port->tty->hw_stopped = true; |
| 366 | info->IER &= ~UART_IER_THRI; | 366 | info->IER &= ~UART_IER_THRI; |
| 367 | /* disable Tx interrupt and remove any pending interrupts */ | 367 | /* disable Tx interrupt and remove any pending interrupts */ |
| 368 | amiga_custom.intena = IF_TBE; | 368 | amiga_custom.intena = IF_TBE; |
| @@ -1197,7 +1197,7 @@ static void rs_set_termios(struct tty_struct *tty, const struct ktermios *old_te · 828 unmodified lines | |||
| 1197 | 1197 | ||
| 1198 | /* Handle turning off CRTSCTS */ | 1198 | /* Handle turning off CRTSCTS */ |
| 1199 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { | 1199 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { |
| 1200 | tty->hw_stopped = 0; | 1200 | tty->hw_stopped = false; |
| 1201 | rs_start(tty); | 1201 | rs_start(tty); |
| 1202 | } | 1202 | } |
| 1203 | 1203 | ||
| @@ -553,7 +553,7 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info, · 552 unmodified lines | |||
| 553 | 553 | ||
| 554 | if (tty->hw_stopped) { | 554 | if (tty->hw_stopped) { |
| 555 | if (cts) { | 555 | if (cts) { |
| 556 | tty->hw_stopped = 0; | 556 | tty->hw_stopped = false; |
| 557 | 557 | ||
| 558 | if (!mxser_16550A_or_MUST(info)) | 558 | if (!mxser_16550A_or_MUST(info)) |
| 559 | __mxser_start_tx(info); | 559 | __mxser_start_tx(info); |
| @@ -563,7 +563,7 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info, · 3 unmodified lines | |||
| 563 | } else if (cts) | 563 | } else if (cts) |
| 564 | return; | 564 | return; |
| 565 | 565 | ||
| 566 | tty->hw_stopped = 1; | 566 | tty->hw_stopped = true; |
| 567 | if (!mxser_16550A_or_MUST(info)) | 567 | if (!mxser_16550A_or_MUST(info)) |
| 568 | __mxser_stop_tx(info); | 568 | __mxser_stop_tx(info); |
| 569 | } | 569 | } |
| @@ -1361,7 +1361,7 @@ static void mxser_set_termios(struct tty_struct *tty, · 791 unmodified lines | |||
| 1361 | spin_unlock_irqrestore(&info->slock, flags); | 1361 | spin_unlock_irqrestore(&info->slock, flags); |
| 1362 | 1362 | ||
| 1363 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { | 1363 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { |
| 1364 | tty->hw_stopped = 0; | 1364 | tty->hw_stopped = false; |
| 1365 | mxser_start(tty); | 1365 | mxser_start(tty); |
| 1366 | } | 1366 | } |
| 1367 | 1367 | ||
| @@ -42,6 +42,7 @@ · 41 unmodified lines | |||
| 42 | #include <linux/ctype.h> | 42 | #include <linux/ctype.h> |
| 43 | #include <linux/mm.h> | 43 | #include <linux/mm.h> |
| 44 | #include <linux/math.h> | 44 | #include <linux/math.h> |
| 45 | #include <linux/nospec.h> | ||
| 45 | #include <linux/string.h> | 46 | #include <linux/string.h> |
| 46 | #include <linux/slab.h> | 47 | #include <linux/slab.h> |
| 47 | #include <linux/poll.h> | 48 | #include <linux/poll.h> |
| @@ -128,6 +129,7 @@ struct gsm_msg { · 80 unmodified lines | |||
| 128 | 129 | ||
| 129 | enum gsm_dlci_state { | 130 | enum gsm_dlci_state { |
| 130 | DLCI_CLOSED, | 131 | DLCI_CLOSED, |
| 132 | DLCI_WAITING_CONFIG, /* Waiting for DLCI configuration from user */ | ||
| 131 | DLCI_CONFIGURE, /* Sending PN (for adaption > 1) */ | 133 | DLCI_CONFIGURE, /* Sending PN (for adaption > 1) */ |
| 132 | DLCI_OPENING, /* Sending SABM not seen UA */ | 134 | DLCI_OPENING, /* Sending SABM not seen UA */ |
| 133 | DLCI_OPEN, /* SABM/UA complete */ | 135 | DLCI_OPEN, /* SABM/UA complete */ |
| @@ -330,6 +332,7 @@ struct gsm_mux { · 196 unmodified lines | |||
| 330 | unsigned int t3; /* Power wake-up timer in seconds. */ | 332 | unsigned int t3; /* Power wake-up timer in seconds. */ |
| 331 | int n2; /* Retry count */ | 333 | int n2; /* Retry count */ |
| 332 | u8 k; /* Window size */ | 334 | u8 k; /* Window size */ |
| 335 | bool wait_config; /* Wait for configuration by ioctl before DLCI open */ | ||
| 333 | u32 keep_alive; /* Control channel keep-alive in 10ms */ | 336 | u32 keep_alive; /* Control channel keep-alive in 10ms */ |
| 334 | 337 | ||
| 335 | /* Statistics (not currently exposed) */ | 338 | /* Statistics (not currently exposed) */ |
| @@ -451,6 +454,7 @@ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk); · 115 unmodified lines | |||
| 451 | static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, | 454 | static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, |
| 452 | u8 ctrl); | 455 | u8 ctrl); |
| 453 | static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg); | 456 | static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg); |
| 457 | static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr); | ||
| 454 | static void gsmld_write_trigger(struct gsm_mux *gsm); | 458 | static void gsmld_write_trigger(struct gsm_mux *gsm); |
| 455 | static void gsmld_write_task(struct work_struct *work); | 459 | static void gsmld_write_task(struct work_struct *work); |
| 456 | 460 | ||
| @@ -2280,6 +2284,7 @@ static void gsm_dlci_begin_open(struct gsm_dlci *dlci) · 1823 unmodified lines | |||
| 2280 | 2284 | ||
| 2281 | switch (dlci->state) { | 2285 | switch (dlci->state) { |
| 2282 | case DLCI_CLOSED: | 2286 | case DLCI_CLOSED: |
| 2287 | case DLCI_WAITING_CONFIG: | ||
| 2283 | case DLCI_CLOSING: | 2288 | case DLCI_CLOSING: |
| 2284 | dlci->retries = gsm->n2; | 2289 | dlci->retries = gsm->n2; |
| 2285 | if (!need_pn) { | 2290 | if (!need_pn) { |
| @@ -2311,6 +2316,7 @@ static void gsm_dlci_set_opening(struct gsm_dlci *dlci) · 25 unmodified lines | |||
| 2311 | { | 2316 | { |
| 2312 | switch (dlci->state) { | 2317 | switch (dlci->state) { |
| 2313 | case DLCI_CLOSED: | 2318 | case DLCI_CLOSED: |
| 2319 | case DLCI_WAITING_CONFIG: | ||
| 2314 | case DLCI_CLOSING: | 2320 | case DLCI_CLOSING: |
| 2315 | dlci->state = DLCI_OPENING; | 2321 | dlci->state = DLCI_OPENING; |
| 2316 | break; | 2322 | break; |
| @@ -2319,6 +2325,24 @@ static void gsm_dlci_set_opening(struct gsm_dlci *dlci) · 2 unmodified lines | |||
| 2319 | } | 2325 | } |
| 2320 | } | 2326 | } |
| 2321 | 2327 | ||
| 2328 | /** | ||
| 2329 | * gsm_dlci_set_wait_config - wait for channel configuration | ||
| 2330 | * @dlci: DLCI to configure | ||
| 2331 | * | ||
| 2332 | * Wait for a DLCI configuration from the application. | ||
| 2333 | */ | ||
| 2334 | static void gsm_dlci_set_wait_config(struct gsm_dlci *dlci) | ||
| 2335 | { | ||
| 2336 | switch (dlci->state) { | ||
| 2337 | case DLCI_CLOSED: | ||
| 2338 | case DLCI_CLOSING: | ||
| 2339 | dlci->state = DLCI_WAITING_CONFIG; | ||
| 2340 | break; | ||
| 2341 | default: | ||
| 2342 | break; | ||
| 2343 | } | ||
| 2344 | } | ||
| 2345 | |||
| 2322 | /** | 2346 | /** |
| 2323 | * gsm_dlci_begin_close - start channel open procedure | 2347 | * gsm_dlci_begin_close - start channel open procedure |
| 2324 | * @dlci: DLCI to open | 2348 | * @dlci: DLCI to open |
| @@ -2453,6 +2477,128 @@ static void gsm_kick_timer(struct timer_list *t) · 128 unmodified lines | |||
| 2453 | pr_info("%s TX queue stalled\n", __func__); | 2477 | pr_info("%s TX queue stalled\n", __func__); |
| 2454 | } | 2478 | } |
| 2455 | 2479 | ||
| 2480 | /** | ||
| 2481 | * gsm_dlci_copy_config_values - copy DLCI configuration | ||
| 2482 | * @dlci: source DLCI | ||
| 2483 | * @dc: configuration structure to fill | ||
| 2484 | */ | ||
| 2485 | static void gsm_dlci_copy_config_values(struct gsm_dlci *dlci, struct gsm_dlci_config *dc) | ||
| 2486 | { | ||
| 2487 | memset(dc, 0, sizeof(*dc)); | ||
| 2488 | dc->channel = (u32)dlci->addr; | ||
| 2489 | dc->adaption = (u32)dlci->adaption; | ||
| 2490 | dc->mtu = (u32)dlci->mtu; | ||
| 2491 | dc->priority = (u32)dlci->prio; | ||
| 2492 | if (dlci->ftype == UIH) | ||
| 2493 | dc->i = 1; | ||
| 2494 | else | ||
| 2495 | dc->i = 2; | ||
| 2496 | dc->k = (u32)dlci->k; | ||
| 2497 | } | ||
| 2498 | |||
| 2499 | /** | ||
| 2500 | * gsm_dlci_config - configure DLCI from configuration | ||
| 2501 | * @dlci: DLCI to configure | ||
| 2502 | * @dc: DLCI configuration | ||
| 2503 | * @open: open DLCI after configuration? | ||
| 2504 | */ | ||
| 2505 | static int gsm_dlci_config(struct gsm_dlci *dlci, struct gsm_dlci_config *dc, int open) | ||
| 2506 | { | ||
| 2507 | struct gsm_mux *gsm; | ||
| 2508 | bool need_restart = false; | ||
| 2509 | bool need_open = false; | ||
| 2510 | unsigned int i; | ||
| 2511 | |||
| 2512 | /* | ||
| 2513 | * Check that userspace doesn't put stuff in here to prevent breakages | ||
| 2514 | * in the future. | ||
| 2515 | */ | ||
| 2516 | for (i = 0; i < ARRAY_SIZE(dc->reserved); i++) | ||
| 2517 | if (dc->reserved[i]) | ||
| 2518 | return -EINVAL; | ||
| 2519 | |||
| 2520 | if (!dlci) | ||
| 2521 | return -EINVAL; | ||
| 2522 | gsm = dlci->gsm; | ||
| 2523 | |||
| 2524 | /* Stuff we don't support yet - I frame transport */ | ||
| 2525 | if (dc->adaption != 1 && dc->adaption != 2) | ||
| 2526 | return -EOPNOTSUPP; | ||
| 2527 | if (dc->mtu > MAX_MTU || dc->mtu < MIN_MTU || dc->mtu > gsm->mru) | ||
| 2528 | return -EINVAL; | ||
| 2529 | if (dc->priority >= 64) | ||
| 2530 | return -EINVAL; | ||
| 2531 | if (dc->i == 0 || dc->i > 2) /* UIH and UI only */ | ||
| 2532 | return -EINVAL; | ||
| 2533 | if (dc->k > 7) | ||
| 2534 | return -EINVAL; | ||
| 2535 | |||
| 2536 | /* | ||
| 2537 | * See what is needed for reconfiguration | ||
| 2538 | */ | ||
| 2539 | /* Framing fields */ | ||
| 2540 | if (dc->adaption != dlci->adaption) | ||
| 2541 | need_restart = true; | ||
| 2542 | if (dc->mtu != dlci->mtu) | ||
| 2543 | need_restart = true; | ||
| 2544 | if (dc->i != dlci->ftype) | ||
| 2545 | need_restart = true; | ||
| 2546 | /* Requires care */ | ||
| 2547 | if (dc->priority != dlci->prio) | ||
| 2548 | need_restart = true; | ||
| 2549 | |||
| 2550 | if ((open && gsm->wait_config) || need_restart) | ||
| 2551 | need_open = true; | ||
| 2552 | if (dlci->state == DLCI_WAITING_CONFIG) { | ||
| 2553 | need_restart = false; | ||
| 2554 | need_open = true; | ||
| 2555 | } | ||
| 2556 | |||
| 2557 | /* | ||
| 2558 | * Close down what is needed, restart and initiate the new | ||
| 2559 | * configuration. | ||
| 2560 | */ | ||
| 2561 | if (need_restart) { | ||
| 2562 | gsm_dlci_begin_close(dlci); | ||
| 2563 | wait_event_interruptible(gsm->event, dlci->state == DLCI_CLOSED); | ||
| 2564 | if (signal_pending(current)) | ||
| 2565 | return -EINTR; | ||
| 2566 | } | ||
| 2567 | /* | ||
| 2568 | * Setup the new configuration values | ||
| 2569 | */ | ||
| 2570 | dlci->adaption = (int)dc->adaption; | ||
| 2571 | |||
| 2572 | if (dc->mtu) | ||
| 2573 | dlci->mtu = (unsigned int)dc->mtu; | ||
| 2574 | else | ||
| 2575 | dlci->mtu = gsm->mtu; | ||
| 2576 | |||
| 2577 | if (dc->priority) | ||
| 2578 | dlci->prio = (u8)dc->priority; | ||
| 2579 | else | ||
| 2580 | dlci->prio = roundup(dlci->addr + 1, 8) - 1; | ||
| 2581 | |||
| 2582 | if (dc->i == 1) | ||
| 2583 | dlci->ftype = UIH; | ||
| 2584 | else if (dc->i == 2) | ||
| 2585 | dlci->ftype = UI; | ||
| 2586 | |||
| 2587 | if (dc->k) | ||
| 2588 | dlci->k = (u8)dc->k; | ||
| 2589 | else | ||
| 2590 | dlci->k = gsm->k; | ||
| 2591 | |||
| 2592 | if (need_open) { | ||
| 2593 | if (gsm->initiator) | ||
| 2594 | gsm_dlci_begin_open(dlci); | ||
| 2595 | else | ||
| 2596 | gsm_dlci_set_opening(dlci); | ||
| 2597 | } | ||
| 2598 | |||
| 2599 | return 0; | ||
| 2600 | } | ||
| 2601 | |||
| 2456 | /* | 2602 | /* |
| 2457 | * Allocate/Free DLCI channels | 2603 | * Allocate/Free DLCI channels |
| 2458 | */ | 2604 | */ |
| @@ -3078,6 +3224,7 @@ static struct gsm_mux *gsm_alloc_mux(void) · 619 unmodified lines | |||
| 3078 | gsm->mru = 64; /* Default to encoding 1 so these should be 64 */ | 3224 | gsm->mru = 64; /* Default to encoding 1 so these should be 64 */ |
| 3079 | gsm->mtu = 64; | 3225 | gsm->mtu = 64; |
| 3080 | gsm->dead = true; /* Avoid early tty opens */ | 3226 | gsm->dead = true; /* Avoid early tty opens */ |
| 3227 | gsm->wait_config = false; /* Disabled */ | ||
| 3081 | gsm->keep_alive = 0; /* Disabled */ | 3228 | gsm->keep_alive = 0; /* Disabled */ |
| 3082 | 3229 | ||
| 3083 | /* Store the instance to the mux array or abort if no space is | 3230 | /* Store the instance to the mux array or abort if no space is |
| @@ -3130,8 +3277,8 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) · 46 unmodified lines | |||
| 3130 | int need_close = 0; | 3277 | int need_close = 0; |
| 3131 | int need_restart = 0; | 3278 | int need_restart = 0; |
| 3132 | 3279 | ||
| 3133 | /* Stuff we don't support yet - UI or I frame transport, windowing */ | 3280 | /* Stuff we don't support yet - UI or I frame transport */ |
| 3134 | if ((c->adaption != 1 && c->adaption != 2) || c->k) | 3281 | if (c->adaption != 1 && c->adaption != 2) |
| 3135 | return -EOPNOTSUPP; | 3282 | return -EOPNOTSUPP; |
| 3136 | /* Check the MRU/MTU range looks sane */ | 3283 | /* Check the MRU/MTU range looks sane */ |
| 3137 | if (c->mru < MIN_MTU || c->mtu < MIN_MTU) | 3284 | if (c->mru < MIN_MTU || c->mtu < MIN_MTU) |
| @@ -3218,6 +3365,7 @@ static void gsm_copy_config_ext_values(struct gsm_mux *gsm, · 80 unmodified lines | |||
| 3218 | struct gsm_config_ext *ce) | 3365 | struct gsm_config_ext *ce) |
| 3219 | { | 3366 | { |
| 3220 | memset(ce, 0, sizeof(*ce)); | 3367 | memset(ce, 0, sizeof(*ce)); |
| 3368 | ce->wait_config = gsm->wait_config ? 1 : 0; | ||
| 3221 | ce->keep_alive = gsm->keep_alive; | 3369 | ce->keep_alive = gsm->keep_alive; |
| 3222 | } | 3370 | } |
| 3223 | 3371 | ||
| @@ -3233,7 +3381,12 @@ static int gsm_config_ext(struct gsm_mux *gsm, struct gsm_config_ext *ce) · 9 unmodified lines | |||
| 3233 | if (ce->reserved[i]) | 3381 | if (ce->reserved[i]) |
| 3234 | return -EINVAL; | 3382 | return -EINVAL; |
| 3235 | 3383 | ||
| 3384 | /* | ||
| 3385 | * Setup the new configuration values | ||
| 3386 | */ | ||
| 3387 | gsm->wait_config = ce->wait_config ? true : false; | ||
| 3236 | gsm->keep_alive = ce->keep_alive; | 3388 | gsm->keep_alive = ce->keep_alive; |
| 3389 | |||
| 3237 | return 0; | 3390 | return 0; |
| 3238 | } | 3391 | } |
| 3239 | 3392 | ||
| @@ -3433,9 +3586,16 @@ static int gsmld_open(struct tty_struct *tty) · 193 unmodified lines | |||
| 3433 | tty->receive_room = 65536; | 3586 | tty->receive_room = 65536; |
| 3434 | 3587 | ||
| 3435 | /* Attach the initial passive connection */ | 3588 | /* Attach the initial passive connection */ |
| 3436 | gsm->encoding = GSM_ADV_OPT; | ||
| 3437 | gsmld_attach_gsm(tty, gsm); | 3589 | gsmld_attach_gsm(tty, gsm); |
| 3438 | 3590 | ||
| 3591 | /* The mux will not be activated yet, we wait for correct | ||
| 3592 | * configuration first. | ||
| 3593 | */ | ||
| 3594 | if (gsm->encoding == GSM_BASIC_OPT) | ||
| 3595 | gsm->receive = gsm0_receive; | ||
| 3596 | else | ||
| 3597 | gsm->receive = gsm1_receive; | ||
| 3598 | |||
| 3439 | return 0; | 3599 | return 0; |
| 3440 | } | 3600 | } |
| 3441 | 3601 | ||
| @@ -3556,8 +3716,10 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd, · 114 unmodified lines | |||
| 3556 | { | 3716 | { |
| 3557 | struct gsm_config c; | 3717 | struct gsm_config c; |
| 3558 | struct gsm_config_ext ce; | 3718 | struct gsm_config_ext ce; |
| 3719 | struct gsm_dlci_config dc; | ||
| 3559 | struct gsm_mux *gsm = tty->disc_data; | 3720 | struct gsm_mux *gsm = tty->disc_data; |
| 3560 | unsigned int base; | 3721 | unsigned int base, addr; |
| 3722 | struct gsm_dlci *dlci; | ||
| 3561 | 3723 | ||
| 3562 | switch (cmd) { | 3724 | switch (cmd) { |
| 3563 | case GSMIOC_GETCONF: | 3725 | case GSMIOC_GETCONF: |
| @@ -3581,6 +3743,35 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd, · 17 unmodified lines | |||
| 3581 | if (copy_from_user(&ce, (void __user *)arg, sizeof(ce))) | 3743 | if (copy_from_user(&ce, (void __user *)arg, sizeof(ce))) |
| 3582 | return -EFAULT; | 3744 | return -EFAULT; |
| 3583 | return gsm_config_ext(gsm, &ce); | 3745 | return gsm_config_ext(gsm, &ce); |
| 3746 | case GSMIOC_GETCONF_DLCI: | ||
| 3747 | if (copy_from_user(&dc, (void __user *)arg, sizeof(dc))) | ||
| 3748 | return -EFAULT; | ||
| 3749 | if (dc.channel == 0 || dc.channel >= NUM_DLCI) | ||
| 3750 | return -EINVAL; | ||
| 3751 | addr = array_index_nospec(dc.channel, NUM_DLCI); | ||
| 3752 | dlci = gsm->dlci[addr]; | ||
| 3753 | if (!dlci) { | ||
| 3754 | dlci = gsm_dlci_alloc(gsm, addr); | ||
| 3755 | if (!dlci) | ||
| 3756 | return -ENOMEM; | ||
| 3757 | } | ||
| 3758 | gsm_dlci_copy_config_values(dlci, &dc); | ||
| 3759 | if (copy_to_user((void __user *)arg, &dc, sizeof(dc))) | ||
| 3760 | return -EFAULT; | ||
| 3761 | return 0; | ||
| 3762 | case GSMIOC_SETCONF_DLCI: | ||
| 3763 | if (copy_from_user(&dc, (void __user *)arg, sizeof(dc))) | ||
| 3764 | return -EFAULT; | ||
| 3765 | if (dc.channel == 0 || dc.channel >= NUM_DLCI) | ||
| 3766 | return -EINVAL; | ||
| 3767 | addr = array_index_nospec(dc.channel, NUM_DLCI); | ||
| 3768 | dlci = gsm->dlci[addr]; | ||
| 3769 | if (!dlci) { | ||
| 3770 | dlci = gsm_dlci_alloc(gsm, addr); | ||
| 3771 | if (!dlci) | ||
| 3772 | return -ENOMEM; | ||
| 3773 | } | ||
| 3774 | return gsm_dlci_config(dlci, &dc, 0); | ||
| 3584 | default: | 3775 | default: |
| 3585 | return n_tty_ioctl_helper(tty, cmd, arg); | 3776 | return n_tty_ioctl_helper(tty, cmd, arg); |
| 3586 | } | 3777 | } |
| @@ -4008,7 +4199,6 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) · 421 unmodified lines | |||
| 4008 | { | 4199 | { |
| 4009 | struct gsm_dlci *dlci = tty->driver_data; | 4200 | struct gsm_dlci *dlci = tty->driver_data; |
| 4010 | struct tty_port *port = &dlci->port; | 4201 | struct tty_port *port = &dlci->port; |
| 4011 | struct gsm_mux *gsm = dlci->gsm; | ||
| 4012 | 4202 | ||
| 4013 | port->count++; | 4203 | port->count++; |
| 4014 | tty_port_tty_set(port, tty); | 4204 | tty_port_tty_set(port, tty); |
| @@ -4018,10 +4208,15 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) · 3 unmodified lines | |||
| 4018 | a DM straight back. This is ok as that will have caused a hangup */ | 4208 | a DM straight back. This is ok as that will have caused a hangup */ |
| 4019 | tty_port_set_initialized(port, true); | 4209 | tty_port_set_initialized(port, true); |
| 4020 | /* Start sending off SABM messages */ | 4210 | /* Start sending off SABM messages */ |
| 4021 | if (gsm->initiator) | 4211 | if (!dlci->gsm->wait_config) { |
| 4022 | gsm_dlci_begin_open(dlci); | 4212 | /* Start sending off SABM messages */ |
| 4023 | else | 4213 | if (dlci->gsm->initiator) |
| 4024 | gsm_dlci_set_opening(dlci); | 4214 | gsm_dlci_begin_open(dlci); |
| 4215 | else | ||
| 4216 | gsm_dlci_set_opening(dlci); | ||
| 4217 | } else { | ||
| 4218 | gsm_dlci_set_wait_config(dlci); | ||
| 4219 | } | ||
| 4025 | /* And wait for virtual carrier */ | 4220 | /* And wait for virtual carrier */ |
| 4026 | return tty_port_block_til_ready(port, tty, filp); | 4221 | return tty_port_block_til_ready(port, tty, filp); |
| 4027 | } | 4222 | } |
| @@ -4142,6 +4337,7 @@ static int gsmtty_ioctl(struct tty_struct *tty, · 114 unmodified lines | |||
| 4142 | { | 4337 | { |
| 4143 | struct gsm_dlci *dlci = tty->driver_data; | 4338 | struct gsm_dlci *dlci = tty->driver_data; |
| 4144 | struct gsm_netconfig nc; | 4339 | struct gsm_netconfig nc; |
| 4340 | struct gsm_dlci_config dc; | ||
| 4145 | int index; | 4341 | int index; |
| 4146 | 4342 | ||
| 4147 | if (dlci->state == DLCI_CLOSED) | 4343 | if (dlci->state == DLCI_CLOSED) |
| @@ -4165,6 +4361,23 @@ static int gsmtty_ioctl(struct tty_struct *tty, · 17 unmodified lines | |||
| 4165 | gsm_destroy_network(dlci); | 4361 | gsm_destroy_network(dlci); |
| 4166 | mutex_unlock(&dlci->mutex); | 4362 | mutex_unlock(&dlci->mutex); |
| 4167 | return 0; | 4363 | return 0; |
| 4364 | case GSMIOC_GETCONF_DLCI: | ||
| 4365 | if (copy_from_user(&dc, (void __user *)arg, sizeof(dc))) | ||
| 4366 | return -EFAULT; | ||
| 4367 | if (dc.channel != dlci->addr) | ||
| 4368 | return -EPERM; | ||
| 4369 | gsm_dlci_copy_config_values(dlci, &dc); | ||
| 4370 | if (copy_to_user((void __user *)arg, &dc, sizeof(dc))) | ||
| 4371 | return -EFAULT; | ||
| 4372 | return 0; | ||
| 4373 | case GSMIOC_SETCONF_DLCI: | ||
| 4374 | if (copy_from_user(&dc, (void __user *)arg, sizeof(dc))) | ||
| 4375 | return -EFAULT; | ||
| 4376 | if (dc.channel >= NUM_DLCI) | ||
| 4377 | return -EINVAL; | ||
| 4378 | if (dc.channel != 0 && dc.channel != dlci->addr) | ||
| 4379 | return -EPERM; | ||
| 4380 | return gsm_dlci_config(dlci, &dc, 1); | ||
| 4168 | case TIOCMIWAIT: | 4381 | case TIOCMIWAIT: |
| 4169 | return gsm_wait_modem_change(dlci, (u32)arg); | 4382 | return gsm_wait_modem_change(dlci, (u32)arg); |
| 4170 | default: | 4383 | default: |
| @@ -28,27 +28,26 @@ · 27 unmodified lines | |||
| 28 | * EAGAIN | 28 | * EAGAIN |
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | #include <linux/types.h> | 31 | #include <linux/bitmap.h> |
| 32 | #include <linux/major.h> | 32 | #include <linux/bitops.h> |
| 33 | #include <linux/ctype.h> | ||
| 33 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
| 34 | #include <linux/signal.h> | 35 | #include <linux/export.h> |
| 35 | #include <linux/fcntl.h> | 36 | #include <linux/fcntl.h> |
| 37 | #include <linux/file.h> | ||
| 38 | #include <linux/jiffies.h> | ||
| 39 | #include <linux/math.h> | ||
| 40 | #include <linux/poll.h> | ||
| 41 | #include <linux/ratelimit.h> | ||
| 36 | #include <linux/sched.h> | 42 | #include <linux/sched.h> |
| 37 | #include <linux/interrupt.h> | 43 | #include <linux/signal.h> |
| 38 | #include <linux/tty.h> | ||
| 39 | #include <linux/timer.h> | ||
| 40 | #include <linux/ctype.h> | ||
| 41 | #include <linux/mm.h> | ||
| 42 | #include <linux/string.h> | ||
| 43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
| 44 | #include <linux/poll.h> | 45 | #include <linux/string.h> |
| 45 | #include <linux/bitops.h> | 46 | #include <linux/tty.h> |
| 46 | #include <linux/audit.h> | 47 | #include <linux/types.h> |
| 47 | #include <linux/file.h> | ||
| 48 | #include <linux/uaccess.h> | 48 | #include <linux/uaccess.h> |
| 49 | #include <linux/module.h> | ||
| 50 | #include <linux/ratelimit.h> | ||
| 51 | #include <linux/vmalloc.h> | 49 | #include <linux/vmalloc.h> |
| 50 | |||
| 52 | #include "tty.h" | 51 | #include "tty.h" |
| 53 | 52 | ||
| 54 | /* | 53 | /* |
| @@ -625,7 +624,7 @@ static size_t __process_echoes(struct tty_struct *tty) · 570 unmodified lines | |||
| 625 | c = echo_buf(ldata, tail); | 624 | c = echo_buf(ldata, tail); |
| 626 | if (c == ECHO_OP_START) { | 625 | if (c == ECHO_OP_START) { |
| 627 | unsigned char op; | 626 | unsigned char op; |
| 628 | int no_space_left = 0; | 627 | bool space_left = true; |
| 629 | 628 | ||
| 630 | /* | 629 | /* |
| 631 | * Since add_echo_byte() is called without holding | 630 | * Since add_echo_byte() is called without holding |
| @@ -664,7 +663,7 @@ static size_t __process_echoes(struct tty_struct *tty) · 32 unmodified lines | |||
| 664 | num_bs = 8 - (num_chars & 7); | 663 | num_bs = 8 - (num_chars & 7); |
| 665 | 664 | ||
| 666 | if (num_bs > space) { | 665 | if (num_bs > space) { |
| 667 | no_space_left = 1; | 666 | space_left = false; |
| 668 | break; | 667 | break; |
| 669 | } | 668 | } |
| 670 | space -= num_bs; | 669 | space -= num_bs; |
| @@ -690,7 +689,7 @@ static size_t __process_echoes(struct tty_struct *tty) · 19 unmodified lines | |||
| 690 | case ECHO_OP_START: | 689 | case ECHO_OP_START: |
| 691 | /* This is an escaped echo op start code */ | 690 | /* This is an escaped echo op start code */ |
| 692 | if (!space) { | 691 | if (!space) { |
| 693 | no_space_left = 1; | 692 | space_left = false; |
| 694 | break; | 693 | break; |
| 695 | } | 694 | } |
| 696 | tty_put_char(tty, ECHO_OP_START); | 695 | tty_put_char(tty, ECHO_OP_START); |
| @@ -710,7 +709,7 @@ static size_t __process_echoes(struct tty_struct *tty) · 13 unmodified lines | |||
| 710 | * | 709 | * |
| 711 | */ | 710 | */ |
| 712 | if (space < 2) { | 711 | if (space < 2) { |
| 713 | no_space_left = 1; | 712 | space_left = false; |
| 714 | break; | 713 | break; |
| 715 | } | 714 | } |
| 716 | tty_put_char(tty, '^'); | 715 | tty_put_char(tty, '^'); |
| @@ -720,7 +719,7 @@ static size_t __process_echoes(struct tty_struct *tty) · 3 unmodified lines | |||
| 720 | tail += 2; | 719 | tail += 2; |
| 721 | } | 720 | } |
| 722 | 721 | ||
| 723 | if (no_space_left) | 722 | if (!space_left) |
| 724 | break; | 723 | break; |
| 725 | } else { | 724 | } else { |
| 726 | if (O_OPOST(tty)) { | 725 | if (O_OPOST(tty)) { |
| @@ -1177,7 +1176,7 @@ static void n_tty_receive_overrun(struct tty_struct *tty) · 450 unmodified lines | |||
| 1177 | 1176 | ||
| 1178 | ldata->num_overrun++; | 1177 | ldata->num_overrun++; |
| 1179 | if (time_after(jiffies, ldata->overrun_time + HZ) || | 1178 | if (time_after(jiffies, ldata->overrun_time + HZ) || |
| 1180 | time_after(ldata->overrun_time, jiffies)) { | 1179 | time_after(ldata->overrun_time, jiffies)) { |
| 1181 | tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun); | 1180 | tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun); |
| 1182 | ldata->overrun_time = jiffies; | 1181 | ldata->overrun_time = jiffies; |
| 1183 | ldata->num_overrun = 0; | 1182 | ldata->num_overrun = 0; |
| @@ -1691,7 +1690,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, · 507 unmodified lines | |||
| 1691 | 1690 | ||
| 1692 | room = N_TTY_BUF_SIZE - (ldata->read_head - tail); | 1691 | room = N_TTY_BUF_SIZE - (ldata->read_head - tail); |
| 1693 | if (I_PARMRK(tty)) | 1692 | if (I_PARMRK(tty)) |
| 1694 | room = (room + 2) / 3; | 1693 | room = DIV_ROUND_UP(room, 3); |
| 1695 | room--; | 1694 | room--; |
| 1696 | if (room <= 0) { | 1695 | if (room <= 0) { |
| 1697 | overflow = ldata->icanon && ldata->canon_head == tail; | 1696 | overflow = ldata->icanon && ldata->canon_head == tail; |
| @@ -365,6 +365,13 @@ static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p) · 364 unmodified lines | |||
| 365 | if (dma->prepare_rx_dma) | 365 | if (dma->prepare_rx_dma) |
| 366 | dma->prepare_rx_dma(p); | 366 | dma->prepare_rx_dma(p); |
| 367 | } | 367 | } |
| 368 | |||
| 369 | static inline bool serial8250_tx_dma_running(struct uart_8250_port *p) | ||
| 370 | { | ||
| 371 | struct uart_8250_dma *dma = p->dma; | ||
| 372 | |||
| 373 | return dma && dma->tx_running; | ||
| 374 | } | ||
| 368 | #else | 375 | #else |
| 369 | static inline int serial8250_tx_dma(struct uart_8250_port *p) | 376 | static inline int serial8250_tx_dma(struct uart_8250_port *p) |
| 370 | { | 377 | { |
| @@ -380,6 +387,11 @@ static inline int serial8250_request_dma(struct uart_8250_port *p) · 9 unmodified lines | |||
| 380 | return -1; | 387 | return -1; |
| 381 | } | 388 | } |
| 382 | static inline void serial8250_release_dma(struct uart_8250_port *p) { } | 389 | static inline void serial8250_release_dma(struct uart_8250_port *p) { } |
| 390 | |||
| 391 | static inline bool serial8250_tx_dma_running(struct uart_8250_port *p) | ||
| 392 | { | ||
| 393 | return false; | ||
| 394 | } | ||
| 383 | #endif | 395 | #endif |
| 384 | 396 | ||
| 385 | static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) | 397 | static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) |
| @@ -1014,14 +1014,16 @@ static int brcmuart_probe(struct platform_device *pdev) · 1013 unmodified lines | |||
| 1014 | /* See if a Baud clock has been specified */ | 1014 | /* See if a Baud clock has been specified */ |
| 1015 | baud_mux_clk = of_clk_get_by_name(np, "sw_baud"); | 1015 | baud_mux_clk = of_clk_get_by_name(np, "sw_baud"); |
| 1016 | if (IS_ERR(baud_mux_clk)) { | 1016 | if (IS_ERR(baud_mux_clk)) { |
| 1017 | if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER) | 1017 | if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER) { |
| 1018 | return -EPROBE_DEFER; | 1018 | ret = -EPROBE_DEFER; |
| 1019 | goto release_dma; | ||
| 1020 | } | ||
| 1019 | dev_dbg(dev, "BAUD MUX clock not specified\n"); | 1021 | dev_dbg(dev, "BAUD MUX clock not specified\n"); |
| 1020 | } else { | 1022 | } else { |
| 1021 | dev_dbg(dev, "BAUD MUX clock found\n"); | 1023 | dev_dbg(dev, "BAUD MUX clock found\n"); |
| 1022 | ret = clk_prepare_enable(baud_mux_clk); | 1024 | ret = clk_prepare_enable(baud_mux_clk); |
| 1023 | if (ret) | 1025 | if (ret) |
| 1024 | return ret; | 1026 | goto release_dma; |
| 1025 | priv->baud_mux_clk = baud_mux_clk; | 1027 | priv->baud_mux_clk = baud_mux_clk; |
| 1026 | init_real_clk_rates(dev, priv); | 1028 | init_real_clk_rates(dev, priv); |
| 1027 | clk_rate = priv->default_mux_rate; | 1029 | clk_rate = priv->default_mux_rate; |
| @@ -1029,7 +1031,8 @@ static int brcmuart_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 1029 | 1031 | ||
| 1030 | if (clk_rate == 0) { | 1032 | if (clk_rate == 0) { |
| 1031 | dev_err(dev, "clock-frequency or clk not defined\n"); | 1033 | dev_err(dev, "clock-frequency or clk not defined\n"); |
| 1032 | return -EINVAL; | 1034 | ret = -EINVAL; |
| 1035 | goto release_dma; | ||
| 1033 | } | 1036 | } |
| 1034 | 1037 | ||
| 1035 | dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not "); | 1038 | dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not "); |
| @@ -1116,7 +1119,9 @@ err1: · 80 unmodified lines | |||
| 1116 | serial8250_unregister_port(priv->line); | 1119 | serial8250_unregister_port(priv->line); |
| 1117 | err: | 1120 | err: |
| 1118 | brcmuart_free_bufs(dev, priv); | 1121 | brcmuart_free_bufs(dev, priv); |
| 1119 | brcmuart_arbitration(priv, 0); | 1122 | release_dma: |
| 1123 | if (priv->dma_enabled) | ||
| 1124 | brcmuart_arbitration(priv, 0); | ||
| 1120 | return ret; | 1125 | return ret; |
| 1121 | } | 1126 | } |
| 1122 | 1127 | ||
| @@ -1128,7 +1133,8 @@ static int brcmuart_remove(struct platform_device *pdev) · 5 unmodified lines | |||
| 1128 | hrtimer_cancel(&priv->hrt); | 1133 | hrtimer_cancel(&priv->hrt); |
| 1129 | serial8250_unregister_port(priv->line); | 1134 | serial8250_unregister_port(priv->line); |
| 1130 | brcmuart_free_bufs(&pdev->dev, priv); | 1135 | brcmuart_free_bufs(&pdev->dev, priv); |
| 1131 | brcmuart_arbitration(priv, 0); | 1136 | if (priv->dma_enabled) |
| 1137 | brcmuart_arbitration(priv, 0); | ||
| 1132 | return 0; | 1138 | return 0; |
| 1133 | } | 1139 | } |
| 1134 | 1140 | ||
| @@ -1158,6 +1158,7 @@ void serial8250_unregister_port(int line) · 1157 unmodified lines | |||
| 1158 | uart->port.type = PORT_UNKNOWN; | 1158 | uart->port.type = PORT_UNKNOWN; |
| 1159 | uart->port.dev = &serial8250_isa_devs->dev; | 1159 | uart->port.dev = &serial8250_isa_devs->dev; |
| 1160 | uart->capabilities = 0; | 1160 | uart->capabilities = 0; |
| 1161 | serial8250_init_port(uart); | ||
| 1161 | serial8250_apply_quirks(uart); | 1162 | serial8250_apply_quirks(uart); |
| 1162 | uart_add_one_port(&serial8250_reg, &uart->port); | 1163 | uart_add_one_port(&serial8250_reg, &uart->port); |
| 1163 | } else { | 1164 | } else { |
| @@ -13,36 +13,49 @@ · 12 unmodified lines | |||
| 13 | #include <linux/serial_reg.h> | 13 | #include <linux/serial_reg.h> |
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
| 16 | #include <linux/slab.h> | ||
| 17 | 16 | ||
| 18 | #include "8250.h" | 17 | #include "8250.h" |
| 19 | 18 | ||
| 20 | #define UART_DLL_EM 9 | 19 | #define UART_DLL_EM 9 |
| 21 | #define UART_DLM_EM 10 | 20 | #define UART_DLM_EM 10 |
| 21 | #define UART_HCR0_EM 11 | ||
| 22 | |||
| 23 | /* | ||
| 24 | * A high value for UART_FCR_EM avoids overlapping with existing UART_* | ||
| 25 | * register defines. UART_FCR_EM_HW is the real HW register offset. | ||
| 26 | */ | ||
| 27 | #define UART_FCR_EM 0x10003 | ||
| 28 | #define UART_FCR_EM_HW 3 | ||
| 29 | |||
| 30 | #define UART_HCR0_EM_SW_RESET BIT(7) /* SW Reset */ | ||
| 22 | 31 | ||
| 23 | struct serial8250_em_priv { | 32 | struct serial8250_em_priv { |
| 24 | struct clk *sclk; | ||
| 25 | int line; | 33 | int line; |
| 26 | }; | 34 | }; |
| 27 | 35 | ||
| 28 | static void serial8250_em_serial_out(struct uart_port *p, int offset, int value) | 36 | static void serial8250_em_serial_out_helper(struct uart_port *p, int offset, |
| 37 | int value) | ||
| 29 | { | 38 | { |
| 30 | switch (offset) { | 39 | switch (offset) { |
| 31 | case UART_TX: /* TX @ 0x00 */ | 40 | case UART_TX: /* TX @ 0x00 */ |
| 32 | writeb(value, p->membase); | 41 | writeb(value, p->membase); |
| 33 | break; | 42 | break; |
| 34 | case UART_FCR: /* FCR @ 0x0c (+1) */ | ||
| 35 | case UART_LCR: /* LCR @ 0x10 (+1) */ | 43 | case UART_LCR: /* LCR @ 0x10 (+1) */ |
| 36 | case UART_MCR: /* MCR @ 0x14 (+1) */ | 44 | case UART_MCR: /* MCR @ 0x14 (+1) */ |
| 37 | case UART_SCR: /* SCR @ 0x20 (+1) */ | 45 | case UART_SCR: /* SCR @ 0x20 (+1) */ |
| 38 | writel(value, p->membase + ((offset + 1) << 2)); | 46 | writel(value, p->membase + ((offset + 1) << 2)); |
| 39 | break; | 47 | break; |
| 48 | case UART_FCR_EM: | ||
| 49 | writel(value, p->membase + (UART_FCR_EM_HW << 2)); | ||
| 50 | break; | ||
| 40 | case UART_IER: /* IER @ 0x04 */ | 51 | case UART_IER: /* IER @ 0x04 */ |
| 41 | value &= 0x0f; /* only 4 valid bits - not Xscale */ | 52 | value &= 0x0f; /* only 4 valid bits - not Xscale */ |
| 42 | fallthrough; | 53 | fallthrough; |
| 43 | case UART_DLL_EM: /* DLL @ 0x24 (+9) */ | 54 | case UART_DLL_EM: /* DLL @ 0x24 (+9) */ |
| 44 | case UART_DLM_EM: /* DLM @ 0x28 (+9) */ | 55 | case UART_DLM_EM: /* DLM @ 0x28 (+9) */ |
| 56 | case UART_HCR0_EM: /* HCR0 @ 0x2c */ | ||
| 45 | writel(value, p->membase + (offset << 2)); | 57 | writel(value, p->membase + (offset << 2)); |
| 58 | break; | ||
| 46 | } | 59 | } |
| 47 | } | 60 | } |
| 48 | 61 | ||
| @@ -51,20 +64,81 @@ static unsigned int serial8250_em_serial_in(struct uart_port *p, int offset) · 2 unmodified lines | |||
| 51 | switch (offset) { | 64 | switch (offset) { |
| 52 | case UART_RX: /* RX @ 0x00 */ | 65 | case UART_RX: /* RX @ 0x00 */ |
| 53 | return readb(p->membase); | 66 | return readb(p->membase); |
| 67 | case UART_LCR: /* LCR @ 0x10 (+1) */ | ||
| 54 | case UART_MCR: /* MCR @ 0x14 (+1) */ | 68 | case UART_MCR: /* MCR @ 0x14 (+1) */ |
| 55 | case UART_LSR: /* LSR @ 0x18 (+1) */ | 69 | case UART_LSR: /* LSR @ 0x18 (+1) */ |
| 56 | case UART_MSR: /* MSR @ 0x1c (+1) */ | 70 | case UART_MSR: /* MSR @ 0x1c (+1) */ |
| 57 | case UART_SCR: /* SCR @ 0x20 (+1) */ | 71 | case UART_SCR: /* SCR @ 0x20 (+1) */ |
| 58 | return readl(p->membase + ((offset + 1) << 2)); | 72 | return readl(p->membase + ((offset + 1) << 2)); |
| 73 | case UART_FCR_EM: | ||
| 74 | return readl(p->membase + (UART_FCR_EM_HW << 2)); | ||
| 59 | case UART_IER: /* IER @ 0x04 */ | 75 | case UART_IER: /* IER @ 0x04 */ |
| 60 | case UART_IIR: /* IIR @ 0x08 */ | 76 | case UART_IIR: /* IIR @ 0x08 */ |
| 61 | case UART_DLL_EM: /* DLL @ 0x24 (+9) */ | 77 | case UART_DLL_EM: /* DLL @ 0x24 (+9) */ |
| 62 | case UART_DLM_EM: /* DLM @ 0x28 (+9) */ | 78 | case UART_DLM_EM: /* DLM @ 0x28 (+9) */ |
| 79 | case UART_HCR0_EM: /* HCR0 @ 0x2c */ | ||
| 63 | return readl(p->membase + (offset << 2)); | 80 | return readl(p->membase + (offset << 2)); |
| 64 | } | 81 | } |
| 65 | return 0; | 82 | return 0; |
| 66 | } | 83 | } |
| 67 | 84 | ||
| 85 | static void serial8250_em_reg_update(struct uart_port *p, int off, int value) | ||
| 86 | { | ||
| 87 | unsigned int ier, fcr, lcr, mcr, hcr0; | ||
| 88 | |||
| 89 | ier = serial8250_em_serial_in(p, UART_IER); | ||
| 90 | fcr = serial8250_em_serial_in(p, UART_FCR_EM); | ||
| 91 | lcr = serial8250_em_serial_in(p, UART_LCR); | ||
| 92 | mcr = serial8250_em_serial_in(p, UART_MCR); | ||
| 93 | hcr0 = serial8250_em_serial_in(p, UART_HCR0_EM); | ||
| 94 | |||
| 95 | serial8250_em_serial_out_helper(p, UART_FCR_EM, fcr | | ||
| 96 | UART_FCR_CLEAR_RCVR | | ||
| 97 | UART_FCR_CLEAR_XMIT); | ||
| 98 | serial8250_em_serial_out_helper(p, UART_HCR0_EM, hcr0 | | ||
| 99 | UART_HCR0_EM_SW_RESET); | ||
| 100 | serial8250_em_serial_out_helper(p, UART_HCR0_EM, hcr0 & | ||
| 101 | ~UART_HCR0_EM_SW_RESET); | ||
| 102 | |||
| 103 | switch (off) { | ||
| 104 | case UART_FCR_EM: | ||
| 105 | fcr = value; | ||
| 106 | break; | ||
| 107 | case UART_LCR: | ||
| 108 | lcr = value; | ||
| 109 | break; | ||
| 110 | case UART_MCR: | ||
| 111 | mcr = value; | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | |||
| 115 | serial8250_em_serial_out_helper(p, UART_IER, ier); | ||
| 116 | serial8250_em_serial_out_helper(p, UART_FCR_EM, fcr); | ||
| 117 | serial8250_em_serial_out_helper(p, UART_MCR, mcr); | ||
| 118 | serial8250_em_serial_out_helper(p, UART_LCR, lcr); | ||
| 119 | serial8250_em_serial_out_helper(p, UART_HCR0_EM, hcr0); | ||
| 120 | } | ||
| 121 | |||
| 122 | static void serial8250_em_serial_out(struct uart_port *p, int offset, int value) | ||
| 123 | { | ||
| 124 | switch (offset) { | ||
| 125 | case UART_TX: | ||
| 126 | case UART_SCR: | ||
| 127 | case UART_IER: | ||
| 128 | case UART_DLL_EM: | ||
| 129 | case UART_DLM_EM: | ||
| 130 | serial8250_em_serial_out_helper(p, offset, value); | ||
| 131 | break; | ||
| 132 | case UART_FCR: | ||
| 133 | serial8250_em_reg_update(p, UART_FCR_EM, value); | ||
| 134 | break; | ||
| 135 | case UART_LCR: | ||
| 136 | case UART_MCR: | ||
| 137 | serial8250_em_reg_update(p, offset, value); | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 68 | static int serial8250_em_serial_dl_read(struct uart_8250_port *up) | 142 | static int serial8250_em_serial_dl_read(struct uart_8250_port *up) |
| 69 | { | 143 | { |
| 70 | return serial_in(up, UART_DLL_EM) | serial_in(up, UART_DLM_EM) << 8; | 144 | return serial_in(up, UART_DLL_EM) | serial_in(up, UART_DLM_EM) << 8; |
| @@ -79,8 +153,10 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value) · 8 unmodified lines | |||
| 79 | static int serial8250_em_probe(struct platform_device *pdev) | 153 | static int serial8250_em_probe(struct platform_device *pdev) |
| 80 | { | 154 | { |
| 81 | struct serial8250_em_priv *priv; | 155 | struct serial8250_em_priv *priv; |
| 156 | struct device *dev = &pdev->dev; | ||
| 82 | struct uart_8250_port up; | 157 | struct uart_8250_port up; |
| 83 | struct resource *regs; | 158 | struct resource *regs; |
| 159 | struct clk *sclk; | ||
| 84 | int irq, ret; | 160 | int irq, ret; |
| 85 | 161 | ||
| 86 | irq = platform_get_irq(pdev, 0); | 162 | irq = platform_get_irq(pdev, 0); |
| @@ -88,31 +164,26 @@ static int serial8250_em_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 88 | return irq; | 164 | return irq; |
| 89 | 165 | ||
| 90 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 166 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 91 | if (!regs) { | 167 | if (!regs) |
| 92 | dev_err(&pdev->dev, "missing registers\n"); | 168 | return dev_err_probe(dev, -EINVAL, "missing registers\n"); |
| 93 | return -EINVAL; | ||
| 94 | } | ||
| 95 | 169 | ||
| 96 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 170 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
| 97 | if (!priv) | 171 | if (!priv) |
| 98 | return -ENOMEM; | 172 | return -ENOMEM; |
| 99 | 173 | ||
| 100 | priv->sclk = devm_clk_get(&pdev->dev, "sclk"); | 174 | sclk = devm_clk_get_enabled(dev, "sclk"); |
| 101 | if (IS_ERR(priv->sclk)) { | 175 | if (IS_ERR(sclk)) |
| 102 | dev_err(&pdev->dev, "unable to get clock\n"); | 176 | return dev_err_probe(dev, PTR_ERR(sclk), "unable to get clock\n"); |
| 103 | return PTR_ERR(priv->sclk); | ||
| 104 | } | ||
| 105 | 177 | ||
| 106 | memset(&up, 0, sizeof(up)); | 178 | memset(&up, 0, sizeof(up)); |
| 107 | up.port.mapbase = regs->start; | 179 | up.port.mapbase = regs->start; |
| 108 | up.port.irq = irq; | 180 | up.port.irq = irq; |
| 109 | up.port.type = PORT_16750; | 181 | up.port.type = PORT_16750; |
| 110 | up.port.flags = UPF_FIXED_PORT | UPF_IOREMAP | UPF_FIXED_TYPE; | 182 | up.port.flags = UPF_FIXED_PORT | UPF_IOREMAP | UPF_FIXED_TYPE; |
| 111 | up.port.dev = &pdev->dev; | 183 | up.port.dev = dev; |
| 112 | up.port.private_data = priv; | 184 | up.port.private_data = priv; |
| 113 | 185 | ||
| 114 | clk_prepare_enable(priv->sclk); | 186 | up.port.uartclk = clk_get_rate(sclk); |
| 115 | up.port.uartclk = clk_get_rate(priv->sclk); | ||
| 116 | 187 | ||
| 117 | up.port.iotype = UPIO_MEM32; | 188 | up.port.iotype = UPIO_MEM32; |
| 118 | up.port.serial_in = serial8250_em_serial_in; | 189 | up.port.serial_in = serial8250_em_serial_in; |
| @@ -121,11 +192,8 @@ static int serial8250_em_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 121 | up.dl_write = serial8250_em_serial_dl_write; | 192 | up.dl_write = serial8250_em_serial_dl_write; |
| 122 | 193 | ||
| 123 | ret = serial8250_register_8250_port(&up); | 194 | ret = serial8250_register_8250_port(&up); |
| 124 | if (ret < 0) { | 195 | if (ret < 0) |
| 125 | dev_err(&pdev->dev, "unable to register 8250 port\n"); | 196 | return dev_err_probe(dev, ret, "unable to register 8250 port\n"); |
| 126 | clk_disable_unprepare(priv->sclk); | ||
| 127 | return ret; | ||
| 128 | } | ||
| 129 | 197 | ||
| 130 | priv->line = ret; | 198 | priv->line = ret; |
| 131 | platform_set_drvdata(pdev, priv); | 199 | platform_set_drvdata(pdev, priv); |
| @@ -137,7 +205,6 @@ static int serial8250_em_remove(struct platform_device *pdev) · 5 unmodified lines | |||
| 137 | struct serial8250_em_priv *priv = platform_get_drvdata(pdev); | 205 | struct serial8250_em_priv *priv = platform_get_drvdata(pdev); |
| 138 | 206 | ||
| 139 | serial8250_unregister_port(priv->line); | 207 | serial8250_unregister_port(priv->line); |
| 140 | clk_disable_unprepare(priv->sclk); | ||
| 141 | return 0; | 208 | return 0; |
| 142 | } | 209 | } |
| 143 | 210 | ||
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/moduleparam.h> | 15 | #include <linux/moduleparam.h> |
| 16 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| 18 | #include <linux/irq.h> | ||
| 18 | #include <linux/console.h> | 19 | #include <linux/console.h> |
| 19 | #include <linux/gpio/consumer.h> | 20 | #include <linux/gpio/consumer.h> |
| 20 | #include <linux/sysrq.h> | 21 | #include <linux/sysrq.h> |
| @@ -1932,6 +1933,7 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir) · 1911 unmodified lines | |||
| 1932 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | 1933 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir) |
| 1933 | { | 1934 | { |
| 1934 | struct uart_8250_port *up = up_to_u8250p(port); | 1935 | struct uart_8250_port *up = up_to_u8250p(port); |
| 1936 | struct tty_port *tport = &port->state->port; | ||
| 1935 | bool skip_rx = false; | 1937 | bool skip_rx = false; |
| 1936 | unsigned long flags; | 1938 | unsigned long flags; |
| 1937 | u16 status; | 1939 | u16 status; |
| @@ -1957,6 +1959,8 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) · 19 unmodified lines | |||
| 1957 | skip_rx = true; | 1959 | skip_rx = true; |
| 1958 | 1960 | ||
| 1959 | if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { | 1961 | if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { |
| 1962 | if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) | ||
| 1963 | pm_wakeup_event(tport->tty->dev, 0); | ||
| 1960 | if (!up->dma || handle_rx_dma(up, iir)) | 1964 | if (!up->dma || handle_rx_dma(up, iir)) |
| 1961 | status = serial8250_rx_chars(up, status); | 1965 | status = serial8250_rx_chars(up, status); |
| 1962 | } | 1966 | } |
| @@ -2016,18 +2020,19 @@ static int serial8250_tx_threshold_handle_irq(struct uart_port *port) · 53 unmodified lines | |||
| 2016 | static unsigned int serial8250_tx_empty(struct uart_port *port) | 2020 | static unsigned int serial8250_tx_empty(struct uart_port *port) |
| 2017 | { | 2021 | { |
| 2018 | struct uart_8250_port *up = up_to_u8250p(port); | 2022 | struct uart_8250_port *up = up_to_u8250p(port); |
| 2023 | unsigned int result = 0; | ||
| 2019 | unsigned long flags; | 2024 | unsigned long flags; |
| 2020 | u16 lsr; | ||
| 2021 | 2025 | ||
| 2022 | serial8250_rpm_get(up); | 2026 | serial8250_rpm_get(up); |
| 2023 | 2027 | ||
| 2024 | spin_lock_irqsave(&port->lock, flags); | 2028 | spin_lock_irqsave(&port->lock, flags); |
| 2025 | lsr = serial_lsr_in(up); | 2029 | if (!serial8250_tx_dma_running(up) && uart_lsr_tx_empty(serial_lsr_in(up))) |
| 2030 | result = TIOCSER_TEMT; | ||
| 2026 | spin_unlock_irqrestore(&port->lock, flags); | 2031 | spin_unlock_irqrestore(&port->lock, flags); |
| 2027 | 2032 | ||
| 2028 | serial8250_rpm_put(up); | 2033 | serial8250_rpm_put(up); |
| 2029 | 2034 | ||
| 2030 | return uart_lsr_tx_empty(lsr) ? TIOCSER_TEMT : 0; | 2035 | return result; |
| 2031 | } | 2036 | } |
| 2032 | 2037 | ||
| 2033 | unsigned int serial8250_do_get_mctrl(struct uart_port *port) | 2038 | unsigned int serial8250_do_get_mctrl(struct uart_port *port) |
| @@ -248,13 +248,6 @@ config SERIAL_SAMSUNG · 247 unmodified lines | |||
| 248 | 248 | ||
| 249 | Choose Y/M here only if you build for such SoC. | 249 | Choose Y/M here only if you build for such SoC. |
| 250 | 250 | ||
| 251 | config SERIAL_SAMSUNG_UARTS_4 | ||
| 252 | bool | ||
| 253 | depends on SERIAL_SAMSUNG | ||
| 254 | default y | ||
| 255 | help | ||
| 256 | Internal node for the common case of 4 Samsung compatible UARTs | ||
| 257 | |||
| 258 | config SERIAL_SAMSUNG_UARTS | 251 | config SERIAL_SAMSUNG_UARTS |
| 259 | int | 252 | int |
| 260 | depends on SERIAL_SAMSUNG | 253 | depends on SERIAL_SAMSUNG |
| @@ -958,7 +951,7 @@ config SERIAL_OMAP_CONSOLE · 697 unmodified lines | |||
| 958 | config SERIAL_SIFIVE | 951 | config SERIAL_SIFIVE |
| 959 | tristate "SiFive UART support" | 952 | tristate "SiFive UART support" |
| 960 | depends on OF | 953 | depends on OF |
| 961 | default SOC_SIFIVE || SOC_CANAAN | 954 | default ARCH_SIFIVE || ARCH_CANAAN |
| 962 | select SERIAL_CORE | 955 | select SERIAL_CORE |
| 963 | help | 956 | help |
| 964 | Select this option if you are building a kernel for a device that | 957 | Select this option if you are building a kernel for a device that |
| @@ -968,7 +961,7 @@ config SERIAL_SIFIVE · 3 unmodified lines | |||
| 968 | config SERIAL_SIFIVE_CONSOLE | 961 | config SERIAL_SIFIVE_CONSOLE |
| 969 | bool "Console on SiFive UART" | 962 | bool "Console on SiFive UART" |
| 970 | depends on SERIAL_SIFIVE=y | 963 | depends on SERIAL_SIFIVE=y |
| 971 | default SOC_SIFIVE || SOC_CANAAN | 964 | default ARCH_SIFIVE || ARCH_CANAAN |
| 972 | select SERIAL_CORE_CONSOLE | 965 | select SERIAL_CORE_CONSOLE |
| 973 | select SERIAL_EARLYCON | 966 | select SERIAL_EARLYCON |
| 974 | help | 967 | help |
| @@ -596,6 +596,40 @@ static int bcm_uart_verify_port(struct uart_port *port, · 595 unmodified lines | |||
| 596 | return 0; | 596 | return 0; |
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | #ifdef CONFIG_CONSOLE_POLL | ||
| 600 | /* | ||
| 601 | * return true when outstanding tx equals fifo size | ||
| 602 | */ | ||
| 603 | static bool bcm_uart_tx_full(struct uart_port *port) | ||
| 604 | { | ||
| 605 | unsigned int val; | ||
| 606 | |||
| 607 | val = bcm_uart_readl(port, UART_MCTL_REG); | ||
| 608 | val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT; | ||
| 609 | return !(port->fifosize - val); | ||
| 610 | } | ||
| 611 | |||
| 612 | static int bcm_uart_poll_get_char(struct uart_port *port) | ||
| 613 | { | ||
| 614 | unsigned int iestat; | ||
| 615 | |||
| 616 | iestat = bcm_uart_readl(port, UART_IR_REG); | ||
| 617 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) | ||
| 618 | return NO_POLL_CHAR; | ||
| 619 | |||
| 620 | return bcm_uart_readl(port, UART_FIFO_REG); | ||
| 621 | } | ||
| 622 | |||
| 623 | static void bcm_uart_poll_put_char(struct uart_port *port, unsigned char c) | ||
| 624 | { | ||
| 625 | while (bcm_uart_tx_full(port)) { | ||
| 626 | cpu_relax(); | ||
| 627 | } | ||
| 628 | |||
| 629 | bcm_uart_writel(port, c, UART_FIFO_REG); | ||
| 630 | } | ||
| 631 | #endif | ||
| 632 | |||
| 599 | /* serial core callbacks */ | 633 | /* serial core callbacks */ |
| 600 | static const struct uart_ops bcm_uart_ops = { | 634 | static const struct uart_ops bcm_uart_ops = { |
| 601 | .tx_empty = bcm_uart_tx_empty, | 635 | .tx_empty = bcm_uart_tx_empty, |
| @@ -614,6 +648,10 @@ static const struct uart_ops bcm_uart_ops = { · 12 unmodified lines | |||
| 614 | .request_port = bcm_uart_request_port, | 648 | .request_port = bcm_uart_request_port, |
| 615 | .config_port = bcm_uart_config_port, | 649 | .config_port = bcm_uart_config_port, |
| 616 | .verify_port = bcm_uart_verify_port, | 650 | .verify_port = bcm_uart_verify_port, |
| 651 | #ifdef CONFIG_CONSOLE_POLL | ||
| 652 | .poll_get_char = bcm_uart_poll_get_char, | ||
| 653 | .poll_put_char = bcm_uart_poll_put_char, | ||
| 654 | #endif | ||
| 617 | }; | 655 | }; |
| 618 | 656 | ||
| 619 | 657 | ||
| @@ -678,15 +678,14 @@ static int cpm_uart_tx_pump(struct uart_port *port) · 677 unmodified lines | |||
| 678 | /* Pick next descriptor and fill from buffer */ | 678 | /* Pick next descriptor and fill from buffer */ |
| 679 | bdp = pinfo->tx_cur; | 679 | bdp = pinfo->tx_cur; |
| 680 | 680 | ||
| 681 | while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && | 681 | while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && !uart_circ_empty(xmit)) { |
| 682 | xmit->tail != xmit->head) { | ||
| 683 | count = 0; | 682 | count = 0; |
| 684 | p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); | 683 | p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); |
| 685 | while (count < pinfo->tx_fifosize) { | 684 | while (count < pinfo->tx_fifosize) { |
| 686 | *p++ = xmit->buf[xmit->tail]; | 685 | *p++ = xmit->buf[xmit->tail]; |
| 687 | uart_xmit_advance(port, 1); | 686 | uart_xmit_advance(port, 1); |
| 688 | count++; | 687 | count++; |
| 689 | if (xmit->head == xmit->tail) | 688 | if (uart_circ_empty(xmit)) |
| 690 | break; | 689 | break; |
| 691 | } | 690 | } |
| 692 | out_be16(&bdp->cbd_datlen, count); | 691 | out_be16(&bdp->cbd_datlen, count); |
| @@ -1296,7 +1296,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport) · 1295 unmodified lines | |||
| 1296 | * 10ms at any baud rate. | 1296 | * 10ms at any baud rate. |
| 1297 | */ | 1297 | */ |
| 1298 | sport->rx_dma_rng_buf_len = (DMA_RX_TIMEOUT * baud / bits / 1000) * 2; | 1298 | sport->rx_dma_rng_buf_len = (DMA_RX_TIMEOUT * baud / bits / 1000) * 2; |
| 1299 | sport->rx_dma_rng_buf_len = (1 << (fls(sport->rx_dma_rng_buf_len) - 1)); | 1299 | sport->rx_dma_rng_buf_len = (1 << fls(sport->rx_dma_rng_buf_len)); |
| 1300 | if (sport->rx_dma_rng_buf_len < 16) | 1300 | if (sport->rx_dma_rng_buf_len < 16) |
| 1301 | sport->rx_dma_rng_buf_len = 16; | 1301 | sport->rx_dma_rng_buf_len = 16; |
| 1302 | 1302 | ||
| @@ -1406,12 +1406,12 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio · 103 unmodified lines | |||
| 1406 | struct lpuart_port, port); | 1406 | struct lpuart_port, port); |
| 1407 | 1407 | ||
| 1408 | unsigned long modem = lpuart32_read(&sport->port, UARTMODIR) | 1408 | unsigned long modem = lpuart32_read(&sport->port, UARTMODIR) |
| 1409 | & ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); | 1409 | & ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE); |
| 1410 | lpuart32_write(&sport->port, modem, UARTMODIR); | 1410 | lpuart32_write(&sport->port, modem, UARTMODIR); |
| 1411 | 1411 | ||
| 1412 | if (rs485->flags & SER_RS485_ENABLED) { | 1412 | if (rs485->flags & SER_RS485_ENABLED) { |
| 1413 | /* Enable auto RS-485 RTS mode */ | 1413 | /* Enable auto RS-485 RTS mode */ |
| 1414 | modem |= UARTMODEM_TXRTSE; | 1414 | modem |= UARTMODIR_TXRTSE; |
| 1415 | 1415 | ||
| 1416 | /* | 1416 | /* |
| 1417 | * The hardware defaults to RTS logic HIGH while transfer. | 1417 | * The hardware defaults to RTS logic HIGH while transfer. |
| @@ -1420,9 +1420,9 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio · 2 unmodified lines | |||
| 1420 | * Note: UART is assumed to be active high. | 1420 | * Note: UART is assumed to be active high. |
| 1421 | */ | 1421 | */ |
| 1422 | if (rs485->flags & SER_RS485_RTS_ON_SEND) | 1422 | if (rs485->flags & SER_RS485_RTS_ON_SEND) |
| 1423 | modem |= UARTMODEM_TXRTSPOL; | 1423 | modem |= UARTMODIR_TXRTSPOL; |
| 1424 | else if (rs485->flags & SER_RS485_RTS_AFTER_SEND) | 1424 | else if (rs485->flags & SER_RS485_RTS_AFTER_SEND) |
| 1425 | modem &= ~UARTMODEM_TXRTSPOL; | 1425 | modem &= ~UARTMODIR_TXRTSPOL; |
| 1426 | } | 1426 | } |
| 1427 | 1427 | ||
| 1428 | lpuart32_write(&sport->port, modem, UARTMODIR); | 1428 | lpuart32_write(&sport->port, modem, UARTMODIR); |
| @@ -289,20 +289,6 @@ static inline int imx_uart_is_imx1(struct imx_port *sport) · 288 unmodified lines | |||
| 289 | return sport->devdata->devtype == IMX1_UART; | 289 | return sport->devdata->devtype == IMX1_UART; |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | static inline int imx_uart_is_imx21(struct imx_port *sport) | ||
| 293 | { | ||
| 294 | return sport->devdata->devtype == IMX21_UART; | ||
| 295 | } | ||
| 296 | |||
| 297 | static inline int imx_uart_is_imx53(struct imx_port *sport) | ||
| 298 | { | ||
| 299 | return sport->devdata->devtype == IMX53_UART; | ||
| 300 | } | ||
| 301 | |||
| 302 | static inline int imx_uart_is_imx6q(struct imx_port *sport) | ||
| 303 | { | ||
| 304 | return sport->devdata->devtype == IMX6Q_UART; | ||
| 305 | } | ||
| 306 | /* | 292 | /* |
| 307 | * Save and restore functions for UCR1, UCR2 and UCR3 registers | 293 | * Save and restore functions for UCR1, UCR2 and UCR3 registers |
| 308 | */ | 294 | */ |
| @@ -1808,9 +1794,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, · 1499 unmodified lines | |||
| 1808 | 1794 | ||
| 1809 | static const char *imx_uart_type(struct uart_port *port) | 1795 | static const char *imx_uart_type(struct uart_port *port) |
| 1810 | { | 1796 | { |
| 1811 | struct imx_port *sport = (struct imx_port *)port; | 1797 | return port->type == PORT_IMX ? "IMX" : NULL; |
| 1812 | |||
| 1813 | return sport->port.type == PORT_IMX ? "IMX" : NULL; | ||
| 1814 | } | 1798 | } |
| 1815 | 1799 | ||
| 1816 | /* | 1800 | /* |
| @@ -1818,10 +1802,8 @@ static const char *imx_uart_type(struct uart_port *port) · 1 unmodified line | |||
| 1818 | */ | 1802 | */ |
| 1819 | static void imx_uart_config_port(struct uart_port *port, int flags) | 1803 | static void imx_uart_config_port(struct uart_port *port, int flags) |
| 1820 | { | 1804 | { |
| 1821 | struct imx_port *sport = (struct imx_port *)port; | ||
| 1822 | |||
| 1823 | if (flags & UART_CONFIG_TYPE) | 1805 | if (flags & UART_CONFIG_TYPE) |
| 1824 | sport->port.type = PORT_IMX; | 1806 | port->type = PORT_IMX; |
| 1825 | } | 1807 | } |
| 1826 | 1808 | ||
| 1827 | /* | 1809 | /* |
| @@ -1832,20 +1814,19 @@ static void imx_uart_config_port(struct uart_port *port, int flags) · 4 unmodified lines | |||
| 1832 | static int | 1814 | static int |
| 1833 | imx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) | 1815 | imx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) |
| 1834 | { | 1816 | { |
| 1835 | struct imx_port *sport = (struct imx_port *)port; | ||
| 1836 | int ret = 0; | 1817 | int ret = 0; |
| 1837 | 1818 | ||
| 1838 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_IMX) | 1819 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_IMX) |
| 1839 | ret = -EINVAL; | 1820 | ret = -EINVAL; |
| 1840 | if (sport->port.irq != ser->irq) | 1821 | if (port->irq != ser->irq) |
| 1841 | ret = -EINVAL; | 1822 | ret = -EINVAL; |
| 1842 | if (ser->io_type != UPIO_MEM) | 1823 | if (ser->io_type != UPIO_MEM) |
| 1843 | ret = -EINVAL; | 1824 | ret = -EINVAL; |
| 1844 | if (sport->port.uartclk / 16 != ser->baud_base) | 1825 | if (port->uartclk / 16 != ser->baud_base) |
| 1845 | ret = -EINVAL; | 1826 | ret = -EINVAL; |
| 1846 | if (sport->port.mapbase != (unsigned long)ser->iomem_base) | 1827 | if (port->mapbase != (unsigned long)ser->iomem_base) |
| 1847 | ret = -EINVAL; | 1828 | ret = -EINVAL; |
| 1848 | if (sport->port.iobase != ser->port) | 1829 | if (port->iobase != ser->port) |
| 1849 | ret = -EINVAL; | 1830 | ret = -EINVAL; |
| 1850 | if (ser->hub6 != 0) | 1831 | if (ser->hub6 != 0) |
| 1851 | ret = -EINVAL; | 1832 | ret = -EINVAL; |
| @@ -2262,21 +2243,16 @@ static int imx_uart_probe(struct platform_device *pdev) · 410 unmodified lines | |||
| 2262 | } | 2243 | } |
| 2263 | sport->port.line = ret; | 2244 | sport->port.line = ret; |
| 2264 | 2245 | ||
| 2265 | if (of_get_property(np, "uart-has-rtscts", NULL) || | 2246 | sport->have_rtscts = of_property_read_bool(np, "uart-has-rtscts") || |
| 2266 | of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */) | 2247 | of_property_read_bool(np, "fsl,uart-has-rtscts"); /* deprecated */ |
| 2267 | sport->have_rtscts = 1; | ||
| 2268 | 2248 | ||
| 2269 | if (of_get_property(np, "fsl,dte-mode", NULL)) | 2249 | sport->dte_mode = of_property_read_bool(np, "fsl,dte-mode"); |
| 2270 | sport->dte_mode = 1; | ||
| 2271 | 2250 | ||
| 2272 | if (of_get_property(np, "rts-gpios", NULL)) | 2251 | sport->have_rtsgpio = of_property_present(np, "rts-gpios"); |
| 2273 | sport->have_rtsgpio = 1; | ||
| 2274 | 2252 | ||
| 2275 | if (of_get_property(np, "fsl,inverted-tx", NULL)) | 2253 | sport->inverted_tx = of_property_read_bool(np, "fsl,inverted-tx"); |
| 2276 | sport->inverted_tx = 1; | ||
| 2277 | 2254 | ||
| 2278 | if (of_get_property(np, "fsl,inverted-rx", NULL)) | 2255 | sport->inverted_rx = of_property_read_bool(np, "fsl,inverted-rx"); |
| 2279 | sport->inverted_rx = 1; | ||
| 2280 | 2256 | ||
| 2281 | if (!of_property_read_u32_array(np, "fsl,dma-info", dma_buf_conf, 2)) { | 2257 | if (!of_property_read_u32_array(np, "fsl,dma-info", dma_buf_conf, 2)) { |
| 2282 | sport->rx_period_length = dma_buf_conf[0]; | 2258 | sport->rx_period_length = dma_buf_conf[0]; |
| @@ -525,6 +525,11 @@ static bool max310x_reg_precious(struct device *dev, unsigned int reg) · 524 unmodified lines | |||
| 525 | return false; | 525 | return false; |
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | static bool max310x_reg_noinc(struct device *dev, unsigned int reg) | ||
| 529 | { | ||
| 530 | return reg == MAX310X_RHR_REG; | ||
| 531 | } | ||
| 532 | |||
| 528 | static int max310x_set_baud(struct uart_port *port, int baud) | 533 | static int max310x_set_baud(struct uart_port *port, int baud) |
| 529 | { | 534 | { |
| 530 | unsigned int mode = 0, div = 0, frac = 0, c = 0, F = 0; | 535 | unsigned int mode = 0, div = 0, frac = 0, c = 0, F = 0; |
| @@ -651,14 +656,14 @@ static void max310x_batch_write(struct uart_port *port, u8 *txbuf, unsigned int · 120 unmodified lines | |||
| 651 | { | 656 | { |
| 652 | struct max310x_one *one = to_max310x_port(port); | 657 | struct max310x_one *one = to_max310x_port(port); |
| 653 | 658 | ||
| 654 | regmap_raw_write(one->regmap, MAX310X_THR_REG, txbuf, len); | 659 | regmap_noinc_write(one->regmap, MAX310X_THR_REG, txbuf, len); |
| 655 | } | 660 | } |
| 656 | 661 | ||
| 657 | static void max310x_batch_read(struct uart_port *port, u8 *rxbuf, unsigned int len) | 662 | static void max310x_batch_read(struct uart_port *port, u8 *rxbuf, unsigned int len) |
| 658 | { | 663 | { |
| 659 | struct max310x_one *one = to_max310x_port(port); | 664 | struct max310x_one *one = to_max310x_port(port); |
| 660 | 665 | ||
| 661 | regmap_raw_read(one->regmap, MAX310X_RHR_REG, rxbuf, len); | 666 | regmap_noinc_read(one->regmap, MAX310X_RHR_REG, rxbuf, len); |
| 662 | } | 667 | } |
| 663 | 668 | ||
| 664 | static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen) | 669 | static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen) |
| @@ -1468,6 +1473,10 @@ static struct regmap_config regcfg = { · 803 unmodified lines | |||
| 1468 | .writeable_reg = max310x_reg_writeable, | 1473 | .writeable_reg = max310x_reg_writeable, |
| 1469 | .volatile_reg = max310x_reg_volatile, | 1474 | .volatile_reg = max310x_reg_volatile, |
| 1470 | .precious_reg = max310x_reg_precious, | 1475 | .precious_reg = max310x_reg_precious, |
| 1476 | .writeable_noinc_reg = max310x_reg_noinc, | ||
| 1477 | .readable_noinc_reg = max310x_reg_noinc, | ||
| 1478 | .max_raw_read = MAX310X_FIFO_SIZE, | ||
| 1479 | .max_raw_write = MAX310X_FIFO_SIZE, | ||
| 1471 | }; | 1480 | }; |
| 1472 | 1481 | ||
| 1473 | #ifdef CONFIG_SPI_MASTER | 1482 | #ifdef CONFIG_SPI_MASTER |
| @@ -1553,6 +1562,10 @@ static struct regmap_config regcfg_i2c = { · 79 unmodified lines | |||
| 1553 | .volatile_reg = max310x_reg_volatile, | 1562 | .volatile_reg = max310x_reg_volatile, |
| 1554 | .precious_reg = max310x_reg_precious, | 1563 | .precious_reg = max310x_reg_precious, |
| 1555 | .max_register = MAX310X_I2C_REVID_EXTREG, | 1564 | .max_register = MAX310X_I2C_REVID_EXTREG, |
| 1565 | .writeable_noinc_reg = max310x_reg_noinc, | ||
| 1566 | .readable_noinc_reg = max310x_reg_noinc, | ||
| 1567 | .max_raw_read = MAX310X_FIFO_SIZE, | ||
| 1568 | .max_raw_write = MAX310X_FIFO_SIZE, | ||
| 1556 | }; | 1569 | }; |
| 1557 | 1570 | ||
| 1558 | static const struct max310x_if_cfg max310x_i2c_if_cfg = { | 1571 | static const struct max310x_if_cfg max310x_i2c_if_cfg = { |
| @@ -779,7 +779,7 @@ static int meson_uart_remove(struct platform_device *pdev) · 778 unmodified lines | |||
| 779 | return 0; | 779 | return 0; |
| 780 | } | 780 | } |
| 781 | 781 | ||
| 782 | static struct meson_uart_data s4_uart_data = { | 782 | static struct meson_uart_data meson_g12a_uart_data = { |
| 783 | .has_xtal_div2 = true, | 783 | .has_xtal_div2 = true, |
| 784 | }; | 784 | }; |
| 785 | 785 | ||
| @@ -788,9 +788,13 @@ static const struct of_device_id meson_uart_dt_match[] = { · 2 unmodified lines | |||
| 788 | { .compatible = "amlogic,meson8-uart" }, | 788 | { .compatible = "amlogic,meson8-uart" }, |
| 789 | { .compatible = "amlogic,meson8b-uart" }, | 789 | { .compatible = "amlogic,meson8b-uart" }, |
| 790 | { .compatible = "amlogic,meson-gx-uart" }, | 790 | { .compatible = "amlogic,meson-gx-uart" }, |
| 791 | { | ||
| 792 | .compatible = "amlogic,meson-g12a-uart", | ||
| 793 | .data = (void *)&meson_g12a_uart_data, | ||
| 794 | }, | ||
| 791 | { | 795 | { |
| 792 | .compatible = "amlogic,meson-s4-uart", | 796 | .compatible = "amlogic,meson-s4-uart", |
| 793 | .data = (void *)&s4_uart_data, | 797 | .data = (void *)&meson_g12a_uart_data, |
| 794 | }, | 798 | }, |
| 795 | { /* sentinel */ }, | 799 | { /* sentinel */ }, |
| 796 | }; | 800 | }; |
| @@ -1587,8 +1587,8 @@ static int mxs_auart_probe(struct platform_device *pdev) · 1586 unmodified lines | |||
| 1587 | } | 1587 | } |
| 1588 | s->port.line = ret; | 1588 | s->port.line = ret; |
| 1589 | 1589 | ||
| 1590 | if (of_get_property(np, "uart-has-rtscts", NULL) || | 1590 | if (of_property_read_bool(np, "uart-has-rtscts") || |
| 1591 | of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */) | 1591 | of_property_read_bool(np, "fsl,uart-has-rtscts") /* deprecated */) |
| 1592 | set_bit(MXS_AUART_RTSCTS, &s->flags); | 1592 | set_bit(MXS_AUART_RTSCTS, &s->flags); |
| 1593 | 1593 | ||
| 1594 | if (s->port.line >= ARRAY_SIZE(auart_port)) { | 1594 | if (s->port.line >= ARRAY_SIZE(auart_port)) { |
| @@ -854,21 +854,19 @@ static void qcom_geni_serial_stop_tx(struct uart_port *uport) · 853 unmodified lines | |||
| 854 | } | 854 | } |
| 855 | 855 | ||
| 856 | static void qcom_geni_serial_send_chunk_fifo(struct uart_port *uport, | 856 | static void qcom_geni_serial_send_chunk_fifo(struct uart_port *uport, |
| 857 | unsigned int chunk) | 857 | unsigned int remaining) |
| 858 | { | 858 | { |
| 859 | struct qcom_geni_serial_port *port = to_dev_port(uport); | 859 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 860 | struct circ_buf *xmit = &uport->state->xmit; | 860 | struct circ_buf *xmit = &uport->state->xmit; |
| 861 | unsigned int tx_bytes, c, remaining = chunk; | 861 | unsigned int tx_bytes; |
| 862 | u8 buf[BYTES_PER_FIFO_WORD]; | 862 | u8 buf[BYTES_PER_FIFO_WORD]; |
| 863 | 863 | ||
| 864 | while (remaining) { | 864 | while (remaining) { |
| 865 | memset(buf, 0, sizeof(buf)); | 865 | memset(buf, 0, sizeof(buf)); |
| 866 | tx_bytes = min(remaining, BYTES_PER_FIFO_WORD); | 866 | tx_bytes = min(remaining, BYTES_PER_FIFO_WORD); |
| 867 | 867 | ||
| 868 | for (c = 0; c < tx_bytes ; c++) { | 868 | memcpy(buf, &xmit->buf[xmit->tail], tx_bytes); |
| 869 | buf[c] = xmit->buf[xmit->tail]; | 869 | uart_xmit_advance(uport, tx_bytes); |
| 870 | uart_xmit_advance(uport, 1); | ||
| 871 | } | ||
| 872 | 870 | ||
| 873 | iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1); | 871 | iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1); |
| 874 | 872 | ||
| @@ -1535,6 +1533,7 @@ static const struct uart_ops qcom_geni_console_pops = { · 660 unmodified lines | |||
| 1535 | #ifdef CONFIG_CONSOLE_POLL | 1533 | #ifdef CONFIG_CONSOLE_POLL |
| 1536 | .poll_get_char = qcom_geni_serial_get_char, | 1534 | .poll_get_char = qcom_geni_serial_get_char, |
| 1537 | .poll_put_char = qcom_geni_serial_poll_put_char, | 1535 | .poll_put_char = qcom_geni_serial_poll_put_char, |
| 1536 | .poll_init = qcom_geni_serial_port_setup, | ||
| 1538 | #endif | 1537 | #endif |
| 1539 | .pm = qcom_geni_serial_pm, | 1538 | .pm = qcom_geni_serial_pm, |
| 1540 | }; | 1539 | }; |
| @@ -41,7 +41,7 @@ · 40 unmodified lines | |||
| 41 | #include <asm/sibyte/swarm.h> | 41 | #include <asm/sibyte/swarm.h> |
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) | 44 | #if defined(CONFIG_SIBYTE_BCM1x80) |
| 45 | #include <asm/sibyte/bcm1480_regs.h> | 45 | #include <asm/sibyte/bcm1480_regs.h> |
| 46 | #include <asm/sibyte/bcm1480_int.h> | 46 | #include <asm/sibyte/bcm1480_int.h> |
| 47 | 47 | ||
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/console.h> | 16 | #include <linux/console.h> |
| 17 | #include <linux/gpio/consumer.h> | 17 | #include <linux/gpio/consumer.h> |
| 18 | #include <linux/kernel.h> | ||
| 18 | #include <linux/of.h> | 19 | #include <linux/of.h> |
| 19 | #include <linux/proc_fs.h> | 20 | #include <linux/proc_fs.h> |
| 20 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
| @@ -48,9 +49,6 @@ static struct lock_class_key port_lock_key; · 27 unmodified lines | |||
| 48 | */ | 49 | */ |
| 49 | #define RS485_MAX_RTS_DELAY 100 /* msecs */ | 50 | #define RS485_MAX_RTS_DELAY 100 /* msecs */ |
| 50 | 51 | ||
| 51 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | ||
| 52 | const struct ktermios *old_termios); | ||
| 53 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); | ||
| 54 | static void uart_change_pm(struct uart_state *state, | 52 | static void uart_change_pm(struct uart_state *state, |
| 55 | enum uart_pm_state pm_state); | 53 | enum uart_pm_state pm_state); |
| 56 | 54 | ||
| @@ -137,7 +135,7 @@ static void __uart_start(struct tty_struct *tty) · 80 unmodified lines | |||
| 137 | struct uart_state *state = tty->driver_data; | 135 | struct uart_state *state = tty->driver_data; |
| 138 | struct uart_port *port = state->uart_port; | 136 | struct uart_port *port = state->uart_port; |
| 139 | 137 | ||
| 140 | if (port && !uart_tx_stopped(port)) | 138 | if (port && !(port->flags & UPF_DEAD) && !uart_tx_stopped(port)) |
| 141 | port->ops->start_tx(port); | 139 | port->ops->start_tx(port); |
| 142 | } | 140 | } |
| 143 | 141 | ||
| @@ -177,6 +175,51 @@ static void uart_port_dtr_rts(struct uart_port *uport, bool active) · 33 unmodified lines | |||
| 177 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 175 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
| 178 | } | 176 | } |
| 179 | 177 | ||
| 178 | /* Caller holds port mutex */ | ||
| 179 | static void uart_change_line_settings(struct tty_struct *tty, struct uart_state *state, | ||
| 180 | const struct ktermios *old_termios) | ||
| 181 | { | ||
| 182 | struct uart_port *uport = uart_port_check(state); | ||
| 183 | struct ktermios *termios; | ||
| 184 | bool old_hw_stopped; | ||
| 185 | |||
| 186 | /* | ||
| 187 | * If we have no tty, termios, or the port does not exist, | ||
| 188 | * then we can't set the parameters for this port. | ||
| 189 | */ | ||
| 190 | if (!tty || uport->type == PORT_UNKNOWN) | ||
| 191 | return; | ||
| 192 | |||
| 193 | termios = &tty->termios; | ||
| 194 | uport->ops->set_termios(uport, termios, old_termios); | ||
| 195 | |||
| 196 | /* | ||
| 197 | * Set modem status enables based on termios cflag | ||
| 198 | */ | ||
| 199 | spin_lock_irq(&uport->lock); | ||
| 200 | if (termios->c_cflag & CRTSCTS) | ||
| 201 | uport->status |= UPSTAT_CTS_ENABLE; | ||
| 202 | else | ||
| 203 | uport->status &= ~UPSTAT_CTS_ENABLE; | ||
| 204 | |||
| 205 | if (termios->c_cflag & CLOCAL) | ||
| 206 | uport->status &= ~UPSTAT_DCD_ENABLE; | ||
| 207 | else | ||
| 208 | uport->status |= UPSTAT_DCD_ENABLE; | ||
| 209 | |||
| 210 | /* reset sw-assisted CTS flow control based on (possibly) new mode */ | ||
| 211 | old_hw_stopped = uport->hw_stopped; | ||
| 212 | uport->hw_stopped = uart_softcts_mode(uport) && | ||
| 213 | !(uport->ops->get_mctrl(uport) & TIOCM_CTS); | ||
| 214 | if (uport->hw_stopped != old_hw_stopped) { | ||
| 215 | if (!old_hw_stopped) | ||
| 216 | uport->ops->stop_tx(uport); | ||
| 217 | else | ||
| 218 | __uart_start(tty); | ||
| 219 | } | ||
| 220 | spin_unlock_irq(&uport->lock); | ||
| 221 | } | ||
| 222 | |||
| 180 | /* | 223 | /* |
| 181 | * Startup the port. This will be called once per open. All calls | 224 | * Startup the port. This will be called once per open. All calls |
| 182 | * will be serialised by the per-port mutex. | 225 | * will be serialised by the per-port mutex. |
| @@ -232,7 +275,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, · 49 unmodified lines | |||
| 232 | /* | 275 | /* |
| 233 | * Initialise the hardware port settings. | 276 | * Initialise the hardware port settings. |
| 234 | */ | 277 | */ |
| 235 | uart_change_speed(tty, state, NULL); | 278 | uart_change_line_settings(tty, state, NULL); |
| 236 | 279 | ||
| 237 | /* | 280 | /* |
| 238 | * Setup the RTS and DTR signals once the | 281 | * Setup the RTS and DTR signals once the |
| @@ -485,52 +528,6 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) · 246 unmodified lines | |||
| 485 | } | 528 | } |
| 486 | EXPORT_SYMBOL(uart_get_divisor); | 529 | EXPORT_SYMBOL(uart_get_divisor); |
| 487 | 530 | ||
| 488 | /* Caller holds port mutex */ | ||
| 489 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | ||
| 490 | const struct ktermios *old_termios) | ||
| 491 | { | ||
| 492 | struct uart_port *uport = uart_port_check(state); | ||
| 493 | struct ktermios *termios; | ||
| 494 | int hw_stopped; | ||
| 495 | |||
| 496 | /* | ||
| 497 | * If we have no tty, termios, or the port does not exist, | ||
| 498 | * then we can't set the parameters for this port. | ||
| 499 | */ | ||
| 500 | if (!tty || uport->type == PORT_UNKNOWN) | ||
| 501 | return; | ||
| 502 | |||
| 503 | termios = &tty->termios; | ||
| 504 | uport->ops->set_termios(uport, termios, old_termios); | ||
| 505 | |||
| 506 | /* | ||
| 507 | * Set modem status enables based on termios cflag | ||
| 508 | */ | ||
| 509 | spin_lock_irq(&uport->lock); | ||
| 510 | if (termios->c_cflag & CRTSCTS) | ||
| 511 | uport->status |= UPSTAT_CTS_ENABLE; | ||
| 512 | else | ||
| 513 | uport->status &= ~UPSTAT_CTS_ENABLE; | ||
| 514 | |||
| 515 | if (termios->c_cflag & CLOCAL) | ||
| 516 | uport->status &= ~UPSTAT_DCD_ENABLE; | ||
| 517 | else | ||
| 518 | uport->status |= UPSTAT_DCD_ENABLE; | ||
| 519 | |||
| 520 | /* reset sw-assisted CTS flow control based on (possibly) new mode */ | ||
| 521 | hw_stopped = uport->hw_stopped; | ||
| 522 | uport->hw_stopped = uart_softcts_mode(uport) && | ||
| 523 | !(uport->ops->get_mctrl(uport) & TIOCM_CTS); | ||
| 524 | if (uport->hw_stopped) { | ||
| 525 | if (!hw_stopped) | ||
| 526 | uport->ops->stop_tx(uport); | ||
| 527 | } else { | ||
| 528 | if (hw_stopped) | ||
| 529 | __uart_start(tty); | ||
| 530 | } | ||
| 531 | spin_unlock_irq(&uport->lock); | ||
| 532 | } | ||
| 533 | |||
| 534 | static int uart_put_char(struct tty_struct *tty, unsigned char c) | 531 | static int uart_put_char(struct tty_struct *tty, unsigned char c) |
| 535 | { | 532 | { |
| 536 | struct uart_state *state = tty->driver_data; | 533 | struct uart_state *state = tty->driver_data; |
| @@ -994,7 +991,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, · 457 unmodified lines | |||
| 994 | current->comm, | 991 | current->comm, |
| 995 | tty_name(port->tty)); | 992 | tty_name(port->tty)); |
| 996 | } | 993 | } |
| 997 | uart_change_speed(tty, state, NULL); | 994 | uart_change_line_settings(tty, state, NULL); |
| 998 | } | 995 | } |
| 999 | } else { | 996 | } else { |
| 1000 | retval = uart_startup(tty, state, true); | 997 | retval = uart_startup(tty, state, true); |
| @@ -1491,7 +1488,7 @@ static int uart_set_iso7816_config(struct uart_port *port, · 490 unmodified lines | |||
| 1491 | * There are 5 words reserved for future use. Check that userspace | 1488 | * There are 5 words reserved for future use. Check that userspace |
| 1492 | * doesn't put stuff in there to prevent breakages in the future. | 1489 | * doesn't put stuff in there to prevent breakages in the future. |
| 1493 | */ | 1490 | */ |
| 1494 | for (i = 0; i < 5; i++) | 1491 | for (i = 0; i < ARRAY_SIZE(iso7816.reserved); i++) |
| 1495 | if (iso7816.reserved[i]) | 1492 | if (iso7816.reserved[i]) |
| 1496 | return -EINVAL; | 1493 | return -EINVAL; |
| 1497 | 1494 | ||
| @@ -1552,7 +1549,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) · 54 unmodified lines | |||
| 1552 | goto out; | 1549 | goto out; |
| 1553 | 1550 | ||
| 1554 | /* rs485_config requires more locking than others */ | 1551 | /* rs485_config requires more locking than others */ |
| 1555 | if (cmd == TIOCGRS485) | 1552 | if (cmd == TIOCSRS485) |
| 1556 | down_write(&tty->termios_rwsem); | 1553 | down_write(&tty->termios_rwsem); |
| 1557 | 1554 | ||
| 1558 | mutex_lock(&port->mutex); | 1555 | mutex_lock(&port->mutex); |
| @@ -1595,7 +1592,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) · 36 unmodified lines | |||
| 1595 | } | 1592 | } |
| 1596 | out_up: | 1593 | out_up: |
| 1597 | mutex_unlock(&port->mutex); | 1594 | mutex_unlock(&port->mutex); |
| 1598 | if (cmd == TIOCGRS485) | 1595 | if (cmd == TIOCSRS485) |
| 1599 | up_write(&tty->termios_rwsem); | 1596 | up_write(&tty->termios_rwsem); |
| 1600 | out: | 1597 | out: |
| 1601 | return ret; | 1598 | return ret; |
| @@ -1656,15 +1653,15 @@ static void uart_set_termios(struct tty_struct *tty, · 54 unmodified lines | |||
| 1656 | goto out; | 1653 | goto out; |
| 1657 | } | 1654 | } |
| 1658 | 1655 | ||
| 1659 | uart_change_speed(tty, state, old_termios); | 1656 | uart_change_line_settings(tty, state, old_termios); |
| 1660 | /* reload cflag from termios; port driver may have overridden flags */ | 1657 | /* reload cflag from termios; port driver may have overridden flags */ |
| 1661 | cflag = tty->termios.c_cflag; | 1658 | cflag = tty->termios.c_cflag; |
| 1662 | 1659 | ||
| 1663 | /* Handle transition to B0 status */ | 1660 | /* Handle transition to B0 status */ |
| 1664 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) | 1661 | if (((old_termios->c_cflag & CBAUD) != B0) && ((cflag & CBAUD) == B0)) |
| 1665 | uart_clear_mctrl(uport, TIOCM_RTS | TIOCM_DTR); | 1662 | uart_clear_mctrl(uport, TIOCM_RTS | TIOCM_DTR); |
| 1666 | /* Handle transition away from B0 status */ | 1663 | /* Handle transition away from B0 status */ |
| 1667 | else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { | 1664 | else if (((old_termios->c_cflag & CBAUD) == B0) && ((cflag & CBAUD) != B0)) { |
| 1668 | unsigned int mask = TIOCM_DTR; | 1665 | unsigned int mask = TIOCM_DTR; |
| 1669 | 1666 | ||
| 1670 | if (!(cflag & CRTSCTS) || !tty_throttled(tty)) | 1667 | if (!(cflag & CRTSCTS) || !tty_throttled(tty)) |
| @@ -2452,7 +2449,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) · 781 unmodified lines | |||
| 2452 | ret = ops->startup(uport); | 2449 | ret = ops->startup(uport); |
| 2453 | if (ret == 0) { | 2450 | if (ret == 0) { |
| 2454 | if (tty) | 2451 | if (tty) |
| 2455 | uart_change_speed(tty, state, NULL); | 2452 | uart_change_line_settings(tty, state, NULL); |
| 2456 | spin_lock_irq(&uport->lock); | 2453 | spin_lock_irq(&uport->lock); |
| 2457 | if (!(uport->rs485.flags & SER_RS485_ENABLED)) | 2454 | if (!(uport->rs485.flags & SER_RS485_ENABLED)) |
| 2458 | ops->set_mctrl(uport, uport->mctrl); | 2455 | ops->set_mctrl(uport, uport->mctrl); |
| @@ -2593,6 +2590,7 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) · 134 unmodified lines | |||
| 2593 | { | 2590 | { |
| 2594 | struct uart_driver *drv = driver->driver_state; | 2591 | struct uart_driver *drv = driver->driver_state; |
| 2595 | struct uart_state *state = drv->state + line; | 2592 | struct uart_state *state = drv->state + line; |
| 2593 | enum uart_pm_state pm_state; | ||
| 2596 | struct tty_port *tport; | 2594 | struct tty_port *tport; |
| 2597 | struct uart_port *port; | 2595 | struct uart_port *port; |
| 2598 | int baud = 9600; | 2596 | int baud = 9600; |
| @@ -2610,6 +2608,9 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) · 11 unmodified lines | |||
| 2610 | goto out; | 2608 | goto out; |
| 2611 | } | 2609 | } |
| 2612 | 2610 | ||
| 2611 | pm_state = state->pm_state; | ||
| 2612 | uart_change_pm(state, UART_PM_STATE_ON); | ||
| 2613 | |||
| 2613 | if (port->ops->poll_init) { | 2614 | if (port->ops->poll_init) { |
| 2614 | /* | 2615 | /* |
| 2615 | * We don't set initialized as we only initialized the hw, | 2616 | * We don't set initialized as we only initialized the hw, |
| @@ -2626,6 +2627,8 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) · 10 unmodified lines | |||
| 2626 | console_list_unlock(); | 2627 | console_list_unlock(); |
| 2627 | } | 2628 | } |
| 2628 | out: | 2629 | out: |
| 2630 | if (ret) | ||
| 2631 | uart_change_pm(state, pm_state); | ||
| 2629 | mutex_unlock(&tport->mutex); | 2632 | mutex_unlock(&tport->mutex); |
| 2630 | return ret; | 2633 | return ret; |
| 2631 | } | 2634 | } |
| @@ -3305,13 +3308,13 @@ void uart_handle_cts_change(struct uart_port *uport, bool active) · 673 unmodified lines | |||
| 3305 | if (uart_softcts_mode(uport)) { | 3308 | if (uart_softcts_mode(uport)) { |
| 3306 | if (uport->hw_stopped) { | 3309 | if (uport->hw_stopped) { |
| 3307 | if (active) { | 3310 | if (active) { |
| 3308 | uport->hw_stopped = 0; | 3311 | uport->hw_stopped = false; |
| 3309 | uport->ops->start_tx(uport); | 3312 | uport->ops->start_tx(uport); |
| 3310 | uart_write_wakeup(uport); | 3313 | uart_write_wakeup(uport); |
| 3311 | } | 3314 | } |
| 3312 | } else { | 3315 | } else { |
| 3313 | if (!active) { | 3316 | if (!active) { |
| 3314 | uport->hw_stopped = 1; | 3317 | uport->hw_stopped = true; |
| 3315 | uport->ops->stop_tx(uport); | 3318 | uport->ops->stop_tx(uport); |
| 3316 | } | 3319 | } |
| 3317 | } | 3320 | } |
| @@ -588,14 +588,28 @@ static void sci_start_tx(struct uart_port *port) · 587 unmodified lines | |||
| 588 | 588 | ||
| 589 | if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && | 589 | if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && |
| 590 | dma_submit_error(s->cookie_tx)) { | 590 | dma_submit_error(s->cookie_tx)) { |
| 591 | if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) | ||
| 592 | /* Switch irq from SCIF to DMA */ | ||
| 593 | disable_irq(s->irqs[SCIx_TXI_IRQ]); | ||
| 594 | |||
| 591 | s->cookie_tx = 0; | 595 | s->cookie_tx = 0; |
| 592 | schedule_work(&s->work_tx); | 596 | schedule_work(&s->work_tx); |
| 593 | } | 597 | } |
| 594 | #endif | 598 | #endif |
| 595 | 599 | ||
| 596 | if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | 600 | if (!s->chan_tx || s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE || |
| 601 | port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | ||
| 597 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | 602 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ |
| 598 | ctrl = serial_port_in(port, SCSCR); | 603 | ctrl = serial_port_in(port, SCSCR); |
| 604 | |||
| 605 | /* | ||
| 606 | * For SCI, TE (transmit enable) must be set after setting TIE | ||
| 607 | * (transmit interrupt enable) or in the same instruction to start | ||
| 608 | * the transmit process. | ||
| 609 | */ | ||
| 610 | if (port->type == PORT_SCI) | ||
| 611 | ctrl |= SCSCR_TE; | ||
| 612 | |||
| 599 | serial_port_out(port, SCSCR, ctrl | SCSCR_TIE); | 613 | serial_port_out(port, SCSCR, ctrl | SCSCR_TIE); |
| 600 | } | 614 | } |
| 601 | } | 615 | } |
| @@ -833,6 +847,11 @@ static void sci_transmit_chars(struct uart_port *port) · 231 unmodified lines | |||
| 833 | } else if (!uart_circ_empty(xmit) && !stopped) { | 847 | } else if (!uart_circ_empty(xmit) && !stopped) { |
| 834 | c = xmit->buf[xmit->tail]; | 848 | c = xmit->buf[xmit->tail]; |
| 835 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 849 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
| 850 | } else if (port->type == PORT_SCI && uart_circ_empty(xmit)) { | ||
| 851 | ctrl = serial_port_in(port, SCSCR); | ||
| 852 | ctrl &= ~SCSCR_TE; | ||
| 853 | serial_port_out(port, SCSCR, ctrl); | ||
| 854 | return; | ||
| 836 | } else { | 855 | } else { |
| 837 | break; | 856 | break; |
| 838 | } | 857 | } |
| @@ -846,9 +865,16 @@ static void sci_transmit_chars(struct uart_port *port) · 7 unmodified lines | |||
| 846 | 865 | ||
| 847 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 866 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
| 848 | uart_write_wakeup(port); | 867 | uart_write_wakeup(port); |
| 849 | if (uart_circ_empty(xmit)) | 868 | if (uart_circ_empty(xmit)) { |
| 850 | sci_stop_tx(port); | 869 | if (port->type == PORT_SCI) { |
| 870 | ctrl = serial_port_in(port, SCSCR); | ||
| 871 | ctrl &= ~SCSCR_TIE; | ||
| 872 | ctrl |= SCSCR_TEIE; | ||
| 873 | serial_port_out(port, SCSCR, ctrl); | ||
| 874 | } | ||
| 851 | 875 | ||
| 876 | sci_stop_tx(port); | ||
| 877 | } | ||
| 852 | } | 878 | } |
| 853 | 879 | ||
| 854 | static void sci_receive_chars(struct uart_port *port) | 880 | static void sci_receive_chars(struct uart_port *port) |
| @@ -1192,9 +1218,15 @@ static void sci_dma_tx_complete(void *arg) · 337 unmodified lines | |||
| 1192 | schedule_work(&s->work_tx); | 1218 | schedule_work(&s->work_tx); |
| 1193 | } else { | 1219 | } else { |
| 1194 | s->cookie_tx = -EINVAL; | 1220 | s->cookie_tx = -EINVAL; |
| 1195 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | 1221 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB || |
| 1222 | s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) { | ||
| 1196 | u16 ctrl = serial_port_in(port, SCSCR); | 1223 | u16 ctrl = serial_port_in(port, SCSCR); |
| 1197 | serial_port_out(port, SCSCR, ctrl & ~SCSCR_TIE); | 1224 | serial_port_out(port, SCSCR, ctrl & ~SCSCR_TIE); |
| 1225 | if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) { | ||
| 1226 | /* Switch irq from DMA to SCIF */ | ||
| 1227 | dmaengine_pause(s->chan_tx_saved); | ||
| 1228 | enable_irq(s->irqs[SCIx_TXI_IRQ]); | ||
| 1229 | } | ||
| 1198 | } | 1230 | } |
| 1199 | } | 1231 | } |
| 1200 | 1232 | ||
| @@ -1266,9 +1298,13 @@ static void sci_dma_rx_reenable_irq(struct sci_port *s) · 65 unmodified lines | |||
| 1266 | 1298 | ||
| 1267 | /* Direct new serial port interrupts back to CPU */ | 1299 | /* Direct new serial port interrupts back to CPU */ |
| 1268 | scr = serial_port_in(port, SCSCR); | 1300 | scr = serial_port_in(port, SCSCR); |
| 1269 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | 1301 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB || |
| 1270 | scr &= ~SCSCR_RDRQE; | 1302 | s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) { |
| 1271 | enable_irq(s->irqs[SCIx_RXI_IRQ]); | 1303 | enable_irq(s->irqs[SCIx_RXI_IRQ]); |
| 1304 | if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) | ||
| 1305 | scif_set_rtrg(port, s->rx_trigger); | ||
| 1306 | else | ||
| 1307 | scr &= ~SCSCR_RDRQE; | ||
| 1272 | } | 1308 | } |
| 1273 | serial_port_out(port, SCSCR, scr | SCSCR_RIE); | 1309 | serial_port_out(port, SCSCR, scr | SCSCR_RIE); |
| 1274 | } | 1310 | } |
| @@ -1505,7 +1541,8 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t) · 230 unmodified lines | |||
| 1505 | tty_flip_buffer_push(&port->state->port); | 1541 | tty_flip_buffer_push(&port->state->port); |
| 1506 | } | 1542 | } |
| 1507 | 1543 | ||
| 1508 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) | 1544 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB || |
| 1545 | s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) | ||
| 1509 | sci_dma_rx_submit(s, true); | 1546 | sci_dma_rx_submit(s, true); |
| 1510 | 1547 | ||
| 1511 | sci_dma_rx_reenable_irq(s); | 1548 | sci_dma_rx_reenable_irq(s); |
| @@ -1531,15 +1568,12 @@ static struct dma_chan *sci_request_dma_chan(struct uart_port *port, · 19 unmodified lines | |||
| 1531 | 1568 | ||
| 1532 | memset(&cfg, 0, sizeof(cfg)); | 1569 | memset(&cfg, 0, sizeof(cfg)); |
| 1533 | cfg.direction = dir; | 1570 | cfg.direction = dir; |
| 1534 | if (dir == DMA_MEM_TO_DEV) { | 1571 | cfg.dst_addr = port->mapbase + |
| 1535 | cfg.dst_addr = port->mapbase + | 1572 | (sci_getreg(port, SCxTDR)->offset << port->regshift); |
| 1536 | (sci_getreg(port, SCxTDR)->offset << port->regshift); | 1573 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
| 1537 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | 1574 | cfg.src_addr = port->mapbase + |
| 1538 | } else { | 1575 | (sci_getreg(port, SCxRDR)->offset << port->regshift); |
| 1539 | cfg.src_addr = port->mapbase + | 1576 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
| 1540 | (sci_getreg(port, SCxRDR)->offset << port->regshift); | ||
| 1541 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
| 1542 | } | ||
| 1543 | 1577 | ||
| 1544 | ret = dmaengine_slave_config(chan, &cfg); | 1578 | ret = dmaengine_slave_config(chan, &cfg); |
| 1545 | if (ret) { | 1579 | if (ret) { |
| @@ -1574,7 +1608,7 @@ static void sci_request_dma(struct uart_port *port) · 28 unmodified lines | |||
| 1574 | * Don't request a dma channel if no channel was specified | 1608 | * Don't request a dma channel if no channel was specified |
| 1575 | * in the device tree. | 1609 | * in the device tree. |
| 1576 | */ | 1610 | */ |
| 1577 | if (!of_find_property(port->dev->of_node, "dmas", NULL)) | 1611 | if (!of_property_present(port->dev->of_node, "dmas")) |
| 1578 | return; | 1612 | return; |
| 1579 | 1613 | ||
| 1580 | chan = sci_request_dma_chan(port, DMA_MEM_TO_DEV); | 1614 | chan = sci_request_dma_chan(port, DMA_MEM_TO_DEV); |
| @@ -1632,7 +1666,8 @@ static void sci_request_dma(struct uart_port *port) · 51 unmodified lines | |||
| 1632 | 1666 | ||
| 1633 | s->chan_rx_saved = s->chan_rx = chan; | 1667 | s->chan_rx_saved = s->chan_rx = chan; |
| 1634 | 1668 | ||
| 1635 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) | 1669 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB || |
| 1670 | s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) | ||
| 1636 | sci_dma_rx_submit(s, false); | 1671 | sci_dma_rx_submit(s, false); |
| 1637 | } | 1672 | } |
| 1638 | } | 1673 | } |
| @@ -1685,9 +1720,15 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) · 46 unmodified lines | |||
| 1685 | u16 ssr = serial_port_in(port, SCxSR); | 1720 | u16 ssr = serial_port_in(port, SCxSR); |
| 1686 | 1721 | ||
| 1687 | /* Disable future Rx interrupts */ | 1722 | /* Disable future Rx interrupts */ |
| 1688 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | 1723 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB || |
| 1689 | disable_irq_nosync(irq); | 1724 | s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) { |
| 1690 | scr |= SCSCR_RDRQE; | 1725 | disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]); |
| 1726 | if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) { | ||
| 1727 | scif_set_rtrg(port, 1); | ||
| 1728 | scr |= SCSCR_RIE; | ||
| 1729 | } else { | ||
| 1730 | scr |= SCSCR_RDRQE; | ||
| 1731 | } | ||
| 1691 | } else { | 1732 | } else { |
| 1692 | if (sci_dma_rx_submit(s, false) < 0) | 1733 | if (sci_dma_rx_submit(s, false) < 0) |
| 1693 | goto handle_pio; | 1734 | goto handle_pio; |
| @@ -1737,6 +1778,24 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr) · 43 unmodified lines | |||
| 1737 | return IRQ_HANDLED; | 1778 | return IRQ_HANDLED; |
| 1738 | } | 1779 | } |
| 1739 | 1780 | ||
| 1781 | static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr) | ||
| 1782 | { | ||
| 1783 | struct uart_port *port = ptr; | ||
| 1784 | unsigned long flags; | ||
| 1785 | unsigned short ctrl; | ||
| 1786 | |||
| 1787 | if (port->type != PORT_SCI) | ||
| 1788 | return sci_tx_interrupt(irq, ptr); | ||
| 1789 | |||
| 1790 | spin_lock_irqsave(&port->lock, flags); | ||
| 1791 | ctrl = serial_port_in(port, SCSCR); | ||
| 1792 | ctrl &= ~(SCSCR_TE | SCSCR_TEIE); | ||
| 1793 | serial_port_out(port, SCSCR, ctrl); | ||
| 1794 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 1795 | |||
| 1796 | return IRQ_HANDLED; | ||
| 1797 | } | ||
| 1798 | |||
| 1740 | static irqreturn_t sci_br_interrupt(int irq, void *ptr) | 1799 | static irqreturn_t sci_br_interrupt(int irq, void *ptr) |
| 1741 | { | 1800 | { |
| 1742 | struct uart_port *port = ptr; | 1801 | struct uart_port *port = ptr; |
| @@ -1873,7 +1932,7 @@ static const struct sci_irq_desc { · 130 unmodified lines | |||
| 1873 | 1932 | ||
| 1874 | [SCIx_TEI_IRQ] = { | 1933 | [SCIx_TEI_IRQ] = { |
| 1875 | .desc = "tx end", | 1934 | .desc = "tx end", |
| 1876 | .handler = sci_tx_interrupt, | 1935 | .handler = sci_tx_end_interrupt, |
| 1877 | }, | 1936 | }, |
| 1878 | 1937 | ||
| 1879 | /* | 1938 | /* |
| @@ -2580,8 +2639,14 @@ done: · 700 unmodified lines | |||
| 2580 | sci_set_mctrl(port, port->mctrl); | 2639 | sci_set_mctrl(port, port->mctrl); |
| 2581 | } | 2640 | } |
| 2582 | 2641 | ||
| 2583 | scr_val |= SCSCR_RE | SCSCR_TE | | 2642 | /* |
| 2584 | (s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)); | 2643 | * For SCI, TE (transmit enable) must be set after setting TIE |
| 2644 | * (transmit interrupt enable) or in the same instruction to | ||
| 2645 | * start the transmitting process. So skip setting TE here for SCI. | ||
| 2646 | */ | ||
| 2647 | if (port->type != PORT_SCI) | ||
| 2648 | scr_val |= SCSCR_TE; | ||
| 2649 | scr_val |= SCSCR_RE | (s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)); | ||
| 2585 | serial_port_out(port, SCSCR, scr_val | s->hscif_tot); | 2650 | serial_port_out(port, SCSCR, scr_val | s->hscif_tot); |
| 2586 | if ((srr + 1 == 5) && | 2651 | if ((srr + 1 == 5) && |
| 2587 | (port->type == PORT_SCIFA || port->type == PORT_SCIFB)) { | 2652 | (port->type == PORT_SCIFA || port->type == PORT_SCIFB)) { |
| @@ -3149,7 +3214,7 @@ static int sci_remove(struct platform_device *dev) · 561 unmodified lines | |||
| 3149 | #define SCI_OF_TYPE(data) ((unsigned long)(data) >> 16) | 3214 | #define SCI_OF_TYPE(data) ((unsigned long)(data) >> 16) |
| 3150 | #define SCI_OF_REGTYPE(data) ((unsigned long)(data) & 0xffff) | 3215 | #define SCI_OF_REGTYPE(data) ((unsigned long)(data) & 0xffff) |
| 3151 | 3216 | ||
| 3152 | static const struct of_device_id of_sci_match[] = { | 3217 | static const struct of_device_id of_sci_match[] __maybe_unused = { |
| 3153 | /* SoC-specific types */ | 3218 | /* SoC-specific types */ |
| 3154 | { | 3219 | { |
| 3155 | .compatible = "renesas,scif-r7s72100", | 3220 | .compatible = "renesas,scif-r7s72100", |
| @@ -59,6 +59,9 @@ enum { · 58 unmodified lines | |||
| 59 | #define SCSMR_SRC_19 0x0600 /* Sampling rate 1/19 */ | 59 | #define SCSMR_SRC_19 0x0600 /* Sampling rate 1/19 */ |
| 60 | #define SCSMR_SRC_27 0x0700 /* Sampling rate 1/27 */ | 60 | #define SCSMR_SRC_27 0x0700 /* Sampling rate 1/27 */ |
| 61 | 61 | ||
| 62 | /* Serial Control Register, SCI only bits */ | ||
| 63 | #define SCSCR_TEIE BIT(2) /* Transmit End Interrupt Enable */ | ||
| 64 | |||
| 62 | /* Serial Control Register, SCIFA/SCIFB only bits */ | 65 | /* Serial Control Register, SCIFA/SCIFB only bits */ |
| 63 | #define SCSCR_TDRQE BIT(15) /* Tx Data Transfer Request Enable */ | 66 | #define SCSCR_TDRQE BIT(15) /* Tx Data Transfer Request Enable */ |
| 64 | #define SCSCR_RDRQE BIT(14) /* Rx Data Transfer Request Enable */ | 67 | #define SCSCR_RDRQE BIT(14) /* Rx Data Transfer Request Enable */ |
| @@ -1250,7 +1250,7 @@ static struct platform_driver sprd_platform_driver = { · 1249 unmodified lines | |||
| 1250 | .remove = sprd_remove, | 1250 | .remove = sprd_remove, |
| 1251 | .driver = { | 1251 | .driver = { |
| 1252 | .name = "sprd_serial", | 1252 | .name = "sprd_serial", |
| 1253 | .of_match_table = of_match_ptr(serial_ids), | 1253 | .of_match_table = serial_ids, |
| 1254 | .pm = &sprd_pm_ops, | 1254 | .pm = &sprd_pm_ops, |
| 1255 | }, | 1255 | }, |
| 1256 | }; | 1256 | }; |
| @@ -693,8 +693,9 @@ static void stm32_usart_transmit_chars(struct uart_port *port) · 692 unmodified lines | |||
| 693 | int ret; | 693 | int ret; |
| 694 | 694 | ||
| 695 | if (!stm32_port->hw_flow_control && | 695 | if (!stm32_port->hw_flow_control && |
| 696 | port->rs485.flags & SER_RS485_ENABLED) { | 696 | port->rs485.flags & SER_RS485_ENABLED && |
| 697 | stm32_port->txdone = false; | 697 | (port->x_char || |
| 698 | !(uart_circ_empty(xmit) || uart_tx_stopped(port)))) { | ||
| 698 | stm32_usart_tc_interrupt_disable(port); | 699 | stm32_usart_tc_interrupt_disable(port); |
| 699 | stm32_usart_rs485_rts_enable(port); | 700 | stm32_usart_rs485_rts_enable(port); |
| 700 | } | 701 | } |
| @@ -743,7 +744,6 @@ static void stm32_usart_transmit_chars(struct uart_port *port) · 42 unmodified lines | |||
| 743 | stm32_usart_tx_interrupt_disable(port); | 744 | stm32_usart_tx_interrupt_disable(port); |
| 744 | if (!stm32_port->hw_flow_control && | 745 | if (!stm32_port->hw_flow_control && |
| 745 | port->rs485.flags & SER_RS485_ENABLED) { | 746 | port->rs485.flags & SER_RS485_ENABLED) { |
| 746 | stm32_port->txdone = true; | ||
| 747 | stm32_usart_tc_interrupt_enable(port); | 747 | stm32_usart_tc_interrupt_enable(port); |
| 748 | } | 748 | } |
| 749 | } | 749 | } |
| @@ -203,7 +203,6 @@ struct stm32_port { · 202 unmodified lines | |||
| 203 | bool hw_flow_control; | 203 | bool hw_flow_control; |
| 204 | bool swap; /* swap RX & TX pins */ | 204 | bool swap; /* swap RX & TX pins */ |
| 205 | bool fifoen; | 205 | bool fifoen; |
| 206 | bool txdone; | ||
| 207 | int rxftcfg; /* RX FIFO threshold CFG */ | 206 | int rxftcfg; /* RX FIFO threshold CFG */ |
| 208 | int txftcfg; /* TX FIFO threshold CFG */ | 207 | int txftcfg; /* TX FIFO threshold CFG */ |
| 209 | bool wakeup_src; | 208 | bool wakeup_src; |
| @@ -1403,7 +1403,7 @@ static int zs_probe(struct platform_device *op) · 1402 unmodified lines | |||
| 1403 | int keyboard_mouse = 0; | 1403 | int keyboard_mouse = 0; |
| 1404 | int err; | 1404 | int err; |
| 1405 | 1405 | ||
| 1406 | if (of_find_property(op->dev.of_node, "keyboard", NULL)) | 1406 | if (of_property_present(op->dev.of_node, "keyboard")) |
| 1407 | keyboard_mouse = 1; | 1407 | keyboard_mouse = 1; |
| 1408 | 1408 | ||
| 1409 | /* uarts must come before keyboards/mice */ | 1409 | /* uarts must come before keyboards/mice */ |
| @@ -1553,7 +1553,7 @@ static int __init sunzilog_init(void) · 143 unmodified lines | |||
| 1553 | 1553 | ||
| 1554 | for_each_node_by_name(dp, "zs") { | 1554 | for_each_node_by_name(dp, "zs") { |
| 1555 | num_sunzilog++; | 1555 | num_sunzilog++; |
| 1556 | if (of_find_property(dp, "keyboard", NULL)) | 1556 | if (of_property_present(dp, "keyboard")) |
| 1557 | num_keybms++; | 1557 | num_keybms++; |
| 1558 | } | 1558 | } |
| 1559 | 1559 | ||
| @@ -366,15 +366,14 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port) · 365 unmodified lines | |||
| 366 | /* Pick next descriptor and fill from buffer */ | 366 | /* Pick next descriptor and fill from buffer */ |
| 367 | bdp = qe_port->tx_cur; | 367 | bdp = qe_port->tx_cur; |
| 368 | 368 | ||
| 369 | while (!(ioread16be(&bdp->status) & BD_SC_READY) && | 369 | while (!(ioread16be(&bdp->status) & BD_SC_READY) && !uart_circ_empty(xmit)) { |
| 370 | (xmit->tail != xmit->head)) { | ||
| 371 | count = 0; | 370 | count = 0; |
| 372 | p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port); | 371 | p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port); |
| 373 | while (count < qe_port->tx_fifosize) { | 372 | while (count < qe_port->tx_fifosize) { |
| 374 | *p++ = xmit->buf[xmit->tail]; | 373 | *p++ = xmit->buf[xmit->tail]; |
| 375 | uart_xmit_advance(port, 1); | 374 | uart_xmit_advance(port, 1); |
| 376 | count++; | 375 | count++; |
| 377 | if (xmit->head == xmit->tail) | 376 | if (uart_circ_empty(xmit)) |
| 378 | break; | 377 | break; |
| 379 | } | 378 | } |
| 380 | 379 | ||
| @@ -1179,7 +1178,7 @@ static int soft_uart_init(struct platform_device *ofdev) · 798 unmodified lines | |||
| 1179 | struct qe_firmware_info *qe_fw_info; | 1178 | struct qe_firmware_info *qe_fw_info; |
| 1180 | int ret; | 1179 | int ret; |
| 1181 | 1180 | ||
| 1182 | if (of_find_property(np, "soft-uart", NULL)) { | 1181 | if (of_property_read_bool(np, "soft-uart")) { |
| 1183 | dev_dbg(&ofdev->dev, "using Soft-UART mode\n"); | 1182 | dev_dbg(&ofdev->dev, "using Soft-UART mode\n"); |
| 1184 | soft_uart = 1; | 1183 | soft_uart = 1; |
| 1185 | } else { | 1184 | } else { |
| @@ -287,7 +287,6 @@ struct slgt_info { · 286 unmodified lines | |||
| 287 | unsigned char *tx_buf; | 287 | unsigned char *tx_buf; |
| 288 | int tx_count; | 288 | int tx_count; |
| 289 | 289 | ||
| 290 | char *flag_buf; | ||
| 291 | bool drop_rts_on_tx_done; | 290 | bool drop_rts_on_tx_done; |
| 292 | struct _input_signal_events input_signal_events; | 291 | struct _input_signal_events input_signal_events; |
| 293 | 292 | ||
| @@ -730,7 +729,7 @@ static void set_termios(struct tty_struct *tty, · 436 unmodified lines | |||
| 730 | 729 | ||
| 731 | /* Handle turning off CRTSCTS */ | 730 | /* Handle turning off CRTSCTS */ |
| 732 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { | 731 | if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { |
| 733 | tty->hw_stopped = 0; | 732 | tty->hw_stopped = false; |
| 734 | tx_release(tty); | 733 | tx_release(tty); |
| 735 | } | 734 | } |
| 736 | } | 735 | } |
| @@ -1953,13 +1952,13 @@ static void cts_change(struct slgt_info *info, unsigned short status) · 1216 unmodified lines | |||
| 1953 | if (info->port.tty) { | 1952 | if (info->port.tty) { |
| 1954 | if (info->port.tty->hw_stopped) { | 1953 | if (info->port.tty->hw_stopped) { |
| 1955 | if (info->signals & SerialSignal_CTS) { | 1954 | if (info->signals & SerialSignal_CTS) { |
| 1956 | info->port.tty->hw_stopped = 0; | 1955 | info->port.tty->hw_stopped = false; |
| 1957 | info->pending_bh |= BH_TRANSMIT; | 1956 | info->pending_bh |= BH_TRANSMIT; |
| 1958 | return; | 1957 | return; |
| 1959 | } | 1958 | } |
| 1960 | } else { | 1959 | } else { |
| 1961 | if (!(info->signals & SerialSignal_CTS)) | 1960 | if (!(info->signals & SerialSignal_CTS)) |
| 1962 | info->port.tty->hw_stopped = 1; | 1961 | info->port.tty->hw_stopped = true; |
| 1963 | } | 1962 | } |
| 1964 | } | 1963 | } |
| 1965 | } | 1964 | } |
| @@ -3244,13 +3243,7 @@ static int alloc_tmp_rbuf(struct slgt_info *info) · 1278 unmodified lines | |||
| 3244 | info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); | 3243 | info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); |
| 3245 | if (info->tmp_rbuf == NULL) | 3244 | if (info->tmp_rbuf == NULL) |
| 3246 | return -ENOMEM; | 3245 | return -ENOMEM; |
| 3247 | /* unused flag buffer to satisfy receive_buf calling interface */ | 3246 | |
| 3248 | info->flag_buf = kzalloc(info->max_frame_size + 5, GFP_KERNEL); | ||
| 3249 | if (!info->flag_buf) { | ||
| 3250 | kfree(info->tmp_rbuf); | ||
| 3251 | info->tmp_rbuf = NULL; | ||
| 3252 | return -ENOMEM; | ||
| 3253 | } | ||
| 3254 | return 0; | 3247 | return 0; |
| 3255 | } | 3248 | } |
| 3256 | 3249 | ||
| @@ -3258,8 +3251,6 @@ static void free_tmp_rbuf(struct slgt_info *info) · 1 unmodified line | |||
| 3258 | { | 3251 | { |
| 3259 | kfree(info->tmp_rbuf); | 3252 | kfree(info->tmp_rbuf); |
| 3260 | info->tmp_rbuf = NULL; | 3253 | info->tmp_rbuf = NULL; |
| 3261 | kfree(info->flag_buf); | ||
| 3262 | info->flag_buf = NULL; | ||
| 3263 | } | 3254 | } |
| 3264 | 3255 | ||
| 3265 | /* | 3256 | /* |
| @@ -4657,7 +4648,8 @@ check_again: · 1391 unmodified lines | |||
| 4657 | hdlcdev_rx(info,info->tmp_rbuf, framesize); | 4648 | hdlcdev_rx(info,info->tmp_rbuf, framesize); |
| 4658 | else | 4649 | else |
| 4659 | #endif | 4650 | #endif |
| 4660 | ldisc_receive_buf(tty, info->tmp_rbuf, info->flag_buf, framesize); | 4651 | ldisc_receive_buf(tty, info->tmp_rbuf, NULL, |
| 4652 | framesize); | ||
| 4661 | } | 4653 | } |
| 4662 | } | 4654 | } |
| 4663 | free_rbufs(info, start, end); | 4655 | free_rbufs(info, start, end); |
| @@ -4691,8 +4683,8 @@ static bool rx_get_buf(struct slgt_info *info) · 27 unmodified lines | |||
| 4691 | DBGDATA(info, info->rbufs[i].buf, count, "rx"); | 4683 | DBGDATA(info, info->rbufs[i].buf, count, "rx"); |
| 4692 | DBGINFO(("rx_get_buf size=%d\n", count)); | 4684 | DBGINFO(("rx_get_buf size=%d\n", count)); |
| 4693 | if (count) | 4685 | if (count) |
| 4694 | ldisc_receive_buf(info->port.tty, info->rbufs[i].buf, | 4686 | ldisc_receive_buf(info->port.tty, info->rbufs[i].buf, NULL, |
| 4695 | info->flag_buf, count); | 4687 | count); |
| 4696 | free_rbufs(info, i, i); | 4688 | free_rbufs(info, i, i); |
| 4697 | return true; | 4689 | return true; |
| 4698 | } | 4690 | } |
| @@ -62,6 +62,8 @@ int __tty_check_change(struct tty_struct *tty, int sig); · 61 unmodified lines | |||
| 62 | int tty_check_change(struct tty_struct *tty); | 62 | int tty_check_change(struct tty_struct *tty); |
| 63 | void __stop_tty(struct tty_struct *tty); | 63 | void __stop_tty(struct tty_struct *tty); |
| 64 | void __start_tty(struct tty_struct *tty); | 64 | void __start_tty(struct tty_struct *tty); |
| 65 | void tty_write_unlock(struct tty_struct *tty); | ||
| 66 | int tty_write_lock(struct tty_struct *tty, int ndelay); | ||
| 65 | void tty_vhangup_session(struct tty_struct *tty); | 67 | void tty_vhangup_session(struct tty_struct *tty); |
| 66 | void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); | 68 | void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); |
| 67 | int tty_signal_session_leader(struct tty_struct *tty, int exit_session); | 69 | int tty_signal_session_leader(struct tty_struct *tty, int exit_session); |
| @@ -933,13 +933,13 @@ static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to) · 932 unmodified lines | |||
| 933 | return i; | 933 | return i; |
| 934 | } | 934 | } |
| 935 | 935 | ||
| 936 | static void tty_write_unlock(struct tty_struct *tty) | 936 | void tty_write_unlock(struct tty_struct *tty) |
| 937 | { | 937 | { |
| 938 | mutex_unlock(&tty->atomic_write_lock); | 938 | mutex_unlock(&tty->atomic_write_lock); |
| 939 | wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); | 939 | wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); |
| 940 | } | 940 | } |
| 941 | 941 | ||
| 942 | static int tty_write_lock(struct tty_struct *tty, int ndelay) | 942 | int tty_write_lock(struct tty_struct *tty, int ndelay) |
| 943 | { | 943 | { |
| 944 | if (!mutex_trylock(&tty->atomic_write_lock)) { | 944 | if (!mutex_trylock(&tty->atomic_write_lock)) { |
| 945 | if (ndelay) | 945 | if (ndelay) |
| @@ -3614,31 +3614,13 @@ static struct ctl_table tty_table[] = { · 2668 unmodified lines | |||
| 3614 | { } | 3614 | { } |
| 3615 | }; | 3615 | }; |
| 3616 | 3616 | ||
| 3617 | static struct ctl_table tty_dir_table[] = { | ||
| 3618 | { | ||
| 3619 | .procname = "tty", | ||
| 3620 | .mode = 0555, | ||
| 3621 | .child = tty_table, | ||
| 3622 | }, | ||
| 3623 | { } | ||
| 3624 | }; | ||
| 3625 | |||
| 3626 | static struct ctl_table tty_root_table[] = { | ||
| 3627 | { | ||
| 3628 | .procname = "dev", | ||
| 3629 | .mode = 0555, | ||
| 3630 | .child = tty_dir_table, | ||
| 3631 | }, | ||
| 3632 | { } | ||
| 3633 | }; | ||
| 3634 | |||
| 3635 | /* | 3617 | /* |
| 3636 | * Ok, now we can initialize the rest of the tty devices and can count | 3618 | * Ok, now we can initialize the rest of the tty devices and can count |
| 3637 | * on memory allocations, interrupts etc.. | 3619 | * on memory allocations, interrupts etc.. |
| 3638 | */ | 3620 | */ |
| 3639 | int __init tty_init(void) | 3621 | int __init tty_init(void) |
| 3640 | { | 3622 | { |
| 3641 | register_sysctl_table(tty_root_table); | 3623 | register_sysctl_init("dev/tty", tty_table); |
| 3642 | cdev_init(&tty_cdev, &tty_fops); | 3624 | cdev_init(&tty_cdev, &tty_fops); |
| 3643 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | 3625 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
| 3644 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | 3626 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | * discipline handling modules (like SLIP). | 7 | * discipline handling modules (like SLIP). |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/bits.h> | ||
| 10 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 11 | #include <linux/termios.h> | 12 | #include <linux/termios.h> |
| 12 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| @@ -40,10 +41,10 @@ · 27 unmodified lines | |||
| 40 | /* | 41 | /* |
| 41 | * Internal flag options for termios setting behavior | 42 | * Internal flag options for termios setting behavior |
| 42 | */ | 43 | */ |
| 43 | #define TERMIOS_FLUSH 1 | 44 | #define TERMIOS_FLUSH BIT(0) |
| 44 | #define TERMIOS_WAIT 2 | 45 | #define TERMIOS_WAIT BIT(1) |
| 45 | #define TERMIOS_TERMIO 4 | 46 | #define TERMIOS_TERMIO BIT(2) |
| 46 | #define TERMIOS_OLD 8 | 47 | #define TERMIOS_OLD BIT(3) |
| 47 | 48 | ||
| 48 | 49 | ||
| 49 | /** | 50 | /** |
| @@ -500,21 +501,42 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) · 450 unmodified lines | |||
| 500 | tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); | 501 | tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); |
| 501 | tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); | 502 | tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); |
| 502 | 503 | ||
| 503 | ld = tty_ldisc_ref(tty); | 504 | if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) { |
| 505 | retry_write_wait: | ||
| 506 | retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty)); | ||
| 507 | if (retval < 0) | ||
| 508 | return retval; | ||
| 504 | 509 | ||
| 505 | if (ld != NULL) { | 510 | if (tty_write_lock(tty, 0) < 0) |
| 506 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) | 511 | goto retry_write_wait; |
| 507 | ld->ops->flush_buffer(tty); | ||
| 508 | tty_ldisc_deref(ld); | ||
| 509 | } | ||
| 510 | 512 | ||
| 511 | if (opt & TERMIOS_WAIT) { | 513 | /* Racing writer? */ |
| 512 | tty_wait_until_sent(tty, 0); | 514 | if (tty_chars_in_buffer(tty)) { |
| 513 | if (signal_pending(current)) | 515 | tty_write_unlock(tty); |
| 514 | return -ERESTARTSYS; | 516 | goto retry_write_wait; |
| 515 | } | 517 | } |
| 516 | 518 | ||
| 517 | tty_set_termios(tty, &tmp_termios); | 519 | ld = tty_ldisc_ref(tty); |
| 520 | if (ld != NULL) { | ||
| 521 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) | ||
| 522 | ld->ops->flush_buffer(tty); | ||
| 523 | tty_ldisc_deref(ld); | ||
| 524 | } | ||
| 525 | |||
| 526 | if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) { | ||
| 527 | tty->ops->wait_until_sent(tty, 0); | ||
| 528 | if (signal_pending(current)) { | ||
| 529 | tty_write_unlock(tty); | ||
| 530 | return -ERESTARTSYS; | ||
| 531 | } | ||
| 532 | } | ||
| 533 | |||
| 534 | tty_set_termios(tty, &tmp_termios); | ||
| 535 | |||
| 536 | tty_write_unlock(tty); | ||
| 537 | } else { | ||
| 538 | tty_set_termios(tty, &tmp_termios); | ||
| 539 | } | ||
| 518 | 540 | ||
| 519 | /* FIXME: Arguably if tmp_termios == tty->termios AND the | 541 | /* FIXME: Arguably if tmp_termios == tty->termios AND the |
| 520 | actual requested termios was not tmp_termios then we may | 542 | actual requested termios was not tmp_termios then we may |
| @@ -58,7 +58,6 @@ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; · 57 unmodified lines | |||
| 58 | int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc) | 58 | int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc) |
| 59 | { | 59 | { |
| 60 | unsigned long flags; | 60 | unsigned long flags; |
| 61 | int ret = 0; | ||
| 62 | 61 | ||
| 63 | if (new_ldisc->num < N_TTY || new_ldisc->num >= NR_LDISCS) | 62 | if (new_ldisc->num < N_TTY || new_ldisc->num >= NR_LDISCS) |
| 64 | return -EINVAL; | 63 | return -EINVAL; |
| @@ -67,7 +66,7 @@ int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc) · 2 unmodified lines | |||
| 67 | tty_ldiscs[new_ldisc->num] = new_ldisc; | 66 | tty_ldiscs[new_ldisc->num] = new_ldisc; |
| 68 | raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); | 67 | raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); |
| 69 | 68 | ||
| 70 | return ret; | 69 | return 0; |
| 71 | } | 70 | } |
| 72 | EXPORT_SYMBOL(tty_register_ldisc); | 71 | EXPORT_SYMBOL(tty_register_ldisc); |
| 73 | 72 | ||
| @@ -135,10 +135,9 @@ const struct consw *conswitchp; · 134 unmodified lines | |||
| 135 | #define DEFAULT_CURSOR_BLINK_MS 200 | 135 | #define DEFAULT_CURSOR_BLINK_MS 200 |
| 136 | 136 | ||
| 137 | struct vc vc_cons [MAX_NR_CONSOLES]; | 137 | struct vc vc_cons [MAX_NR_CONSOLES]; |
| 138 | EXPORT_SYMBOL(vc_cons); | ||
| 138 | 139 | ||
| 139 | #ifndef VT_SINGLE_DRIVER | ||
| 140 | static const struct consw *con_driver_map[MAX_NR_CONSOLES]; | 140 | static const struct consw *con_driver_map[MAX_NR_CONSOLES]; |
| 141 | #endif | ||
| 142 | 141 | ||
| 143 | static int con_open(struct tty_struct *, struct file *); | 142 | static int con_open(struct tty_struct *, struct file *); |
| 144 | static void vc_init(struct vc_data *vc, unsigned int rows, | 143 | static void vc_init(struct vc_data *vc, unsigned int rows, |
| @@ -162,6 +161,7 @@ int default_utf8 = true; · 17 unmodified lines | |||
| 162 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); | 161 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); |
| 163 | int global_cursor_default = -1; | 162 | int global_cursor_default = -1; |
| 164 | module_param(global_cursor_default, int, S_IRUGO | S_IWUSR); | 163 | module_param(global_cursor_default, int, S_IRUGO | S_IWUSR); |
| 164 | EXPORT_SYMBOL(global_cursor_default); | ||
| 165 | 165 | ||
| 166 | static int cur_default = CUR_UNDERLINE; | 166 | static int cur_default = CUR_UNDERLINE; |
| 167 | module_param(cur_default, int, S_IRUGO | S_IWUSR); | 167 | module_param(cur_default, int, S_IRUGO | S_IWUSR); |
| @@ -174,6 +174,7 @@ static int ignore_poke; · 6 unmodified lines | |||
| 174 | 174 | ||
| 175 | int do_poke_blanked_console; | 175 | int do_poke_blanked_console; |
| 176 | int console_blanked; | 176 | int console_blanked; |
| 177 | EXPORT_SYMBOL(console_blanked); | ||
| 177 | 178 | ||
| 178 | static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ | 179 | static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ |
| 179 | static int vesa_off_interval; | 180 | static int vesa_off_interval; |
| @@ -190,8 +191,10 @@ static DECLARE_WORK(con_driver_unregister_work, con_driver_unregister_callback); · 10 unmodified lines | |||
| 190 | * saved_* variants are for save/restore around kernel debugger enter/leave | 191 | * saved_* variants are for save/restore around kernel debugger enter/leave |
| 191 | */ | 192 | */ |
| 192 | int fg_console; | 193 | int fg_console; |
| 194 | EXPORT_SYMBOL(fg_console); | ||
| 193 | int last_console; | 195 | int last_console; |
| 194 | int want_console = -1; | 196 | int want_console = -1; |
| 197 | |||
| 195 | static int saved_fg_console; | 198 | static int saved_fg_console; |
| 196 | static int saved_last_console; | 199 | static int saved_last_console; |
| 197 | static int saved_want_console; | 200 | static int saved_want_console; |
| @@ -223,6 +226,7 @@ static int scrollback_delta; · 25 unmodified lines | |||
| 223 | * the console on our behalf. | 226 | * the console on our behalf. |
| 224 | */ | 227 | */ |
| 225 | int (*console_blank_hook)(int); | 228 | int (*console_blank_hook)(int); |
| 229 | EXPORT_SYMBOL(console_blank_hook); | ||
| 226 | 230 | ||
| 227 | static DEFINE_TIMER(console_timer, blank_screen_t); | 231 | static DEFINE_TIMER(console_timer, blank_screen_t); |
| 228 | static int blank_state; | 232 | static int blank_state; |
| @@ -639,6 +643,7 @@ void update_region(struct vc_data *vc, unsigned long start, int count) · 410 unmodified lines | |||
| 639 | set_cursor(vc); | 643 | set_cursor(vc); |
| 640 | } | 644 | } |
| 641 | } | 645 | } |
| 646 | EXPORT_SYMBOL(update_region); | ||
| 642 | 647 | ||
| 643 | /* Structure of attributes is hardware-dependent */ | 648 | /* Structure of attributes is hardware-dependent */ |
| 644 | 649 | ||
| @@ -984,6 +989,7 @@ void redraw_screen(struct vc_data *vc, int is_switch) · 339 unmodified lines | |||
| 984 | notify_update(vc); | 989 | notify_update(vc); |
| 985 | } | 990 | } |
| 986 | } | 991 | } |
| 992 | EXPORT_SYMBOL(redraw_screen); | ||
| 987 | 993 | ||
| 988 | /* | 994 | /* |
| 989 | * Allocation, freeing and resizing of VTs. | 995 | * Allocation, freeing and resizing of VTs. |
| @@ -1000,10 +1006,10 @@ static void visual_init(struct vc_data *vc, int num, int init) · 10 unmodified lines | |||
| 1000 | if (vc->vc_sw) | 1006 | if (vc->vc_sw) |
| 1001 | module_put(vc->vc_sw->owner); | 1007 | module_put(vc->vc_sw->owner); |
| 1002 | vc->vc_sw = conswitchp; | 1008 | vc->vc_sw = conswitchp; |
| 1003 | #ifndef VT_SINGLE_DRIVER | 1009 | |
| 1004 | if (con_driver_map[num]) | 1010 | if (con_driver_map[num]) |
| 1005 | vc->vc_sw = con_driver_map[num]; | 1011 | vc->vc_sw = con_driver_map[num]; |
| 1006 | #endif | 1012 | |
| 1007 | __module_get(vc->vc_sw->owner); | 1013 | __module_get(vc->vc_sw->owner); |
| 1008 | vc->vc_num = num; | 1014 | vc->vc_num = num; |
| 1009 | vc->vc_display_fg = &master_display_fg; | 1015 | vc->vc_display_fg = &master_display_fg; |
| @@ -1305,6 +1311,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) · 295 unmodified lines | |||
| 1305 | { | 1311 | { |
| 1306 | return vc_do_resize(vc->port.tty, vc, cols, rows); | 1312 | return vc_do_resize(vc->port.tty, vc, cols, rows); |
| 1307 | } | 1313 | } |
| 1314 | EXPORT_SYMBOL(vc_resize); | ||
| 1308 | 1315 | ||
| 1309 | /** | 1316 | /** |
| 1310 | * vt_resize - resize a VT | 1317 | * vt_resize - resize a VT |
| @@ -1368,6 +1375,7 @@ enum { EPecma = 0, EPdec, EPeq, EPgt, EPlt}; · 57 unmodified lines | |||
| 1368 | 1375 | ||
| 1369 | const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, | 1376 | const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, |
| 1370 | 8,12,10,14, 9,13,11,15 }; | 1377 | 8,12,10,14, 9,13,11,15 }; |
| 1378 | EXPORT_SYMBOL(color_table); | ||
| 1371 | 1379 | ||
| 1372 | /* the default colour table, for VGA+ colour systems */ | 1380 | /* the default colour table, for VGA+ colour systems */ |
| 1373 | unsigned char default_red[] = { | 1381 | unsigned char default_red[] = { |
| @@ -1375,18 +1383,21 @@ unsigned char default_red[] = { · 1 unmodified line | |||
| 1375 | 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff | 1383 | 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff |
| 1376 | }; | 1384 | }; |
| 1377 | module_param_array(default_red, byte, NULL, S_IRUGO | S_IWUSR); | 1385 | module_param_array(default_red, byte, NULL, S_IRUGO | S_IWUSR); |
| 1386 | EXPORT_SYMBOL(default_red); | ||
| 1378 | 1387 | ||
| 1379 | unsigned char default_grn[] = { | 1388 | unsigned char default_grn[] = { |
| 1380 | 0x00, 0x00, 0xaa, 0x55, 0x00, 0x00, 0xaa, 0xaa, | 1389 | 0x00, 0x00, 0xaa, 0x55, 0x00, 0x00, 0xaa, 0xaa, |
| 1381 | 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, 0xff, 0xff | 1390 | 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, 0xff, 0xff |
| 1382 | }; | 1391 | }; |
| 1383 | module_param_array(default_grn, byte, NULL, S_IRUGO | S_IWUSR); | 1392 | module_param_array(default_grn, byte, NULL, S_IRUGO | S_IWUSR); |
| 1393 | EXPORT_SYMBOL(default_grn); | ||
| 1384 | 1394 | ||
| 1385 | unsigned char default_blu[] = { | 1395 | unsigned char default_blu[] = { |
| 1386 | 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, | 1396 | 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, |
| 1387 | 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff | 1397 | 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff |
| 1388 | }; | 1398 | }; |
| 1389 | module_param_array(default_blu, byte, NULL, S_IRUGO | S_IWUSR); | 1399 | module_param_array(default_blu, byte, NULL, S_IRUGO | S_IWUSR); |
| 1400 | EXPORT_SYMBOL(default_blu); | ||
| 1390 | 1401 | ||
| 1391 | /* | 1402 | /* |
| 1392 | * gotoxy() must verify all boundaries, because the arguments | 1403 | * gotoxy() must verify all boundaries, because the arguments |
| @@ -3143,93 +3154,84 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) · 1750 unmodified lines | |||
| 3143 | return -EFAULT; | 3154 | return -EFAULT; |
| 3144 | ret = 0; | 3155 | ret = 0; |
| 3145 | 3156 | ||
| 3146 | switch (type) | 3157 | switch (type) { |
| 3147 | { | 3158 | case TIOCL_SETSEL: |
| 3148 | case TIOCL_SETSEL: | 3159 | return set_selection_user((struct tiocl_selection |
| 3149 | ret = set_selection_user((struct tiocl_selection | 3160 | __user *)(p+1), tty); |
| 3150 | __user *)(p+1), tty); | 3161 | case TIOCL_PASTESEL: |
| 3151 | break; | 3162 | return paste_selection(tty); |
| 3152 | case TIOCL_PASTESEL: | 3163 | case TIOCL_UNBLANKSCREEN: |
| 3153 | ret = paste_selection(tty); | 3164 | console_lock(); |
| 3154 | break; | 3165 | unblank_screen(); |
| 3155 | case TIOCL_UNBLANKSCREEN: | 3166 | console_unlock(); |
| 3156 | console_lock(); | 3167 | break; |
| 3157 | unblank_screen(); | 3168 | case TIOCL_SELLOADLUT: |
| 3158 | console_unlock(); | 3169 | console_lock(); |
| 3159 | break; | 3170 | ret = sel_loadlut(p); |
| 3160 | case TIOCL_SELLOADLUT: | 3171 | console_unlock(); |
| 3161 | console_lock(); | 3172 | break; |
| 3162 | ret = sel_loadlut(p); | 3173 | case TIOCL_GETSHIFTSTATE: |
| 3163 | console_unlock(); | 3174 | /* |
| 3164 | break; | 3175 | * Make it possible to react to Shift+Mousebutton. Note that |
| 3165 | case TIOCL_GETSHIFTSTATE: | 3176 | * 'shift_state' is an undocumented kernel-internal variable; |
| 3177 | * programs not closely related to the kernel should not use | ||
| 3178 | * this. | ||
| 3179 | */ | ||
| 3180 | data = vt_get_shift_state(); | ||
| 3181 | return put_user(data, p); | ||
| 3182 | case TIOCL_GETMOUSEREPORTING: | ||
| 3183 | console_lock(); /* May be overkill */ | ||
| 3184 | data = mouse_reporting(); | ||
| 3185 | console_unlock(); | ||
| 3186 | return put_user(data, p); | ||
| 3187 | case TIOCL_SETVESABLANK: | ||
| 3188 | console_lock(); | ||
| 3189 | ret = set_vesa_blanking(p); | ||
| 3190 | console_unlock(); | ||
| 3191 | break; | ||
| 3192 | case TIOCL_GETKMSGREDIRECT: | ||
| 3193 | data = vt_get_kmsg_redirect(); | ||
| 3194 | return put_user(data, p); | ||
| 3195 | case TIOCL_SETKMSGREDIRECT: | ||
| 3196 | if (!capable(CAP_SYS_ADMIN)) | ||
| 3197 | return -EPERM; | ||
| 3166 | 3198 | ||
| 3167 | /* | 3199 | if (get_user(data, p+1)) |
| 3168 | * Make it possible to react to Shift+Mousebutton. | 3200 | return -EFAULT; |
| 3169 | * Note that 'shift_state' is an undocumented | 3201 | |
| 3170 | * kernel-internal variable; programs not closely | 3202 | vt_kmsg_redirect(data); |
| 3171 | * related to the kernel should not use this. | 3203 | |
| 3172 | */ | 3204 | break; |
| 3173 | data = vt_get_shift_state(); | 3205 | case TIOCL_GETFGCONSOLE: |
| 3174 | ret = put_user(data, p); | 3206 | /* |
| 3175 | break; | 3207 | * No locking needed as this is a transiently correct return |
| 3176 | case TIOCL_GETMOUSEREPORTING: | 3208 | * anyway if the caller hasn't disabled switching. |
| 3177 | console_lock(); /* May be overkill */ | 3209 | */ |
| 3178 | data = mouse_reporting(); | 3210 | return fg_console; |
| 3179 | console_unlock(); | 3211 | case TIOCL_SCROLLCONSOLE: |
| 3180 | ret = put_user(data, p); | 3212 | if (get_user(lines, (s32 __user *)(p+4))) |
| 3181 | break; | 3213 | return -EFAULT; |
| 3182 | case TIOCL_SETVESABLANK: | 3214 | |
| 3183 | console_lock(); | 3215 | /* |
| 3184 | ret = set_vesa_blanking(p); | 3216 | * Needs the console lock here. Note that lots of other calls |
| 3185 | console_unlock(); | 3217 | * need fixing before the lock is actually useful! |
| 3186 | break; | 3218 | */ |
| 3187 | case TIOCL_GETKMSGREDIRECT: | 3219 | console_lock(); |
| 3188 | data = vt_get_kmsg_redirect(); | 3220 | scrollfront(vc_cons[fg_console].d, lines); |
| 3189 | ret = put_user(data, p); | 3221 | console_unlock(); |
| 3190 | break; | 3222 | break; |
| 3191 | case TIOCL_SETKMSGREDIRECT: | 3223 | case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */ |
| 3192 | if (!capable(CAP_SYS_ADMIN)) { | 3224 | console_lock(); |
| 3193 | ret = -EPERM; | 3225 | ignore_poke = 1; |
| 3194 | } else { | 3226 | do_blank_screen(0); |
| 3195 | if (get_user(data, p+1)) | 3227 | console_unlock(); |
| 3196 | ret = -EFAULT; | 3228 | break; |
| 3197 | else | 3229 | case TIOCL_BLANKEDSCREEN: |
| 3198 | vt_kmsg_redirect(data); | 3230 | return console_blanked; |
| 3199 | } | 3231 | default: |
| 3200 | break; | 3232 | return -EINVAL; |
| 3201 | case TIOCL_GETFGCONSOLE: | ||
| 3202 | /* No locking needed as this is a transiently | ||
| 3203 | correct return anyway if the caller hasn't | ||
| 3204 | disabled switching */ | ||
| 3205 | ret = fg_console; | ||
| 3206 | break; | ||
| 3207 | case TIOCL_SCROLLCONSOLE: | ||
| 3208 | if (get_user(lines, (s32 __user *)(p+4))) { | ||
| 3209 | ret = -EFAULT; | ||
| 3210 | } else { | ||
| 3211 | /* Need the console lock here. Note that lots | ||
| 3212 | of other calls need fixing before the lock | ||
| 3213 | is actually useful ! */ | ||
| 3214 | console_lock(); | ||
| 3215 | scrollfront(vc_cons[fg_console].d, lines); | ||
| 3216 | console_unlock(); | ||
| 3217 | ret = 0; | ||
| 3218 | } | ||
| 3219 | break; | ||
| 3220 | case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */ | ||
| 3221 | console_lock(); | ||
| 3222 | ignore_poke = 1; | ||
| 3223 | do_blank_screen(0); | ||
| 3224 | console_unlock(); | ||
| 3225 | break; | ||
| 3226 | case TIOCL_BLANKEDSCREEN: | ||
| 3227 | ret = console_blanked; | ||
| 3228 | break; | ||
| 3229 | default: | ||
| 3230 | ret = -EINVAL; | ||
| 3231 | break; | ||
| 3232 | } | 3233 | } |
| 3234 | |||
| 3233 | return ret; | 3235 | return ret; |
| 3234 | } | 3236 | } |
| 3235 | 3237 | ||
| @@ -3571,8 +3573,6 @@ int __init vty_init(const struct file_operations *console_fops) · 335 unmodified lines | |||
| 3571 | return 0; | 3573 | return 0; |
| 3572 | } | 3574 | } |
| 3573 | 3575 | ||
| 3574 | #ifndef VT_SINGLE_DRIVER | ||
| 3575 | |||
| 3576 | static struct class *vtconsole_class; | 3576 | static struct class *vtconsole_class; |
| 3577 | 3577 | ||
| 3578 | static int do_bind_con_driver(const struct consw *csw, int first, int last, | 3578 | static int do_bind_con_driver(const struct consw *csw, int first, int last, |
| @@ -4236,6 +4236,7 @@ void give_up_console(const struct consw *csw) · 657 unmodified lines | |||
| 4236 | do_unregister_con_driver(csw); | 4236 | do_unregister_con_driver(csw); |
| 4237 | console_unlock(); | 4237 | console_unlock(); |
| 4238 | } | 4238 | } |
| 4239 | EXPORT_SYMBOL(give_up_console); | ||
| 4239 | 4240 | ||
| 4240 | static int __init vtconsole_class_init(void) | 4241 | static int __init vtconsole_class_init(void) |
| 4241 | { | 4242 | { |
| @@ -4273,8 +4274,6 @@ static int __init vtconsole_class_init(void) · 31 unmodified lines | |||
| 4273 | } | 4274 | } |
| 4274 | postcore_initcall(vtconsole_class_init); | 4275 | postcore_initcall(vtconsole_class_init); |
| 4275 | 4276 | ||
| 4276 | #endif | ||
| 4277 | |||
| 4278 | /* | 4277 | /* |
| 4279 | * Screen blanking | 4278 | * Screen blanking |
| 4280 | */ | 4279 | */ |
| @@ -4792,23 +4791,3 @@ void vc_scrolldelta_helper(struct vc_data *c, int lines, · 511 unmodified lines | |||
| 4792 | c->vc_visible_origin = ubase + (from + from_off) % wrap; | 4791 | c->vc_visible_origin = ubase + (from + from_off) % wrap; |
| 4793 | } | 4792 | } |
| 4794 | EXPORT_SYMBOL_GPL(vc_scrolldelta_helper); | 4793 | EXPORT_SYMBOL_GPL(vc_scrolldelta_helper); |
| 4795 | |||
| 4796 | /* | ||
| 4797 | * Visible symbols for modules | ||
| 4798 | */ | ||
| 4799 | |||
| 4800 | EXPORT_SYMBOL(color_table); | ||
| 4801 | EXPORT_SYMBOL(default_red); | ||
| 4802 | EXPORT_SYMBOL(default_grn); | ||
| 4803 | EXPORT_SYMBOL(default_blu); | ||
| 4804 | EXPORT_SYMBOL(update_region); | ||
| 4805 | EXPORT_SYMBOL(redraw_screen); | ||
| 4806 | EXPORT_SYMBOL(vc_resize); | ||
| 4807 | EXPORT_SYMBOL(fg_console); | ||
| 4808 | EXPORT_SYMBOL(console_blank_hook); | ||
| 4809 | EXPORT_SYMBOL(console_blanked); | ||
| 4810 | EXPORT_SYMBOL(vc_cons); | ||
| 4811 | EXPORT_SYMBOL(global_cursor_default); | ||
| 4812 | #ifndef VT_SINGLE_DRIVER | ||
| 4813 | EXPORT_SYMBOL(give_up_console); | ||
| 4814 | #endif | ||
| @@ -18,16 +18,16 @@ struct plat_serial8250_port { · 17 unmodified lines | |||
| 18 | unsigned long iobase; /* io base address */ | 18 | unsigned long iobase; /* io base address */ |
| 19 | void __iomem *membase; /* ioremap cookie or NULL */ | 19 | void __iomem *membase; /* ioremap cookie or NULL */ |
| 20 | resource_size_t mapbase; /* resource base */ | 20 | resource_size_t mapbase; /* resource base */ |
| 21 | unsigned int uartclk; /* UART clock rate */ | ||
| 21 | unsigned int irq; /* interrupt number */ | 22 | unsigned int irq; /* interrupt number */ |
| 22 | unsigned long irqflags; /* request_irq flags */ | 23 | unsigned long irqflags; /* request_irq flags */ |
| 23 | unsigned int uartclk; /* UART clock rate */ | ||
| 24 | void *private_data; | 24 | void *private_data; |
| 25 | unsigned char regshift; /* register shift */ | 25 | unsigned char regshift; /* register shift */ |
| 26 | unsigned char iotype; /* UPIO_* */ | 26 | unsigned char iotype; /* UPIO_* */ |
| 27 | unsigned char hub6; | 27 | unsigned char hub6; |
| 28 | unsigned char has_sysrq; /* supports magic SysRq */ | 28 | unsigned char has_sysrq; /* supports magic SysRq */ |
| 29 | upf_t flags; /* UPF_* flags */ | ||
| 30 | unsigned int type; /* If UPF_FIXED_TYPE */ | 29 | unsigned int type; /* If UPF_FIXED_TYPE */ |
| 30 | upf_t flags; /* UPF_* flags */ | ||
| 31 | unsigned int (*serial_in)(struct uart_port *, int); | 31 | unsigned int (*serial_in)(struct uart_port *, int); |
| 32 | void (*serial_out)(struct uart_port *, int, int); | 32 | void (*serial_out)(struct uart_port *, int, int); |
| 33 | void (*set_termios)(struct uart_port *, | 33 | void (*set_termios)(struct uart_port *, |
| @@ -151,26 +151,22 @@ void serial8250_unregister_port(int line); · 117 unmodified lines | |||
| 151 | void serial8250_suspend_port(int line); | 151 | void serial8250_suspend_port(int line); |
| 152 | void serial8250_resume_port(int line); | 152 | void serial8250_resume_port(int line); |
| 153 | 153 | ||
| 154 | extern int early_serial_setup(struct uart_port *port); | 154 | int early_serial_setup(struct uart_port *port); |
| 155 | 155 | int early_serial8250_setup(struct earlycon_device *device, const char *options); | |
| 156 | extern int early_serial8250_setup(struct earlycon_device *device, | 156 | |
| 157 | const char *options); | 157 | void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk); |
| 158 | extern void serial8250_update_uartclk(struct uart_port *port, | 158 | void serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, |
| 159 | unsigned int uartclk); | 159 | const struct ktermios *old); |
| 160 | extern void serial8250_do_set_termios(struct uart_port *port, | 160 | void serial8250_do_set_ldisc(struct uart_port *port, struct ktermios *termios); |
| 161 | struct ktermios *termios, const struct ktermios *old); | 161 | unsigned int serial8250_do_get_mctrl(struct uart_port *port); |
| 162 | extern void serial8250_do_set_ldisc(struct uart_port *port, | 162 | int serial8250_do_startup(struct uart_port *port); |
| 163 | struct ktermios *termios); | 163 | void serial8250_do_shutdown(struct uart_port *port); |
| 164 | extern unsigned int serial8250_do_get_mctrl(struct uart_port *port); | 164 | void serial8250_do_pm(struct uart_port *port, unsigned int state, |
| 165 | extern int serial8250_do_startup(struct uart_port *port); | 165 | unsigned int oldstate); |
| 166 | extern void serial8250_do_shutdown(struct uart_port *port); | 166 | void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl); |
| 167 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, | 167 | void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, |
| 168 | unsigned int oldstate); | 168 | unsigned int quot, unsigned int quot_frac); |
| 169 | extern void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl); | 169 | int fsl8250_handle_irq(struct uart_port *port); |
| 170 | extern void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, | ||
| 171 | unsigned int quot, | ||
| 172 | unsigned int quot_frac); | ||
| 173 | extern int fsl8250_handle_irq(struct uart_port *port); | ||
| 174 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir); | 170 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir); |
| 175 | u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr); | 171 | u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr); |
| 176 | void serial8250_read_char(struct uart_8250_port *up, u16 lsr); | 172 | void serial8250_read_char(struct uart_8250_port *up, u16 lsr); |
| @@ -183,9 +179,8 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, · 6 unmodified lines | |||
| 183 | int serial8250_console_setup(struct uart_port *port, char *options, bool probe); | 179 | int serial8250_console_setup(struct uart_port *port, char *options, bool probe); |
| 184 | int serial8250_console_exit(struct uart_port *port); | 180 | int serial8250_console_exit(struct uart_port *port); |
| 185 | 181 | ||
| 186 | extern void serial8250_set_isa_configurator(void (*v) | 182 | void serial8250_set_isa_configurator(void (*v)(int port, struct uart_port *up, |
| 187 | (int port, struct uart_port *up, | 183 | u32 *capabilities)); |
| 188 | u32 *capabilities)); | ||
| 189 | 184 | ||
| 190 | #ifdef CONFIG_SERIAL_8250_RT288X | 185 | #ifdef CONFIG_SERIAL_8250_RT288X |
| 191 | unsigned int au_serial_in(struct uart_port *p, int offset); | 186 | unsigned int au_serial_in(struct uart_port *p, int offset); |
| @@ -553,7 +553,7 @@ struct uart_port { · 552 unmodified lines | |||
| 553 | #define UPSTAT_AUTOXOFF ((__force upstat_t) (1 << 4)) | 553 | #define UPSTAT_AUTOXOFF ((__force upstat_t) (1 << 4)) |
| 554 | #define UPSTAT_SYNC_FIFO ((__force upstat_t) (1 << 5)) | 554 | #define UPSTAT_SYNC_FIFO ((__force upstat_t) (1 << 5)) |
| 555 | 555 | ||
| 556 | int hw_stopped; /* sw-assisted CTS flow state */ | 556 | bool hw_stopped; /* sw-assisted CTS flow state */ |
| 557 | unsigned int mctrl; /* current modem ctrl settings */ | 557 | unsigned int mctrl; /* current modem ctrl settings */ |
| 558 | unsigned int frame_time; /* frame timing in ns */ | 558 | unsigned int frame_time; /* frame timing in ns */ |
| 559 | unsigned int type; /* port type */ | 559 | unsigned int type; /* port type */ |
| @@ -812,9 +812,8 @@ extern const struct earlycon_id __earlycon_table_end[]; · 252 unmodified lines | |||
| 812 | 812 | ||
| 813 | #define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn) | 813 | #define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn) |
| 814 | 814 | ||
| 815 | extern int of_setup_earlycon(const struct earlycon_id *match, | 815 | int of_setup_earlycon(const struct earlycon_id *match, unsigned long node, |
| 816 | unsigned long node, | 816 | const char *options); |
| 817 | const char *options); | ||
| 818 | 817 | ||
| 819 | #ifdef CONFIG_SERIAL_EARLYCON | 818 | #ifdef CONFIG_SERIAL_EARLYCON |
| 820 | extern bool earlycon_acpi_spcr_enable __initdata; | 819 | extern bool earlycon_acpi_spcr_enable __initdata; |
| @@ -897,11 +896,11 @@ static inline bool uart_softcts_mode(struct uart_port *uport) · 76 unmodified lines | |||
| 897 | * The following are helper functions for the low level drivers. | 896 | * The following are helper functions for the low level drivers. |
| 898 | */ | 897 | */ |
| 899 | 898 | ||
| 900 | extern void uart_handle_dcd_change(struct uart_port *uport, bool active); | 899 | void uart_handle_dcd_change(struct uart_port *uport, bool active); |
| 901 | extern void uart_handle_cts_change(struct uart_port *uport, bool active); | 900 | void uart_handle_cts_change(struct uart_port *uport, bool active); |
| 902 | 901 | ||
| 903 | extern void uart_insert_char(struct uart_port *port, unsigned int status, | 902 | void uart_insert_char(struct uart_port *port, unsigned int status, |
| 904 | unsigned int overrun, unsigned int ch, unsigned int flag); | 903 | unsigned int overrun, unsigned int ch, unsigned int flag); |
| 905 | 904 | ||
| 906 | void uart_xchar_out(struct uart_port *uport, int offset); | 905 | void uart_xchar_out(struct uart_port *uport, int offset); |
| 907 | 906 | ||
| @@ -227,7 +227,7 @@ struct tty_struct { · 226 unmodified lines | |||
| 227 | unsigned long unused[0]; | 227 | unsigned long unused[0]; |
| 228 | } __aligned(sizeof(unsigned long)) ctrl; | 228 | } __aligned(sizeof(unsigned long)) ctrl; |
| 229 | 229 | ||
| 230 | int hw_stopped; | 230 | bool hw_stopped; |
| 231 | unsigned int receive_room; | 231 | unsigned int receive_room; |
| 232 | int flow_change; | 232 | int flow_change; |
| 233 | 233 | ||
| @@ -43,10 +43,25 @@ struct gsm_config_ext { · 42 unmodified lines | |||
| 43 | __u32 keep_alive; /* Control channel keep-alive in 1/100th of a | 43 | __u32 keep_alive; /* Control channel keep-alive in 1/100th of a |
| 44 | * second (0 to disable) | 44 | * second (0 to disable) |
| 45 | */ | 45 | */ |
| 46 | __u32 reserved[7]; /* For future use, must be initialized to zero */ | 46 | __u32 wait_config; /* Wait for DLCI config before opening virtual link? */ |
| 47 | __u32 reserved[6]; /* For future use, must be initialized to zero */ | ||
| 47 | }; | 48 | }; |
| 48 | 49 | ||
| 49 | #define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext) | 50 | #define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext) |
| 50 | #define GSMIOC_SETCONF_EXT _IOW('G', 6, struct gsm_config_ext) | 51 | #define GSMIOC_SETCONF_EXT _IOW('G', 6, struct gsm_config_ext) |
| 51 | 52 | ||
| 53 | /* Set channel accordingly before calling GSMIOC_GETCONF_DLCI. */ | ||
| 54 | struct gsm_dlci_config { | ||
| 55 | __u32 channel; /* DLCI (0 for the associated DLCI) */ | ||
| 56 | __u32 adaption; /* Convergence layer type */ | ||
| 57 | __u32 mtu; /* Maximum transfer unit */ | ||
| 58 | __u32 priority; /* Priority (0 for default value) */ | ||
| 59 | __u32 i; /* Frame type (1 = UIH, 2 = UI) */ | ||
| 60 | __u32 k; /* Window size (0 for default value) */ | ||
| 61 | __u32 reserved[8]; /* For future use, must be initialized to zero */ | ||
| 62 | }; | ||
| 63 | |||
| 64 | #define GSMIOC_GETCONF_DLCI _IOWR('G', 7, struct gsm_dlci_config) | ||
| 65 | #define GSMIOC_SETCONF_DLCI _IOW('G', 8, struct gsm_dlci_config) | ||
| 66 | |||
| 52 | #endif | 67 | #endif |