Merge 6.3-rc6 into tty-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Apr 2023 06:51:09 +0000 (08:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Apr 2023 06:51:09 +0000 (08:51 +0200)
We need the tty/serial fixes in here for testing.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
60 files changed:
Documentation/admin-guide/serial-console.rst
Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml
Documentation/devicetree/bindings/serial/fsl-lpuart.yaml
Documentation/devicetree/bindings/serial/mediatek,uart.yaml
Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml
Documentation/devicetree/bindings/serial/renesas,em-uart.yaml
Documentation/devicetree/bindings/serial/renesas,hscif.yaml
Documentation/devicetree/bindings/serial/renesas,sci.yaml
Documentation/devicetree/bindings/serial/renesas,scif.yaml
Documentation/devicetree/bindings/serial/renesas,scifa.yaml
Documentation/devicetree/bindings/serial/renesas,scifb.yaml
Documentation/devicetree/bindings/serial/serial.yaml
Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
Documentation/devicetree/bindings/serial/sprd-uart.yaml
Documentation/devicetree/bindings/serial/sunplus,sp7021-uart.yaml
Documentation/driver-api/tty/n_gsm.rst
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun8i-a23-a33.dtsi
arch/arm/boot/dts/sun8i-v3s.dtsi
arch/arm/boot/dts/sunxi-h3-h5.dtsi
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
drivers/bluetooth/hci_ldisc.c
drivers/char/pcmcia/synclink_cs.c
drivers/mmc/core/sdio_uart.c
drivers/tty/Kconfig
drivers/tty/amiserial.c
drivers/tty/mxser.c
drivers/tty/n_gsm.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_bcm7271.c
drivers/tty/serial/8250/8250_em.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/Kconfig
drivers/tty/serial/bcm63xx_uart.c
drivers/tty/serial/cpm_uart/cpm_uart_core.c
drivers/tty/serial/imx.c
drivers/tty/serial/meson_uart.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/sb1250-duart.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sprd_serial.c
drivers/tty/serial/stm32-usart.c
drivers/tty/serial/stm32-usart.h
drivers/tty/serial/sunzilog.c
drivers/tty/serial/ucc_uart.c
drivers/tty/synclink_gt.c
drivers/tty/tty.h
drivers/tty/tty_io.c
drivers/tty/tty_ioctl.c
drivers/tty/tty_ldisc.c
include/linux/serial_8250.h
include/linux/serial_core.h
include/linux/tty.h
include/linux/vt_buffer.h
include/uapi/linux/gsmmux.h

index 58b3283..8c8b94e 100644 (file)
@@ -33,8 +33,11 @@ The format of this option is::
                        9600n8. The maximum baudrate is 115200.
 
 You can specify multiple console= options on the kernel command line.
-Output will appear on all of them. The last device will be used when
-you open ``/dev/console``. So, for example::
+
+The behavior is well defined when each device type is mentioned only once.
+In this case, the output will appear on all requested consoles. And
+the last device will be used when you open ``/dev/console``.
+So, for example::
 
        console=ttyS1,9600 console=tty0
 
@@ -42,7 +45,34 @@ defines that opening ``/dev/console`` will get you the current foreground
 virtual console, and kernel messages will appear on both the VGA
 console and the 2nd serial port (ttyS1 or COM2) at 9600 baud.
 
-Note that you can only define one console per device type (serial, video).
+The behavior is more complicated when the same device type is defined more
+times. In this case, there are the following two rules:
+
+1. The output will appear only on the first device of each defined type.
+
+2. ``/dev/console`` will be associated with the first registered device.
+   Where the registration order depends on how kernel initializes various
+   subsystems.
+
+   This rule is used also when the last console= parameter is not used
+   for other reasons. For example, because of a typo or because
+   the hardware is not available.
+
+The result might be surprising. For example, the following two command
+lines have the same result:
+
+       console=ttyS1,9600 console=tty0 console=tty1
+       console=tty0 console=ttyS1,9600 console=tty1
+
+The kernel messages are printed only on ``tty0`` and ``ttyS1``. And
+``/dev/console`` gets associated with ``tty0``. It is because kernel
+tries to register graphical consoles before serial ones. It does it
+because of the default behavior when no console device is specified,
+see below.
+
+Note that the last ``console=tty1`` parameter still makes a difference.
+The kernel command line is used also by systemd. It would use the last
+defined ``tty1`` as the login console.
 
 If no console device is specified, the first device found capable of
 acting as a system console will be used. At this time, the system
index 3cbdde8..01ec45b 100644 (file)
@@ -2,8 +2,8 @@
 # Copyright 2019 BayLibre, SAS
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/amlogic,meson-uart.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/amlogic,meson-uart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Amlogic Meson SoC UART Serial Interface
 
@@ -34,6 +34,11 @@ properties:
               - amlogic,meson-gx-uart
               - amlogic,meson-s4-uart
           - const: amlogic,meson-ao-uart
+      - description: Always-on power domain UART controller on G12A SoCs
+        items:
+          - const: amlogic,meson-g12a-uart
+          - const: amlogic,meson-gx-uart
+          - const: amlogic,meson-ao-uart
       - description: Everything-Else power domain UART controller
         enum:
           - amlogic,meson6-uart
@@ -41,6 +46,10 @@ properties:
           - amlogic,meson8b-uart
           - amlogic,meson-gx-uart
           - amlogic,meson-s4-uart
+      - description: Everything-Else power domain UART controller on G12A SoCs
+        items:
+          - const: amlogic,meson-g12a-uart
+          - const: amlogic,meson-gx-uart
 
   reg:
     maxItems: 1
index 4cbe76e..4041424 100644 (file)
@@ -49,6 +49,24 @@ properties:
   reg:
     maxItems: 1
 
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: ipg
+      - const: per
+
+  dmas:
+    items:
+      - description: DMA controller phandle and request line for RX
+      - description: DMA controller phandle and request line for TX
+
+  dma-names:
+    items:
+      - const: rx
+      - const: tx
+
   interrupts:
     maxItems: 1
 
@@ -86,12 +104,16 @@ properties:
 required:
   - compatible
   - reg
+  - clocks
+  - clock-names
   - interrupts
 
 unevaluatedProperties: false
 
 examples:
   - |
+    #include <dt-bindings/clock/imx5-clock.h>
+
     aliases {
         serial0 = &uart1;
     };
@@ -100,6 +122,11 @@ examples:
         compatible = "fsl,imx51-uart", "fsl,imx21-uart";
         reg = <0x73fbc000 0x4000>;
         interrupts = <31>;
+        clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+                 <&clks IMX5_CLK_UART1_PER_GATE>;
+        clock-names = "ipg", "per";
+        dmas = <&sdma 18 4 1>, <&sdma 19 4 2>;
+        dma-names = "rx", "tx";
         uart-has-rtscts;
         fsl,dte-mode;
     };
index ab81722..9306240 100644 (file)
@@ -65,6 +65,9 @@ properties:
       - const: rx
       - const: tx
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
index fe098d9..303d02c 100644 (file)
@@ -45,6 +45,7 @@ properties:
               - mediatek,mt8188-uart
               - mediatek,mt8192-uart
               - mediatek,mt8195-uart
+              - mediatek,mt8365-uart
               - mediatek,mt8516-uart
           - const: mediatek,mt6577-uart
 
index 05a6999..dd33794 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/qcom,serial-geni-qcom.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/qcom,serial-geni-qcom.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Qualcomm Geni based QUP UART interface
 
index 12d0fa3..3fc2601 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/renesas,em-uart.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/renesas,em-uart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Renesas EMMA Mobile UART Interface
 
index afedb6e..1c7f127 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/renesas,hscif.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/renesas,hscif.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Renesas High Speed Serial Communication Interface with FIFO (HSCIF)
 
index dc445b3..9f73052 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/renesas,sci.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/renesas,sci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Renesas Serial Communication Interface
 
index 54e4f41..99030fc 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/renesas,scif.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/renesas,scif.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Renesas Serial Communication Interface with FIFO (SCIF)
 
index 4c3b5e7..4995076 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/renesas,scifa.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/renesas,scifa.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Renesas Serial Communications Interface with FIFO A (SCIFA)
 
index 2f7cbbb..810d8a9 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/renesas,scifb.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/renesas,scifb.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Renesas Serial Communications Interface with FIFO B (SCIFB)
 
index c9231e5..ea27756 100644 (file)
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/serial.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/serial.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Serial Interface Generic
 
index 2becdfa..3862411 100644 (file)
@@ -68,12 +68,12 @@ properties:
       - const: apb_pclk
 
   dmas:
-    minItems: 2
+    maxItems: 2
 
   dma-names:
     items:
-      - const: rx
       - const: tx
+      - const: rx
 
   snps,uart-16550-compatible:
     description: reflects the value of UART_16550_COMPATIBLE configuration
index da0e274..28ff77a 100644 (file)
@@ -2,8 +2,8 @@
 # Copyright 2019 Unisoc Inc.
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/sprd-uart.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/sprd-uart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Spreadtrum serial UART
 
index ea1e637..7d0a4bc 100644 (file)
@@ -2,8 +2,8 @@
 # Copyright (C) Sunplus Co., Ltd. 2021
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/serial/sunplus,sp7021-uart.yaml#"
-$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+$id: http://devicetree.org/schemas/serial/sunplus,sp7021-uart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Sunplus SoC SP7021 UART Controller
 
index 9447b8a..120317e 100644 (file)
@@ -29,6 +29,8 @@ Config Initiator
 
 #. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl.
 
+#. Configure DLCs using ``GSMIOC_GETCONF_DLCI``/``GSMIOC_SETCONF_DLCI`` ioctl for non-defaults.
+
 #. Obtain base gsmtty number for the used serial port.
 
    Major parts of the initialization program
@@ -45,6 +47,7 @@ Config Initiator
       int ldisc = N_GSM0710;
       struct gsm_config c;
       struct gsm_config_ext ce;
+      struct gsm_dlci_config dc;
       struct termios configuration;
       uint32_t first;
 
@@ -81,6 +84,13 @@ Config Initiator
       c.mtu = 127;
       /* set the new configuration */
       ioctl(fd, GSMIOC_SETCONF, &c);
+      /* get DLC 1 configuration */
+      dc.channel = 1;
+      ioctl(fd, GSMIOC_GETCONF_DLCI, &dc);
+      /* the first user channel gets a higher priority */
+      dc.priority = 1;
+      /* set the new DLC 1 specific configuration */
+      ioctl(fd, GSMIOC_SETCONF_DLCI, &dc);
       /* get first gsmtty device node */
       ioctl(fd, GSMIOC_GETFIRST, &first);
       printf("first muxed line: /dev/gsmtty%i\n", first);
@@ -120,6 +130,8 @@ Config Requester
 
 #. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl.
 
+#. Configure DLCs using ``GSMIOC_GETCONF_DLCI``/``GSMIOC_SETCONF_DLCI`` ioctl for non-defaults.
+
 #. Obtain base gsmtty number for the used serial port::
 
         #include <stdio.h>
@@ -132,6 +144,7 @@ Config Requester
        int ldisc = N_GSM0710;
        struct gsm_config c;
        struct gsm_config_ext ce;
+       struct gsm_dlci_config dc;
        struct termios configuration;
        uint32_t first;
 
@@ -161,6 +174,13 @@ Config Requester
        c.mtu = 127;
        /* set the new configuration */
        ioctl(fd, GSMIOC_SETCONF, &c);
+       /* get DLC 1 configuration */
+       dc.channel = 1;
+       ioctl(fd, GSMIOC_GETCONF_DLCI, &dc);
+       /* the first user channel gets a higher priority */
+       dc.priority = 1;
+       /* set the new DLC 1 specific configuration */
+       ioctl(fd, GSMIOC_SETCONF_DLCI, &dc);
        /* get first gsmtty device node */
        ioctl(fd, GSMIOC_GETFIRST, &first);
        printf("first muxed line: /dev/gsmtty%i\n", first);
index 6cdadba..5cce491 100644 (file)
                        clocks = <&ccu CLK_APB2_UART0>;
                        resets = <&ccu RST_APB2_UART0>;
                        dmas = <&dma 6>, <&dma 6>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_APB2_UART1>;
                        resets = <&ccu RST_APB2_UART1>;
                        dmas = <&dma 7>, <&dma 7>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_APB2_UART2>;
                        resets = <&ccu RST_APB2_UART2>;
                        dmas = <&dma 8>, <&dma 8>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_APB2_UART3>;
                        resets = <&ccu RST_APB2_UART3>;
                        dmas = <&dma 9>, <&dma 9>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_APB2_UART4>;
                        resets = <&ccu RST_APB2_UART4>;
                        dmas = <&dma 10>, <&dma 10>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_APB2_UART5>;
                        resets = <&ccu RST_APB2_UART5>;
                        dmas = <&dma 22>, <&dma 22>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
index f630ab5..4aa9d88 100644 (file)
                        clocks = <&ccu CLK_BUS_UART0>;
                        resets = <&ccu RST_BUS_UART0>;
                        dmas = <&dma 6>, <&dma 6>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART1>;
                        resets = <&ccu RST_BUS_UART1>;
                        dmas = <&dma 7>, <&dma 7>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART2>;
                        resets = <&ccu RST_BUS_UART2>;
                        dmas = <&dma 8>, <&dma 8>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART3>;
                        resets = <&ccu RST_BUS_UART3>;
                        dmas = <&dma 9>, <&dma 9>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART4>;
                        resets = <&ccu RST_BUS_UART4>;
                        dmas = <&dma 10>, <&dma 10>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
index db194c6..b001251 100644 (file)
                        reg-io-width = <4>;
                        clocks = <&ccu CLK_BUS_UART0>;
                        dmas = <&dma 6>, <&dma 6>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        resets = <&ccu RST_BUS_UART0>;
                        status = "disabled";
                };
                        reg-io-width = <4>;
                        clocks = <&ccu CLK_BUS_UART1>;
                        dmas = <&dma 7>, <&dma 7>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        resets = <&ccu RST_BUS_UART1>;
                        status = "disabled";
                };
                        reg-io-width = <4>;
                        clocks = <&ccu CLK_BUS_UART2>;
                        dmas = <&dma 8>, <&dma 8>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        resets = <&ccu RST_BUS_UART2>;
                        pinctrl-0 = <&uart2_pins>;
                        pinctrl-names = "default";
index 686193b..ade1cd5 100644 (file)
                        clocks = <&ccu CLK_BUS_UART0>;
                        resets = <&ccu RST_BUS_UART0>;
                        dmas = <&dma 6>, <&dma 6>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART1>;
                        resets = <&ccu RST_BUS_UART1>;
                        dmas = <&dma 7>, <&dma 7>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART2>;
                        resets = <&ccu RST_BUS_UART2>;
                        dmas = <&dma 8>, <&dma 8>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART3>;
                        resets = <&ccu RST_BUS_UART3>;
                        dmas = <&dma 9>, <&dma 9>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
index 123a56f..904bcd4 100644 (file)
                        };
 
                        uart_AO: serial@3000 {
-                               compatible = "amlogic,meson-gx-uart",
+                               compatible = "amlogic,meson-g12a-uart",
+                                            "amlogic,meson-gx-uart",
                                             "amlogic,meson-ao-uart";
                                reg = <0x0 0x3000 0x0 0x18>;
                                interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
                        };
 
                        uart_AO_B: serial@4000 {
-                               compatible = "amlogic,meson-gx-uart",
+                               compatible = "amlogic,meson-g12a-uart",
+                                            "amlogic,meson-gx-uart",
                                             "amlogic,meson-ao-uart";
                                reg = <0x0 0x4000 0x0 0x18>;
                                interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
                        };
 
                        uart_C: serial@22000 {
-                               compatible = "amlogic,meson-gx-uart";
+                               compatible = "amlogic,meson-g12a-uart",
+                                            "amlogic,meson-gx-uart";
                                reg = <0x0 0x22000 0x0 0x18>;
                                interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>;
                        };
 
                        uart_B: serial@23000 {
-                               compatible = "amlogic,meson-gx-uart";
+                               compatible = "amlogic,meson-g12a-uart",
+                                            "amlogic,meson-gx-uart";
                                reg = <0x0 0x23000 0x0 0x18>;
                                interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
                        };
 
                        uart_A: serial@24000 {
-                               compatible = "amlogic,meson-gx-uart";
+                               compatible = "amlogic,meson-g12a-uart",
+                                            "amlogic,meson-gx-uart";
                                reg = <0x0 0x24000 0x0 0x18>;
                                interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
index 6fadcee..3ab69c3 100644 (file)
                        clocks = <&ccu CLK_BUS_UART0>;
                        resets = <&ccu RST_BUS_UART0>;
                        dmas = <&dma 14>, <&dma 14>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART1>;
                        resets = <&ccu RST_BUS_UART1>;
                        dmas = <&dma 15>, <&dma 15>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART2>;
                        resets = <&ccu RST_BUS_UART2>;
                        dmas = <&dma 16>, <&dma 16>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART3>;
                        resets = <&ccu RST_BUS_UART3>;
                        dmas = <&dma 17>, <&dma 17>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART4>;
                        resets = <&ccu RST_BUS_UART4>;
                        dmas = <&dma 18>, <&dma 18>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
                        clocks = <&ccu CLK_BUS_UART5>;
                        resets = <&ccu RST_BUS_UART5>;
                        dmas = <&dma 19>, <&dma 19>;
-                       dma-names = "rx", "tx";
+                       dma-names = "tx", "rx";
                        status = "disabled";
                };
 
index 865112e..efdda2c 100644 (file)
@@ -323,9 +323,9 @@ void hci_uart_set_flow_control(struct hci_uart *hu, bool enable)
                /* Disable hardware flow control */
                ktermios = tty->termios;
                ktermios.c_cflag &= ~CRTSCTS;
-               status = tty_set_termios(tty, &ktermios);
+               tty_set_termios(tty, &ktermios);
                BT_DBG("Disabling hardware flow control: %s",
-                      status ? "failed" : "success");
+                      (tty->termios.c_cflag & CRTSCTS) ? "failed" : "success");
 
                /* Clear RTS to prevent the device from sending */
                /* Most UARTs need OUT2 to enable interrupts */
@@ -357,9 +357,9 @@ void hci_uart_set_flow_control(struct hci_uart *hu, bool enable)
                /* Re-enable hardware flow control */
                ktermios = tty->termios;
                ktermios.c_cflag |= CRTSCTS;
-               status = tty_set_termios(tty, &ktermios);
+               tty_set_termios(tty, &ktermios);
                BT_DBG("Enabling hardware flow control: %s",
-                      status ? "failed" : "success");
+                      !(tty->termios.c_cflag & CRTSCTS) ? "failed" : "success");
        }
 }
 
index 6ddfeb2..97c5bfb 100644 (file)
@@ -1060,7 +1060,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty)
                        if (info->serial_signals & SerialSignal_CTS) {
                                if (debug_level >= DEBUG_LEVEL_ISR)
                                        printk("CTS tx start...");
-                               tty->hw_stopped = 0;
+                               tty->hw_stopped = false;
                                tx_start(info, tty);
                                info->pending_bh |= BH_TRANSMIT;
                                return;
@@ -1069,7 +1069,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty)
                        if (!(info->serial_signals & SerialSignal_CTS)) {
                                if (debug_level >= DEBUG_LEVEL_ISR)
                                        printk("CTS tx stop...");
-                               tty->hw_stopped = 1;
+                               tty->hw_stopped = true;
                                tx_stop(info);
                        }
                }
@@ -2312,7 +2312,7 @@ static void mgslpc_set_termios(struct tty_struct *tty,
 
        /* Handle turning off CRTSCTS */
        if (old_termios->c_cflag & CRTSCTS && !C_CRTSCTS(tty)) {
-               tty->hw_stopped = 0;
+               tty->hw_stopped = false;
                tx_release(tty);
        }
 }
index 50536fe..aa65975 100644 (file)
@@ -478,13 +478,13 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
                        int cts = (status & UART_MSR_CTS);
                        if (tty->hw_stopped) {
                                if (cts) {
-                                       tty->hw_stopped = 0;
+                                       tty->hw_stopped = false;
                                        sdio_uart_start_tx(port);
                                        tty_wakeup(tty);
                                }
                        } else {
                                if (!cts) {
-                                       tty->hw_stopped = 1;
+                                       tty->hw_stopped = true;
                                        sdio_uart_stop_tx(port);
                                }
                        }
@@ -633,7 +633,7 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
 
        if (C_CRTSCTS(tty))
                if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
-                       tty->hw_stopped = 1;
+                       tty->hw_stopped = true;
 
        clear_bit(TTY_IO_ERROR, &tty->flags);
 
@@ -882,14 +882,14 @@ static void sdio_uart_set_termios(struct tty_struct *tty,
 
        /* Handle turning off CRTSCTS */
        if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
-               tty->hw_stopped = 0;
+               tty->hw_stopped = false;
                sdio_uart_start_tx(port);
        }
 
        /* Handle turning on CRTSCTS */
        if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
                if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) {
-                       tty->hw_stopped = 1;
+                       tty->hw_stopped = true;
                        sdio_uart_stop_tx(port);
                }
        }
index d35fc06..84caac3 100644 (file)
@@ -160,7 +160,7 @@ config LEGACY_TIOCSTI
          a dangerous legacy operation, and can be disabled on most
          systems.
 
-         Say 'Y here only if you have confirmed that your system's
+         Say Y here only if you have confirmed that your system's
          userspace depends on this functionality to continue operating
          normally.
 
index d7515d6..c06ad0a 100644 (file)
@@ -347,7 +347,7 @@ static void check_modem_status(struct serial_state *info)
 #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
                                printk("CTS tx start...");
 #endif
-                               port->tty->hw_stopped = 0;
+                               port->tty->hw_stopped = false;
                                info->IER |= UART_IER_THRI;
                                amiga_custom.intena = IF_SETCLR | IF_TBE;
                                mb();
@@ -362,7 +362,7 @@ static void check_modem_status(struct serial_state *info)
 #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
                                printk("CTS tx stop...");
 #endif
-                               port->tty->hw_stopped = 1;
+                               port->tty->hw_stopped = true;
                                info->IER &= ~UART_IER_THRI;
                                /* disable Tx interrupt and remove any pending interrupts */
                                amiga_custom.intena = IF_TBE;
@@ -1197,7 +1197,7 @@ static void rs_set_termios(struct tty_struct *tty, const struct ktermios *old_te
 
        /* Handle turning off CRTSCTS */
        if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) {
-               tty->hw_stopped = 0;
+               tty->hw_stopped = false;
                rs_start(tty);
        }
 
index ef3116e..10855e6 100644 (file)
@@ -553,7 +553,7 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info,
 
        if (tty->hw_stopped) {
                if (cts) {
-                       tty->hw_stopped = 0;
+                       tty->hw_stopped = false;
 
                        if (!mxser_16550A_or_MUST(info))
                                __mxser_start_tx(info);
@@ -563,7 +563,7 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info,
        } else if (cts)
                return;
 
-       tty->hw_stopped = 1;
+       tty->hw_stopped = true;
        if (!mxser_16550A_or_MUST(info))
                __mxser_stop_tx(info);
 }
@@ -1361,7 +1361,7 @@ static void mxser_set_termios(struct tty_struct *tty,
        spin_unlock_irqrestore(&info->slock, flags);
 
        if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) {
-               tty->hw_stopped = 0;
+               tty->hw_stopped = false;
                mxser_start(tty);
        }
 
index 7aa05eb..b7e1369 100644 (file)
@@ -128,6 +128,7 @@ struct gsm_msg {
 
 enum gsm_dlci_state {
        DLCI_CLOSED,
+       DLCI_WAITING_CONFIG,    /* Waiting for DLCI configuration from user */
        DLCI_CONFIGURE,         /* Sending PN (for adaption > 1) */
        DLCI_OPENING,           /* Sending SABM not seen UA */
        DLCI_OPEN,              /* SABM/UA complete */
@@ -330,6 +331,7 @@ struct gsm_mux {
        unsigned int t3;        /* Power wake-up timer in seconds. */
        int n2;                 /* Retry count */
        u8 k;                   /* Window size */
+       bool wait_config;       /* Wait for configuration by ioctl before DLCI open */
        u32 keep_alive;         /* Control channel keep-alive in 10ms */
 
        /* Statistics (not currently exposed) */
@@ -451,6 +453,7 @@ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
 static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
                                                                u8 ctrl);
 static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
+static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr);
 static void gsmld_write_trigger(struct gsm_mux *gsm);
 static void gsmld_write_task(struct work_struct *work);
 
@@ -2280,6 +2283,7 @@ static void gsm_dlci_begin_open(struct gsm_dlci *dlci)
 
        switch (dlci->state) {
        case DLCI_CLOSED:
+       case DLCI_WAITING_CONFIG:
        case DLCI_CLOSING:
                dlci->retries = gsm->n2;
                if (!need_pn) {
@@ -2311,6 +2315,7 @@ static void gsm_dlci_set_opening(struct gsm_dlci *dlci)
 {
        switch (dlci->state) {
        case DLCI_CLOSED:
+       case DLCI_WAITING_CONFIG:
        case DLCI_CLOSING:
                dlci->state = DLCI_OPENING;
                break;
@@ -2320,6 +2325,24 @@ static void gsm_dlci_set_opening(struct gsm_dlci *dlci)
 }
 
 /**
+ * gsm_dlci_set_wait_config    -       wait for channel configuration
+ * @dlci: DLCI to configure
+ *
+ * Wait for a DLCI configuration from the application.
+ */
+static void gsm_dlci_set_wait_config(struct gsm_dlci *dlci)
+{
+       switch (dlci->state) {
+       case DLCI_CLOSED:
+       case DLCI_CLOSING:
+               dlci->state = DLCI_WAITING_CONFIG;
+               break;
+       default:
+               break;
+       }
+}
+
+/**
  *     gsm_dlci_begin_close    -       start channel open procedure
  *     @dlci: DLCI to open
  *
@@ -2453,6 +2476,128 @@ static void gsm_kick_timer(struct timer_list *t)
                pr_info("%s TX queue stalled\n", __func__);
 }
 
+/**
+ * gsm_dlci_copy_config_values -       copy DLCI configuration
+ * @dlci: source DLCI
+ * @dc: configuration structure to fill
+ */
+static void gsm_dlci_copy_config_values(struct gsm_dlci *dlci, struct gsm_dlci_config *dc)
+{
+       memset(dc, 0, sizeof(*dc));
+       dc->channel = (u32)dlci->addr;
+       dc->adaption = (u32)dlci->adaption;
+       dc->mtu = (u32)dlci->mtu;
+       dc->priority = (u32)dlci->prio;
+       if (dlci->ftype == UIH)
+               dc->i = 1;
+       else
+               dc->i = 2;
+       dc->k = (u32)dlci->k;
+}
+
+/**
+ * gsm_dlci_config     -       configure DLCI from configuration
+ * @dlci: DLCI to configure
+ * @dc: DLCI configuration
+ * @open: open DLCI after configuration?
+ */
+static int gsm_dlci_config(struct gsm_dlci *dlci, struct gsm_dlci_config *dc, int open)
+{
+       struct gsm_mux *gsm;
+       bool need_restart = false;
+       bool need_open = false;
+       unsigned int i;
+
+       /*
+        * Check that userspace doesn't put stuff in here to prevent breakages
+        * in the future.
+        */
+       for (i = 0; i < ARRAY_SIZE(dc->reserved); i++)
+               if (dc->reserved[i])
+                       return -EINVAL;
+
+       if (!dlci)
+               return -EINVAL;
+       gsm = dlci->gsm;
+
+       /* Stuff we don't support yet - I frame transport */
+       if (dc->adaption != 1 && dc->adaption != 2)
+               return -EOPNOTSUPP;
+       if (dc->mtu > MAX_MTU || dc->mtu < MIN_MTU || dc->mtu > gsm->mru)
+               return -EINVAL;
+       if (dc->priority >= 64)
+               return -EINVAL;
+       if (dc->i == 0 || dc->i > 2)  /* UIH and UI only */
+               return -EINVAL;
+       if (dc->k > 7)
+               return -EINVAL;
+
+       /*
+        * See what is needed for reconfiguration
+        */
+       /* Framing fields */
+       if (dc->adaption != dlci->adaption)
+               need_restart = true;
+       if (dc->mtu != dlci->mtu)
+               need_restart = true;
+       if (dc->i != dlci->ftype)
+               need_restart = true;
+       /* Requires care */
+       if (dc->priority != dlci->prio)
+               need_restart = true;
+
+       if ((open && gsm->wait_config) || need_restart)
+               need_open = true;
+       if (dlci->state == DLCI_WAITING_CONFIG) {
+               need_restart = false;
+               need_open = true;
+       }
+
+       /*
+        * Close down what is needed, restart and initiate the new
+        * configuration.
+        */
+       if (need_restart) {
+               gsm_dlci_begin_close(dlci);
+               wait_event_interruptible(gsm->event, dlci->state == DLCI_CLOSED);
+               if (signal_pending(current))
+                       return -EINTR;
+       }
+       /*
+        * Setup the new configuration values
+        */
+       dlci->adaption = (int)dc->adaption;
+
+       if (dc->mtu)
+               dlci->mtu = (unsigned int)dc->mtu;
+       else
+               dlci->mtu = gsm->mtu;
+
+       if (dc->priority)
+               dlci->prio = (u8)dc->priority;
+       else
+               dlci->prio = roundup(dlci->addr + 1, 8) - 1;
+
+       if (dc->i == 1)
+               dlci->ftype = UIH;
+       else if (dc->i == 2)
+               dlci->ftype = UI;
+
+       if (dc->k)
+               dlci->k = (u8)dc->k;
+       else
+               dlci->k = gsm->k;
+
+       if (need_open) {
+               if (gsm->initiator)
+                       gsm_dlci_begin_open(dlci);
+               else
+                       gsm_dlci_set_opening(dlci);
+       }
+
+       return 0;
+}
+
 /*
  *     Allocate/Free DLCI channels
  */
@@ -3078,6 +3223,7 @@ static struct gsm_mux *gsm_alloc_mux(void)
        gsm->mru = 64;  /* Default to encoding 1 so these should be 64 */
        gsm->mtu = 64;
        gsm->dead = true;       /* Avoid early tty opens */
+       gsm->wait_config = false; /* Disabled */
        gsm->keep_alive = 0;    /* Disabled */
 
        /* Store the instance to the mux array or abort if no space is
@@ -3130,8 +3276,8 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
        int need_close = 0;
        int need_restart = 0;
 
-       /* Stuff we don't support yet - UI or I frame transport, windowing */
-       if ((c->adaption != 1 && c->adaption != 2) || c->k)
+       /* Stuff we don't support yet - UI or I frame transport */
+       if (c->adaption != 1 && c->adaption != 2)
                return -EOPNOTSUPP;
        /* Check the MRU/MTU range looks sane */
        if (c->mru < MIN_MTU || c->mtu < MIN_MTU)
@@ -3218,6 +3364,7 @@ static void gsm_copy_config_ext_values(struct gsm_mux *gsm,
                                       struct gsm_config_ext *ce)
 {
        memset(ce, 0, sizeof(*ce));
+       ce->wait_config = gsm->wait_config ? 1 : 0;
        ce->keep_alive = gsm->keep_alive;
 }
 
@@ -3233,7 +3380,12 @@ static int gsm_config_ext(struct gsm_mux *gsm, struct gsm_config_ext *ce)
                if (ce->reserved[i])
                        return -EINVAL;
 
+       /*
+        * Setup the new configuration values
+        */
+       gsm->wait_config = ce->wait_config ? true : false;
        gsm->keep_alive = ce->keep_alive;
+
        return 0;
 }
 
@@ -3436,6 +3588,14 @@ static int gsmld_open(struct tty_struct *tty)
        gsm->encoding = GSM_ADV_OPT;
        gsmld_attach_gsm(tty, gsm);
 
+       /* The mux will not be activated yet, we wait for correct
+        * configuration first.
+        */
+       if (gsm->encoding == GSM_BASIC_OPT)
+               gsm->receive = gsm0_receive;
+       else
+               gsm->receive = gsm1_receive;
+
        return 0;
 }
 
@@ -3556,7 +3716,9 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd,
 {
        struct gsm_config c;
        struct gsm_config_ext ce;
+       struct gsm_dlci_config dc;
        struct gsm_mux *gsm = tty->disc_data;
+       struct gsm_dlci *dlci;
        unsigned int base;
 
        switch (cmd) {
@@ -3581,6 +3743,33 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd,
                if (copy_from_user(&ce, (void __user *)arg, sizeof(ce)))
                        return -EFAULT;
                return gsm_config_ext(gsm, &ce);
+       case GSMIOC_GETCONF_DLCI:
+               if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
+                       return -EFAULT;
+               if (dc.channel == 0 || dc.channel >= NUM_DLCI)
+                       return -EINVAL;
+               dlci = gsm->dlci[dc.channel];
+               if (!dlci) {
+                       dlci = gsm_dlci_alloc(gsm, dc.channel);
+                       if (!dlci)
+                               return -ENOMEM;
+               }
+               gsm_dlci_copy_config_values(dlci, &dc);
+               if (copy_to_user((void __user *)arg, &dc, sizeof(dc)))
+                       return -EFAULT;
+               return 0;
+       case GSMIOC_SETCONF_DLCI:
+               if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
+                       return -EFAULT;
+               if (dc.channel == 0 || dc.channel >= NUM_DLCI)
+                       return -EINVAL;
+               dlci = gsm->dlci[dc.channel];
+               if (!dlci) {
+                       dlci = gsm_dlci_alloc(gsm, dc.channel);
+                       if (!dlci)
+                               return -ENOMEM;
+               }
+               return gsm_dlci_config(dlci, &dc, 0);
        default:
                return n_tty_ioctl_helper(tty, cmd, arg);
        }
@@ -4008,7 +4197,6 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
 {
        struct gsm_dlci *dlci = tty->driver_data;
        struct tty_port *port = &dlci->port;
-       struct gsm_mux *gsm = dlci->gsm;
 
        port->count++;
        tty_port_tty_set(port, tty);
@@ -4018,10 +4206,15 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
           a DM straight back. This is ok as that will have caused a hangup */
        tty_port_set_initialized(port, true);
        /* Start sending off SABM messages */
-       if (gsm->initiator)
-               gsm_dlci_begin_open(dlci);
-       else
-               gsm_dlci_set_opening(dlci);
+       if (!dlci->gsm->wait_config) {
+               /* Start sending off SABM messages */
+               if (dlci->gsm->initiator)
+                       gsm_dlci_begin_open(dlci);
+               else
+                       gsm_dlci_set_opening(dlci);
+       } else {
+               gsm_dlci_set_wait_config(dlci);
+       }
        /* And wait for virtual carrier */
        return tty_port_block_til_ready(port, tty, filp);
 }
@@ -4142,6 +4335,7 @@ static int gsmtty_ioctl(struct tty_struct *tty,
 {
        struct gsm_dlci *dlci = tty->driver_data;
        struct gsm_netconfig nc;
+       struct gsm_dlci_config dc;
        int index;
 
        if (dlci->state == DLCI_CLOSED)
@@ -4165,6 +4359,23 @@ static int gsmtty_ioctl(struct tty_struct *tty,
                gsm_destroy_network(dlci);
                mutex_unlock(&dlci->mutex);
                return 0;
+       case GSMIOC_GETCONF_DLCI:
+               if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
+                       return -EFAULT;
+               if (dc.channel != dlci->addr)
+                       return -EPERM;
+               gsm_dlci_copy_config_values(dlci, &dc);
+               if (copy_to_user((void __user *)arg, &dc, sizeof(dc)))
+                       return -EFAULT;
+               return 0;
+       case GSMIOC_SETCONF_DLCI:
+               if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
+                       return -EFAULT;
+               if (dc.channel >= NUM_DLCI)
+                       return -EINVAL;
+               if (dc.channel != 0 && dc.channel != dlci->addr)
+                       return -EPERM;
+               return gsm_dlci_config(dlci, &dc, 1);
        case TIOCMIWAIT:
                return gsm_wait_modem_change(dlci, (u32)arg);
        default:
index c8f56c9..1c9e5d2 100644 (file)
  *             EAGAIN
  */
 
-#include <linux/types.h>
-#include <linux/major.h>
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/ctype.h>
 #include <linux/errno.h>
-#include <linux/signal.h>
+#include <linux/export.h>
 #include <linux/fcntl.h>
+#include <linux/file.h>
+#include <linux/jiffies.h>
+#include <linux/math.h>
+#include <linux/poll.h>
+#include <linux/ratelimit.h>
 #include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/timer.h>
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/string.h>
+#include <linux/signal.h>
 #include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/bitops.h>
-#include <linux/audit.h>
-#include <linux/file.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/types.h>
 #include <linux/uaccess.h>
-#include <linux/module.h>
-#include <linux/ratelimit.h>
 #include <linux/vmalloc.h>
+
 #include "tty.h"
 
 /*
@@ -625,7 +624,7 @@ static size_t __process_echoes(struct tty_struct *tty)
                c = echo_buf(ldata, tail);
                if (c == ECHO_OP_START) {
                        unsigned char op;
-                       int no_space_left = 0;
+                       bool space_left = true;
 
                        /*
                         * Since add_echo_byte() is called without holding
@@ -664,7 +663,7 @@ static size_t __process_echoes(struct tty_struct *tty)
                                num_bs = 8 - (num_chars & 7);
 
                                if (num_bs > space) {
-                                       no_space_left = 1;
+                                       space_left = false;
                                        break;
                                }
                                space -= num_bs;
@@ -690,7 +689,7 @@ static size_t __process_echoes(struct tty_struct *tty)
                        case ECHO_OP_START:
                                /* This is an escaped echo op start code */
                                if (!space) {
-                                       no_space_left = 1;
+                                       space_left = false;
                                        break;
                                }
                                tty_put_char(tty, ECHO_OP_START);
@@ -710,7 +709,7 @@ static size_t __process_echoes(struct tty_struct *tty)
                                 *
                                 */
                                if (space < 2) {
-                                       no_space_left = 1;
+                                       space_left = false;
                                        break;
                                }
                                tty_put_char(tty, '^');
@@ -720,7 +719,7 @@ static size_t __process_echoes(struct tty_struct *tty)
                                tail += 2;
                        }
 
-                       if (no_space_left)
+                       if (!space_left)
                                break;
                } else {
                        if (O_OPOST(tty)) {
@@ -1177,7 +1176,7 @@ static void n_tty_receive_overrun(struct tty_struct *tty)
 
        ldata->num_overrun++;
        if (time_after(jiffies, ldata->overrun_time + HZ) ||
-                       time_after(ldata->overrun_time, jiffies)) {
+           time_after(ldata->overrun_time, jiffies)) {
                tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun);
                ldata->overrun_time = jiffies;
                ldata->num_overrun = 0;
@@ -1691,7 +1690,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
 
                room = N_TTY_BUF_SIZE - (ldata->read_head - tail);
                if (I_PARMRK(tty))
-                       room = (room + 2) / 3;
+                       room = DIV_ROUND_UP(room, 3);
                room--;
                if (room <= 0) {
                        overflow = ldata->icanon && ldata->canon_head == tail;
index 287153d..1e8fe44 100644 (file)
@@ -365,6 +365,13 @@ static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p)
        if (dma->prepare_rx_dma)
                dma->prepare_rx_dma(p);
 }
+
+static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
+{
+       struct uart_8250_dma *dma = p->dma;
+
+       return dma && dma->tx_running;
+}
 #else
 static inline int serial8250_tx_dma(struct uart_8250_port *p)
 {
@@ -380,6 +387,11 @@ static inline int serial8250_request_dma(struct uart_8250_port *p)
        return -1;
 }
 static inline void serial8250_release_dma(struct uart_8250_port *p) { }
+
+static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
+{
+       return false;
+}
 #endif
 
 static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
index ed5a947..f801b1f 100644 (file)
@@ -1014,14 +1014,16 @@ static int brcmuart_probe(struct platform_device *pdev)
        /* See if a Baud clock has been specified */
        baud_mux_clk = of_clk_get_by_name(np, "sw_baud");
        if (IS_ERR(baud_mux_clk)) {
-               if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
+               if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto release_dma;
+               }
                dev_dbg(dev, "BAUD MUX clock not specified\n");
        } else {
                dev_dbg(dev, "BAUD MUX clock found\n");
                ret = clk_prepare_enable(baud_mux_clk);
                if (ret)
-                       return ret;
+                       goto release_dma;
                priv->baud_mux_clk = baud_mux_clk;
                init_real_clk_rates(dev, priv);
                clk_rate = priv->default_mux_rate;
@@ -1029,7 +1031,8 @@ static int brcmuart_probe(struct platform_device *pdev)
 
        if (clk_rate == 0) {
                dev_err(dev, "clock-frequency or clk not defined\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto release_dma;
        }
 
        dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not ");
@@ -1116,7 +1119,9 @@ err1:
        serial8250_unregister_port(priv->line);
 err:
        brcmuart_free_bufs(dev, priv);
-       brcmuart_arbitration(priv, 0);
+release_dma:
+       if (priv->dma_enabled)
+               brcmuart_arbitration(priv, 0);
        return ret;
 }
 
@@ -1128,7 +1133,8 @@ static int brcmuart_remove(struct platform_device *pdev)
        hrtimer_cancel(&priv->hrt);
        serial8250_unregister_port(priv->line);
        brcmuart_free_bufs(&pdev->dev, priv);
-       brcmuart_arbitration(priv, 0);
+       if (priv->dma_enabled)
+               brcmuart_arbitration(priv, 0);
        return 0;
 }
 
index d94c381..25a9ecf 100644 (file)
 #include <linux/serial_reg.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
-#include <linux/slab.h>
 
 #include "8250.h"
 
 #define UART_DLL_EM 9
 #define UART_DLM_EM 10
+#define UART_HCR0_EM 11
+
+/*
+ * A high value for UART_FCR_EM avoids overlapping with existing UART_*
+ * register defines. UART_FCR_EM_HW is the real HW register offset.
+ */
+#define UART_FCR_EM 0x10003
+#define UART_FCR_EM_HW 3
+
+#define UART_HCR0_EM_SW_RESET  BIT(7) /* SW Reset */
 
 struct serial8250_em_priv {
-       struct clk *sclk;
        int line;
 };
 
-static void serial8250_em_serial_out(struct uart_port *p, int offset, int value)
+static void serial8250_em_serial_out_helper(struct uart_port *p, int offset,
+                                           int value)
 {
        switch (offset) {
        case UART_TX: /* TX @ 0x00 */
                writeb(value, p->membase);
                break;
-       case UART_FCR: /* FCR @ 0x0c (+1) */
        case UART_LCR: /* LCR @ 0x10 (+1) */
        case UART_MCR: /* MCR @ 0x14 (+1) */
        case UART_SCR: /* SCR @ 0x20 (+1) */
                writel(value, p->membase + ((offset + 1) << 2));
                break;
+       case UART_FCR_EM:
+               writel(value, p->membase + (UART_FCR_EM_HW << 2));
+               break;
        case UART_IER: /* IER @ 0x04 */
                value &= 0x0f; /* only 4 valid bits - not Xscale */
                fallthrough;
        case UART_DLL_EM: /* DLL @ 0x24 (+9) */
        case UART_DLM_EM: /* DLM @ 0x28 (+9) */
+       case UART_HCR0_EM: /* HCR0 @ 0x2c */
                writel(value, p->membase + (offset << 2));
+               break;
        }
 }
 
@@ -51,20 +64,81 @@ static unsigned int serial8250_em_serial_in(struct uart_port *p, int offset)
        switch (offset) {
        case UART_RX: /* RX @ 0x00 */
                return readb(p->membase);
+       case UART_LCR: /* LCR @ 0x10 (+1) */
        case UART_MCR: /* MCR @ 0x14 (+1) */
        case UART_LSR: /* LSR @ 0x18 (+1) */
        case UART_MSR: /* MSR @ 0x1c (+1) */
        case UART_SCR: /* SCR @ 0x20 (+1) */
                return readl(p->membase + ((offset + 1) << 2));
+       case UART_FCR_EM:
+               return readl(p->membase + (UART_FCR_EM_HW << 2));
        case UART_IER: /* IER @ 0x04 */
        case UART_IIR: /* IIR @ 0x08 */
        case UART_DLL_EM: /* DLL @ 0x24 (+9) */
        case UART_DLM_EM: /* DLM @ 0x28 (+9) */
+       case UART_HCR0_EM: /* HCR0 @ 0x2c */
                return readl(p->membase + (offset << 2));
        }
        return 0;
 }
 
+static void serial8250_em_reg_update(struct uart_port *p, int off, int value)
+{
+       unsigned int ier, fcr, lcr, mcr, hcr0;
+
+       ier = serial8250_em_serial_in(p, UART_IER);
+       fcr = serial8250_em_serial_in(p, UART_FCR_EM);
+       lcr = serial8250_em_serial_in(p, UART_LCR);
+       mcr = serial8250_em_serial_in(p, UART_MCR);
+       hcr0 = serial8250_em_serial_in(p, UART_HCR0_EM);
+
+       serial8250_em_serial_out_helper(p, UART_FCR_EM, fcr |
+                                                       UART_FCR_CLEAR_RCVR |
+                                                       UART_FCR_CLEAR_XMIT);
+       serial8250_em_serial_out_helper(p, UART_HCR0_EM, hcr0 |
+                                                        UART_HCR0_EM_SW_RESET);
+       serial8250_em_serial_out_helper(p, UART_HCR0_EM, hcr0 &
+                                                        ~UART_HCR0_EM_SW_RESET);
+
+       switch (off) {
+       case UART_FCR_EM:
+               fcr = value;
+               break;
+       case UART_LCR:
+               lcr = value;
+               break;
+       case UART_MCR:
+               mcr = value;
+               break;
+       }
+
+       serial8250_em_serial_out_helper(p, UART_IER, ier);
+       serial8250_em_serial_out_helper(p, UART_FCR_EM, fcr);
+       serial8250_em_serial_out_helper(p, UART_MCR, mcr);
+       serial8250_em_serial_out_helper(p, UART_LCR, lcr);
+       serial8250_em_serial_out_helper(p, UART_HCR0_EM, hcr0);
+}
+
+static void serial8250_em_serial_out(struct uart_port *p, int offset, int value)
+{
+       switch (offset) {
+       case UART_TX:
+       case UART_SCR:
+       case UART_IER:
+       case UART_DLL_EM:
+       case UART_DLM_EM:
+               serial8250_em_serial_out_helper(p, offset, value);
+               break;
+       case UART_FCR:
+               serial8250_em_reg_update(p, UART_FCR_EM, value);
+               break;
+       case UART_LCR:
+       case UART_MCR:
+               serial8250_em_reg_update(p, offset, value);
+               break;
+       }
+}
+
 static int serial8250_em_serial_dl_read(struct uart_8250_port *up)
 {
        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)
 static int serial8250_em_probe(struct platform_device *pdev)
 {
        struct serial8250_em_priv *priv;
+       struct device *dev = &pdev->dev;
        struct uart_8250_port up;
        struct resource *regs;
+       struct clk *sclk;
        int irq, ret;
 
        irq = platform_get_irq(pdev, 0);
@@ -88,31 +164,26 @@ static int serial8250_em_probe(struct platform_device *pdev)
                return irq;
 
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!regs) {
-               dev_err(&pdev->dev, "missing registers\n");
-               return -EINVAL;
-       }
+       if (!regs)
+               return dev_err_probe(dev, -EINVAL, "missing registers\n");
 
-       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
-       priv->sclk = devm_clk_get(&pdev->dev, "sclk");
-       if (IS_ERR(priv->sclk)) {
-               dev_err(&pdev->dev, "unable to get clock\n");
-               return PTR_ERR(priv->sclk);
-       }
+       sclk = devm_clk_get_enabled(dev, "sclk");
+       if (IS_ERR(sclk))
+               return dev_err_probe(dev, PTR_ERR(sclk), "unable to get clock\n");
 
        memset(&up, 0, sizeof(up));
        up.port.mapbase = regs->start;
        up.port.irq = irq;
        up.port.type = PORT_16750;
        up.port.flags = UPF_FIXED_PORT | UPF_IOREMAP | UPF_FIXED_TYPE;
-       up.port.dev = &pdev->dev;
+       up.port.dev = dev;
        up.port.private_data = priv;
 
-       clk_prepare_enable(priv->sclk);
-       up.port.uartclk = clk_get_rate(priv->sclk);
+       up.port.uartclk = clk_get_rate(sclk);
 
        up.port.iotype = UPIO_MEM32;
        up.port.serial_in = serial8250_em_serial_in;
@@ -121,11 +192,8 @@ static int serial8250_em_probe(struct platform_device *pdev)
        up.dl_write = serial8250_em_serial_dl_write;
 
        ret = serial8250_register_8250_port(&up);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "unable to register 8250 port\n");
-               clk_disable_unprepare(priv->sclk);
-               return ret;
-       }
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "unable to register 8250 port\n");
 
        priv->line = ret;
        platform_set_drvdata(pdev, priv);
@@ -137,7 +205,6 @@ static int serial8250_em_remove(struct platform_device *pdev)
        struct serial8250_em_priv *priv = platform_get_drvdata(pdev);
 
        serial8250_unregister_port(priv->line);
-       clk_disable_unprepare(priv->sclk);
        return 0;
 }
 
index 3ba9c8b..dfbc501 100644 (file)
@@ -2016,18 +2016,19 @@ static int serial8250_tx_threshold_handle_irq(struct uart_port *port)
 static unsigned int serial8250_tx_empty(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
+       unsigned int result = 0;
        unsigned long flags;
-       u16 lsr;
 
        serial8250_rpm_get(up);
 
        spin_lock_irqsave(&port->lock, flags);
-       lsr = serial_lsr_in(up);
+       if (!serial8250_tx_dma_running(up) && uart_lsr_tx_empty(serial_lsr_in(up)))
+               result = TIOCSER_TEMT;
        spin_unlock_irqrestore(&port->lock, flags);
 
        serial8250_rpm_put(up);
 
-       return uart_lsr_tx_empty(lsr) ? TIOCSER_TEMT : 0;
+       return result;
 }
 
 unsigned int serial8250_do_get_mctrl(struct uart_port *port)
index 0072892..39a0078 100644 (file)
@@ -248,13 +248,6 @@ config SERIAL_SAMSUNG
 
          Choose Y/M here only if you build for such SoC.
 
-config SERIAL_SAMSUNG_UARTS_4
-       bool
-       depends on SERIAL_SAMSUNG
-       default y
-       help
-         Internal node for the common case of 4 Samsung compatible UARTs
-
 config SERIAL_SAMSUNG_UARTS
        int
        depends on SERIAL_SAMSUNG
index 62bc724..55e82d0 100644 (file)
@@ -596,6 +596,40 @@ static int bcm_uart_verify_port(struct uart_port *port,
        return 0;
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+/*
+ * return true when outstanding tx equals fifo size
+ */
+static bool bcm_uart_tx_full(struct uart_port *port)
+{
+       unsigned int val;
+
+       val = bcm_uart_readl(port, UART_MCTL_REG);
+       val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT;
+       return !(port->fifosize - val);
+}
+
+static int bcm_uart_poll_get_char(struct uart_port *port)
+{
+       unsigned int iestat;
+
+       iestat = bcm_uart_readl(port, UART_IR_REG);
+       if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
+               return NO_POLL_CHAR;
+
+       return bcm_uart_readl(port, UART_FIFO_REG);
+}
+
+static void bcm_uart_poll_put_char(struct uart_port *port, unsigned char c)
+{
+       while (bcm_uart_tx_full(port)) {
+               cpu_relax();
+       }
+
+       bcm_uart_writel(port, c, UART_FIFO_REG);
+}
+#endif
+
 /* serial core callbacks */
 static const struct uart_ops bcm_uart_ops = {
        .tx_empty       = bcm_uart_tx_empty,
@@ -614,6 +648,10 @@ static const struct uart_ops bcm_uart_ops = {
        .request_port   = bcm_uart_request_port,
        .config_port    = bcm_uart_config_port,
        .verify_port    = bcm_uart_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char  = bcm_uart_poll_get_char,
+       .poll_put_char  = bcm_uart_poll_put_char,
+#endif
 };
 
 
index 5565f30..349e7da 100644 (file)
@@ -678,15 +678,14 @@ static int cpm_uart_tx_pump(struct uart_port *port)
        /* Pick next descriptor and fill from buffer */
        bdp = pinfo->tx_cur;
 
-       while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) &&
-              xmit->tail != xmit->head) {
+       while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && !uart_circ_empty(xmit)) {
                count = 0;
                p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
                while (count < pinfo->tx_fifosize) {
                        *p++ = xmit->buf[xmit->tail];
                        uart_xmit_advance(port, 1);
                        count++;
-                       if (xmit->head == xmit->tail)
+                       if (uart_circ_empty(xmit))
                                break;
                }
                out_be16(&bdp->cbd_datlen, count);
index 523f296..c5e1756 100644 (file)
@@ -289,20 +289,6 @@ static inline int imx_uart_is_imx1(struct imx_port *sport)
        return sport->devdata->devtype == IMX1_UART;
 }
 
-static inline int imx_uart_is_imx21(struct imx_port *sport)
-{
-       return sport->devdata->devtype == IMX21_UART;
-}
-
-static inline int imx_uart_is_imx53(struct imx_port *sport)
-{
-       return sport->devdata->devtype == IMX53_UART;
-}
-
-static inline int imx_uart_is_imx6q(struct imx_port *sport)
-{
-       return sport->devdata->devtype == IMX6Q_UART;
-}
 /*
  * Save and restore functions for UCR1, UCR2 and UCR3 registers
  */
@@ -1808,9 +1794,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
 
 static const char *imx_uart_type(struct uart_port *port)
 {
-       struct imx_port *sport = (struct imx_port *)port;
-
-       return sport->port.type == PORT_IMX ? "IMX" : NULL;
+       return port->type == PORT_IMX ? "IMX" : NULL;
 }
 
 /*
@@ -1818,10 +1802,8 @@ static const char *imx_uart_type(struct uart_port *port)
  */
 static void imx_uart_config_port(struct uart_port *port, int flags)
 {
-       struct imx_port *sport = (struct imx_port *)port;
-
        if (flags & UART_CONFIG_TYPE)
-               sport->port.type = PORT_IMX;
+               port->type = PORT_IMX;
 }
 
 /*
@@ -1832,20 +1814,19 @@ static void imx_uart_config_port(struct uart_port *port, int flags)
 static int
 imx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
-       struct imx_port *sport = (struct imx_port *)port;
        int ret = 0;
 
        if (ser->type != PORT_UNKNOWN && ser->type != PORT_IMX)
                ret = -EINVAL;
-       if (sport->port.irq != ser->irq)
+       if (port->irq != ser->irq)
                ret = -EINVAL;
        if (ser->io_type != UPIO_MEM)
                ret = -EINVAL;
-       if (sport->port.uartclk / 16 != ser->baud_base)
+       if (port->uartclk / 16 != ser->baud_base)
                ret = -EINVAL;
-       if (sport->port.mapbase != (unsigned long)ser->iomem_base)
+       if (port->mapbase != (unsigned long)ser->iomem_base)
                ret = -EINVAL;
-       if (sport->port.iobase != ser->port)
+       if (port->iobase != ser->port)
                ret = -EINVAL;
        if (ser->hub6 != 0)
                ret = -EINVAL;
@@ -2262,21 +2243,16 @@ static int imx_uart_probe(struct platform_device *pdev)
        }
        sport->port.line = ret;
 
-       if (of_get_property(np, "uart-has-rtscts", NULL) ||
-           of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */)
-               sport->have_rtscts = 1;
+       sport->have_rtscts = of_property_read_bool(np, "uart-has-rtscts") ||
+               of_property_read_bool(np, "fsl,uart-has-rtscts"); /* deprecated */
 
-       if (of_get_property(np, "fsl,dte-mode", NULL))
-               sport->dte_mode = 1;
+       sport->dte_mode = of_property_read_bool(np, "fsl,dte-mode");
 
-       if (of_get_property(np, "rts-gpios", NULL))
-               sport->have_rtsgpio = 1;
+       sport->have_rtsgpio = of_property_present(np, "rts-gpios");
 
-       if (of_get_property(np, "fsl,inverted-tx", NULL))
-               sport->inverted_tx = 1;
+       sport->inverted_tx = of_property_read_bool(np, "fsl,inverted-tx");
 
-       if (of_get_property(np, "fsl,inverted-rx", NULL))
-               sport->inverted_rx = 1;
+       sport->inverted_rx = of_property_read_bool(np, "fsl,inverted-rx");
 
        if (!of_property_read_u32_array(np, "fsl,dma-info", dma_buf_conf, 2)) {
                sport->rx_period_length = dma_buf_conf[0];
index 7411001..2501db5 100644 (file)
@@ -779,7 +779,7 @@ static int meson_uart_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct meson_uart_data s4_uart_data = {
+static struct meson_uart_data meson_g12a_uart_data = {
        .has_xtal_div2 = true,
 };
 
@@ -789,8 +789,12 @@ static const struct of_device_id meson_uart_dt_match[] = {
        { .compatible = "amlogic,meson8b-uart" },
        { .compatible = "amlogic,meson-gx-uart" },
        {
+               .compatible = "amlogic,meson-g12a-uart",
+               .data = (void *)&meson_g12a_uart_data,
+       },
+       {
                .compatible = "amlogic,meson-s4-uart",
-               .data = (void *)&s4_uart_data,
+               .data = (void *)&meson_g12a_uart_data,
        },
        { /* sentinel */ },
 };
index ef6e7bb..a368f42 100644 (file)
@@ -1587,8 +1587,8 @@ static int mxs_auart_probe(struct platform_device *pdev)
        }
        s->port.line = ret;
 
-       if (of_get_property(np, "uart-has-rtscts", NULL) ||
-           of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */)
+       if (of_property_read_bool(np, "uart-has-rtscts") ||
+           of_property_read_bool(np, "fsl,uart-has-rtscts") /* deprecated */)
                set_bit(MXS_AUART_RTSCTS, &s->flags);
 
        if (s->port.line >= ARRAY_SIZE(auart_port)) {
index 28fbc92..1881dd5 100644 (file)
@@ -1535,6 +1535,7 @@ static const struct uart_ops qcom_geni_console_pops = {
 #ifdef CONFIG_CONSOLE_POLL
        .poll_get_char  = qcom_geni_serial_get_char,
        .poll_put_char  = qcom_geni_serial_poll_put_char,
+       .poll_init = qcom_geni_serial_port_setup,
 #endif
        .pm = qcom_geni_serial_pm,
 };
index de56f38..b6de0dc 100644 (file)
@@ -41,7 +41,7 @@
 #include <asm/sibyte/swarm.h>
 
 
-#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+#if defined(CONFIG_SIBYTE_BCM1x80)
 #include <asm/sibyte/bcm1480_regs.h>
 #include <asm/sibyte/bcm1480_int.h>
 
index 2bd32c8..afafbb7 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -48,9 +49,6 @@ static struct lock_class_key port_lock_key;
  */
 #define RS485_MAX_RTS_DELAY    100 /* msecs */
 
-static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
-                             const struct ktermios *old_termios);
-static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
 static void uart_change_pm(struct uart_state *state,
                           enum uart_pm_state pm_state);
 
@@ -177,6 +175,51 @@ static void uart_port_dtr_rts(struct uart_port *uport, bool active)
                uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
 }
 
+/* Caller holds port mutex */
+static void uart_change_line_settings(struct tty_struct *tty, struct uart_state *state,
+                                     const struct ktermios *old_termios)
+{
+       struct uart_port *uport = uart_port_check(state);
+       struct ktermios *termios;
+       bool old_hw_stopped;
+
+       /*
+        * If we have no tty, termios, or the port does not exist,
+        * then we can't set the parameters for this port.
+        */
+       if (!tty || uport->type == PORT_UNKNOWN)
+               return;
+
+       termios = &tty->termios;
+       uport->ops->set_termios(uport, termios, old_termios);
+
+       /*
+        * Set modem status enables based on termios cflag
+        */
+       spin_lock_irq(&uport->lock);
+       if (termios->c_cflag & CRTSCTS)
+               uport->status |= UPSTAT_CTS_ENABLE;
+       else
+               uport->status &= ~UPSTAT_CTS_ENABLE;
+
+       if (termios->c_cflag & CLOCAL)
+               uport->status &= ~UPSTAT_DCD_ENABLE;
+       else
+               uport->status |= UPSTAT_DCD_ENABLE;
+
+       /* reset sw-assisted CTS flow control based on (possibly) new mode */
+       old_hw_stopped = uport->hw_stopped;
+       uport->hw_stopped = uart_softcts_mode(uport) &&
+                           !(uport->ops->get_mctrl(uport) & TIOCM_CTS);
+       if (uport->hw_stopped != old_hw_stopped) {
+               if (!old_hw_stopped)
+                       uport->ops->stop_tx(uport);
+               else
+                       __uart_start(tty);
+       }
+       spin_unlock_irq(&uport->lock);
+}
+
 /*
  * Startup the port.  This will be called once per open.  All calls
  * 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,
                /*
                 * Initialise the hardware port settings.
                 */
-               uart_change_speed(tty, state, NULL);
+               uart_change_line_settings(tty, state, NULL);
 
                /*
                 * Setup the RTS and DTR signals once the
@@ -485,52 +528,6 @@ uart_get_divisor(struct uart_port *port, unsigned int baud)
 }
 EXPORT_SYMBOL(uart_get_divisor);
 
-/* Caller holds port mutex */
-static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
-                             const struct ktermios *old_termios)
-{
-       struct uart_port *uport = uart_port_check(state);
-       struct ktermios *termios;
-       int hw_stopped;
-
-       /*
-        * If we have no tty, termios, or the port does not exist,
-        * then we can't set the parameters for this port.
-        */
-       if (!tty || uport->type == PORT_UNKNOWN)
-               return;
-
-       termios = &tty->termios;
-       uport->ops->set_termios(uport, termios, old_termios);
-
-       /*
-        * Set modem status enables based on termios cflag
-        */
-       spin_lock_irq(&uport->lock);
-       if (termios->c_cflag & CRTSCTS)
-               uport->status |= UPSTAT_CTS_ENABLE;
-       else
-               uport->status &= ~UPSTAT_CTS_ENABLE;
-
-       if (termios->c_cflag & CLOCAL)
-               uport->status &= ~UPSTAT_DCD_ENABLE;
-       else
-               uport->status |= UPSTAT_DCD_ENABLE;
-
-       /* reset sw-assisted CTS flow control based on (possibly) new mode */
-       hw_stopped = uport->hw_stopped;
-       uport->hw_stopped = uart_softcts_mode(uport) &&
-                               !(uport->ops->get_mctrl(uport) & TIOCM_CTS);
-       if (uport->hw_stopped) {
-               if (!hw_stopped)
-                       uport->ops->stop_tx(uport);
-       } else {
-               if (hw_stopped)
-                       __uart_start(tty);
-       }
-       spin_unlock_irq(&uport->lock);
-}
-
 static int uart_put_char(struct tty_struct *tty, unsigned char c)
 {
        struct uart_state *state = tty->driver_data;
@@ -994,7 +991,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
                                      current->comm,
                                      tty_name(port->tty));
                        }
-                       uart_change_speed(tty, state, NULL);
+                       uart_change_line_settings(tty, state, NULL);
                }
        } else {
                retval = uart_startup(tty, state, true);
@@ -1491,7 +1488,7 @@ static int uart_set_iso7816_config(struct uart_port *port,
         * There are 5 words reserved for future use. Check that userspace
         * doesn't put stuff in there to prevent breakages in the future.
         */
-       for (i = 0; i < 5; i++)
+       for (i = 0; i < ARRAY_SIZE(iso7816.reserved); i++)
                if (iso7816.reserved[i])
                        return -EINVAL;
 
@@ -1656,15 +1653,15 @@ static void uart_set_termios(struct tty_struct *tty,
                goto out;
        }
 
-       uart_change_speed(tty, state, old_termios);
+       uart_change_line_settings(tty, state, old_termios);
        /* reload cflag from termios; port driver may have overridden flags */
        cflag = tty->termios.c_cflag;
 
        /* Handle transition to B0 status */
-       if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
+       if (((old_termios->c_cflag & CBAUD) != B0) && ((cflag & CBAUD) == B0))
                uart_clear_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
        /* Handle transition away from B0 status */
-       else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
+       else if (((old_termios->c_cflag & CBAUD) == B0) && ((cflag & CBAUD) != B0)) {
                unsigned int mask = TIOCM_DTR;
 
                if (!(cflag & CRTSCTS) || !tty_throttled(tty))
@@ -2452,7 +2449,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
                        ret = ops->startup(uport);
                        if (ret == 0) {
                                if (tty)
-                                       uart_change_speed(tty, state, NULL);
+                                       uart_change_line_settings(tty, state, NULL);
                                spin_lock_irq(&uport->lock);
                                if (!(uport->rs485.flags & SER_RS485_ENABLED))
                                        ops->set_mctrl(uport, uport->mctrl);
@@ -2593,6 +2590,7 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)
 {
        struct uart_driver *drv = driver->driver_state;
        struct uart_state *state = drv->state + line;
+       enum uart_pm_state pm_state;
        struct tty_port *tport;
        struct uart_port *port;
        int baud = 9600;
@@ -2610,6 +2608,9 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)
                goto out;
        }
 
+       pm_state = state->pm_state;
+       uart_change_pm(state, UART_PM_STATE_ON);
+
        if (port->ops->poll_init) {
                /*
                 * 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)
                console_list_unlock();
        }
 out:
+       if (ret)
+               uart_change_pm(state, pm_state);
        mutex_unlock(&tport->mutex);
        return ret;
 }
@@ -3305,13 +3308,13 @@ void uart_handle_cts_change(struct uart_port *uport, bool active)
        if (uart_softcts_mode(uport)) {
                if (uport->hw_stopped) {
                        if (active) {
-                               uport->hw_stopped = 0;
+                               uport->hw_stopped = false;
                                uport->ops->start_tx(uport);
                                uart_write_wakeup(uport);
                        }
                } else {
                        if (!active) {
-                               uport->hw_stopped = 1;
+                               uport->hw_stopped = true;
                                uport->ops->stop_tx(uport);
                        }
                }
index caa09a0..ca31e34 100644 (file)
@@ -1531,15 +1531,12 @@ static struct dma_chan *sci_request_dma_chan(struct uart_port *port,
 
        memset(&cfg, 0, sizeof(cfg));
        cfg.direction = dir;
-       if (dir == DMA_MEM_TO_DEV) {
-               cfg.dst_addr = port->mapbase +
-                       (sci_getreg(port, SCxTDR)->offset << port->regshift);
-               cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
-       } else {
-               cfg.src_addr = port->mapbase +
-                       (sci_getreg(port, SCxRDR)->offset << port->regshift);
-               cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
-       }
+       cfg.dst_addr = port->mapbase +
+               (sci_getreg(port, SCxTDR)->offset << port->regshift);
+       cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+       cfg.src_addr = port->mapbase +
+               (sci_getreg(port, SCxRDR)->offset << port->regshift);
+       cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
 
        ret = dmaengine_slave_config(chan, &cfg);
        if (ret) {
@@ -1574,7 +1571,7 @@ static void sci_request_dma(struct uart_port *port)
         * Don't request a dma channel if no channel was specified
         * in the device tree.
         */
-       if (!of_find_property(port->dev->of_node, "dmas", NULL))
+       if (!of_property_present(port->dev->of_node, "dmas"))
                return;
 
        chan = sci_request_dma_chan(port, DMA_MEM_TO_DEV);
@@ -3149,7 +3146,7 @@ static int sci_remove(struct platform_device *dev)
 #define SCI_OF_TYPE(data)              ((unsigned long)(data) >> 16)
 #define SCI_OF_REGTYPE(data)           ((unsigned long)(data) & 0xffff)
 
-static const struct of_device_id of_sci_match[] = {
+static const struct of_device_id of_sci_match[] __maybe_unused = {
        /* SoC-specific types */
        {
                .compatible = "renesas,scif-r7s72100",
index 492a3bd..b58f512 100644 (file)
@@ -1250,7 +1250,7 @@ static struct platform_driver sprd_platform_driver = {
        .remove         = sprd_remove,
        .driver         = {
                .name   = "sprd_serial",
-               .of_match_table = of_match_ptr(serial_ids),
+               .of_match_table = serial_ids,
                .pm     = &sprd_pm_ops,
        },
 };
index 767ff9f..1e38fc9 100644 (file)
@@ -693,8 +693,9 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
        int ret;
 
        if (!stm32_port->hw_flow_control &&
-           port->rs485.flags & SER_RS485_ENABLED) {
-               stm32_port->txdone = false;
+           port->rs485.flags & SER_RS485_ENABLED &&
+           (port->x_char ||
+            !(uart_circ_empty(xmit) || uart_tx_stopped(port)))) {
                stm32_usart_tc_interrupt_disable(port);
                stm32_usart_rs485_rts_enable(port);
        }
@@ -743,7 +744,6 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
                stm32_usart_tx_interrupt_disable(port);
                if (!stm32_port->hw_flow_control &&
                    port->rs485.flags & SER_RS485_ENABLED) {
-                       stm32_port->txdone = true;
                        stm32_usart_tc_interrupt_enable(port);
                }
        }
index 0ec41a7..903285b 100644 (file)
@@ -203,7 +203,6 @@ struct stm32_port {
        bool hw_flow_control;
        bool swap;               /* swap RX & TX pins */
        bool fifoen;
-       bool txdone;
        int rxftcfg;            /* RX FIFO threshold CFG      */
        int txftcfg;            /* TX FIFO threshold CFG      */
        bool wakeup_src;
index ccb8092..0fbeb3d 100644 (file)
@@ -1403,7 +1403,7 @@ static int zs_probe(struct platform_device *op)
        int keyboard_mouse = 0;
        int err;
 
-       if (of_find_property(op->dev.of_node, "keyboard", NULL))
+       if (of_property_present(op->dev.of_node, "keyboard"))
                keyboard_mouse = 1;
 
        /* uarts must come before keyboards/mice */
@@ -1553,7 +1553,7 @@ static int __init sunzilog_init(void)
 
        for_each_node_by_name(dp, "zs") {
                num_sunzilog++;
-               if (of_find_property(dp, "keyboard", NULL))
+               if (of_property_present(dp, "keyboard"))
                        num_keybms++;
        }
 
index 32c7a5b..404230c 100644 (file)
@@ -366,15 +366,14 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
        /* Pick next descriptor and fill from buffer */
        bdp = qe_port->tx_cur;
 
-       while (!(ioread16be(&bdp->status) & BD_SC_READY) &&
-              (xmit->tail != xmit->head)) {
+       while (!(ioread16be(&bdp->status) & BD_SC_READY) && !uart_circ_empty(xmit)) {
                count = 0;
                p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
                while (count < qe_port->tx_fifosize) {
                        *p++ = xmit->buf[xmit->tail];
                        uart_xmit_advance(port, 1);
                        count++;
-                       if (xmit->head == xmit->tail)
+                       if (uart_circ_empty(xmit))
                                break;
                }
 
@@ -1179,7 +1178,7 @@ static int soft_uart_init(struct platform_device *ofdev)
        struct qe_firmware_info *qe_fw_info;
        int ret;
 
-       if (of_find_property(np, "soft-uart", NULL)) {
+       if (of_property_read_bool(np, "soft-uart")) {
                dev_dbg(&ofdev->dev, "using Soft-UART mode\n");
                soft_uart = 1;
        } else {
index 33f258d..543b322 100644 (file)
@@ -730,7 +730,7 @@ static void set_termios(struct tty_struct *tty,
 
        /* Handle turning off CRTSCTS */
        if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) {
-               tty->hw_stopped = 0;
+               tty->hw_stopped = false;
                tx_release(tty);
        }
 }
@@ -1953,13 +1953,13 @@ static void cts_change(struct slgt_info *info, unsigned short status)
                if (info->port.tty) {
                        if (info->port.tty->hw_stopped) {
                                if (info->signals & SerialSignal_CTS) {
-                                       info->port.tty->hw_stopped = 0;
+                                       info->port.tty->hw_stopped = false;
                                        info->pending_bh |= BH_TRANSMIT;
                                        return;
                                }
                        } else {
                                if (!(info->signals & SerialSignal_CTS))
-                                       info->port.tty->hw_stopped = 1;
+                                       info->port.tty->hw_stopped = true;
                        }
                }
        }
index f45cd68..1e0d80e 100644 (file)
@@ -62,6 +62,8 @@ int __tty_check_change(struct tty_struct *tty, int sig);
 int tty_check_change(struct tty_struct *tty);
 void __stop_tty(struct tty_struct *tty);
 void __start_tty(struct tty_struct *tty);
+void tty_write_unlock(struct tty_struct *tty);
+int tty_write_lock(struct tty_struct *tty, int ndelay);
 void tty_vhangup_session(struct tty_struct *tty);
 void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty);
 int tty_signal_session_leader(struct tty_struct *tty, int exit_session);
index 36fb945..cfb3da0 100644 (file)
@@ -933,13 +933,13 @@ static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to)
        return i;
 }
 
-static void tty_write_unlock(struct tty_struct *tty)
+void tty_write_unlock(struct tty_struct *tty)
 {
        mutex_unlock(&tty->atomic_write_lock);
        wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
 }
 
-static int tty_write_lock(struct tty_struct *tty, int ndelay)
+int tty_write_lock(struct tty_struct *tty, int ndelay)
 {
        if (!mutex_trylock(&tty->atomic_write_lock)) {
                if (ndelay)
@@ -3614,31 +3614,13 @@ static struct ctl_table tty_table[] = {
        { }
 };
 
-static struct ctl_table tty_dir_table[] = {
-       {
-               .procname       = "tty",
-               .mode           = 0555,
-               .child          = tty_table,
-       },
-       { }
-};
-
-static struct ctl_table tty_root_table[] = {
-       {
-               .procname       = "dev",
-               .mode           = 0555,
-               .child          = tty_dir_table,
-       },
-       { }
-};
-
 /*
  * Ok, now we can initialize the rest of the tty devices and can count
  * on memory allocations, interrupts etc..
  */
 int __init tty_init(void)
 {
-       register_sysctl_table(tty_root_table);
+       register_sysctl_init("dev/tty", tty_table);
        cdev_init(&tty_cdev, &tty_fops);
        if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
index 12983ce..2e88b41 100644 (file)
@@ -7,6 +7,7 @@
  * discipline handling modules (like SLIP).
  */
 
+#include <linux/bits.h>
 #include <linux/types.h>
 #include <linux/termios.h>
 #include <linux/errno.h>
 /*
  * Internal flag options for termios setting behavior
  */
-#define TERMIOS_FLUSH  1
-#define TERMIOS_WAIT   2
-#define TERMIOS_TERMIO 4
-#define TERMIOS_OLD    8
+#define TERMIOS_FLUSH  BIT(0)
+#define TERMIOS_WAIT   BIT(1)
+#define TERMIOS_TERMIO BIT(2)
+#define TERMIOS_OLD    BIT(3)
 
 
 /**
@@ -500,21 +501,42 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
        tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
        tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
 
-       ld = tty_ldisc_ref(tty);
+       if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) {
+retry_write_wait:
+               retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty));
+               if (retval < 0)
+                       return retval;
 
-       if (ld != NULL) {
-               if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
-                       ld->ops->flush_buffer(tty);
-               tty_ldisc_deref(ld);
-       }
+               if (tty_write_lock(tty, 0) < 0)
+                       goto retry_write_wait;
 
-       if (opt & TERMIOS_WAIT) {
-               tty_wait_until_sent(tty, 0);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-       }
+               /* Racing writer? */
+               if (tty_chars_in_buffer(tty)) {
+                       tty_write_unlock(tty);
+                       goto retry_write_wait;
+               }
 
-       tty_set_termios(tty, &tmp_termios);
+               ld = tty_ldisc_ref(tty);
+               if (ld != NULL) {
+                       if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
+                               ld->ops->flush_buffer(tty);
+                       tty_ldisc_deref(ld);
+               }
+
+               if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) {
+                       tty->ops->wait_until_sent(tty, 0);
+                       if (signal_pending(current)) {
+                               tty_write_unlock(tty);
+                               return -ERESTARTSYS;
+                       }
+               }
+
+               tty_set_termios(tty, &tmp_termios);
+
+               tty_write_unlock(tty);
+       } else {
+               tty_set_termios(tty, &tmp_termios);
+       }
 
        /* FIXME: Arguably if tmp_termios == tty->termios AND the
           actual requested termios was not tmp_termios then we may
index e758f44..3f68e21 100644 (file)
@@ -58,7 +58,6 @@ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
 int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc)
 {
        unsigned long flags;
-       int ret = 0;
 
        if (new_ldisc->num < N_TTY || new_ldisc->num >= NR_LDISCS)
                return -EINVAL;
@@ -67,7 +66,7 @@ int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc)
        tty_ldiscs[new_ldisc->num] = new_ldisc;
        raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(tty_register_ldisc);
 
index 19376be..6f78f30 100644 (file)
@@ -18,16 +18,16 @@ struct plat_serial8250_port {
        unsigned long   iobase;         /* io base address */
        void __iomem    *membase;       /* ioremap cookie or NULL */
        resource_size_t mapbase;        /* resource base */
+       unsigned int    uartclk;        /* UART clock rate */
        unsigned int    irq;            /* interrupt number */
        unsigned long   irqflags;       /* request_irq flags */
-       unsigned int    uartclk;        /* UART clock rate */
        void            *private_data;
        unsigned char   regshift;       /* register shift */
        unsigned char   iotype;         /* UPIO_* */
        unsigned char   hub6;
        unsigned char   has_sysrq;      /* supports magic SysRq */
-       upf_t           flags;          /* UPF_* flags */
        unsigned int    type;           /* If UPF_FIXED_TYPE */
+       upf_t           flags;          /* UPF_* flags */
        unsigned int    (*serial_in)(struct uart_port *, int);
        void            (*serial_out)(struct uart_port *, int, int);
        void            (*set_termios)(struct uart_port *,
@@ -151,26 +151,22 @@ void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
 void serial8250_resume_port(int line);
 
-extern int early_serial_setup(struct uart_port *port);
-
-extern int early_serial8250_setup(struct earlycon_device *device,
-                                        const char *options);
-extern void serial8250_update_uartclk(struct uart_port *port,
-                                     unsigned int uartclk);
-extern void serial8250_do_set_termios(struct uart_port *port,
-               struct ktermios *termios, const struct ktermios *old);
-extern void serial8250_do_set_ldisc(struct uart_port *port,
-                                   struct ktermios *termios);
-extern unsigned int serial8250_do_get_mctrl(struct uart_port *port);
-extern int serial8250_do_startup(struct uart_port *port);
-extern void serial8250_do_shutdown(struct uart_port *port);
-extern void serial8250_do_pm(struct uart_port *port, unsigned int state,
-                            unsigned int oldstate);
-extern void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl);
-extern void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
-                                     unsigned int quot,
-                                     unsigned int quot_frac);
-extern int fsl8250_handle_irq(struct uart_port *port);
+int early_serial_setup(struct uart_port *port);
+int early_serial8250_setup(struct earlycon_device *device, const char *options);
+
+void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk);
+void serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
+                              const struct ktermios *old);
+void serial8250_do_set_ldisc(struct uart_port *port, struct ktermios *termios);
+unsigned int serial8250_do_get_mctrl(struct uart_port *port);
+int serial8250_do_startup(struct uart_port *port);
+void serial8250_do_shutdown(struct uart_port *port);
+void serial8250_do_pm(struct uart_port *port, unsigned int state,
+                     unsigned int oldstate);
+void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl);
+void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
+                              unsigned int quot, unsigned int quot_frac);
+int fsl8250_handle_irq(struct uart_port *port);
 int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
 u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr);
 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,
 int serial8250_console_setup(struct uart_port *port, char *options, bool probe);
 int serial8250_console_exit(struct uart_port *port);
 
-extern void serial8250_set_isa_configurator(void (*v)
-                                       (int port, struct uart_port *up,
-                                               u32 *capabilities));
+void serial8250_set_isa_configurator(void (*v)(int port, struct uart_port *up,
+                                              u32 *capabilities));
 
 #ifdef CONFIG_SERIAL_8250_RT288X
 unsigned int au_serial_in(struct uart_port *p, int offset);
index 9e3e5e0..66ecec1 100644 (file)
@@ -553,7 +553,7 @@ struct uart_port {
 #define UPSTAT_AUTOXOFF                ((__force upstat_t) (1 << 4))
 #define UPSTAT_SYNC_FIFO       ((__force upstat_t) (1 << 5))
 
-       int                     hw_stopped;             /* sw-assisted CTS flow state */
+       bool                    hw_stopped;             /* sw-assisted CTS flow state */
        unsigned int            mctrl;                  /* current modem ctrl settings */
        unsigned int            frame_time;             /* frame timing in ns */
        unsigned int            type;                   /* port type */
@@ -812,9 +812,8 @@ extern const struct earlycon_id __earlycon_table_end[];
 
 #define EARLYCON_DECLARE(_name, fn)    OF_EARLYCON_DECLARE(_name, "", fn)
 
-extern int of_setup_earlycon(const struct earlycon_id *match,
-                            unsigned long node,
-                            const char *options);
+int of_setup_earlycon(const struct earlycon_id *match, unsigned long node,
+                     const char *options);
 
 #ifdef CONFIG_SERIAL_EARLYCON
 extern bool earlycon_acpi_spcr_enable __initdata;
@@ -897,11 +896,11 @@ static inline bool uart_softcts_mode(struct uart_port *uport)
  * The following are helper functions for the low level drivers.
  */
 
-extern void uart_handle_dcd_change(struct uart_port *uport, bool active);
-extern void uart_handle_cts_change(struct uart_port *uport, bool active);
+void uart_handle_dcd_change(struct uart_port *uport, bool active);
+void uart_handle_cts_change(struct uart_port *uport, bool active);
 
-extern void uart_insert_char(struct uart_port *port, unsigned int status,
-                unsigned int overrun, unsigned int ch, unsigned int flag);
+void uart_insert_char(struct uart_port *port, unsigned int status,
+                     unsigned int overrun, unsigned int ch, unsigned int flag);
 
 void uart_xchar_out(struct uart_port *uport, int offset);
 
index 093935e..60871a9 100644 (file)
@@ -227,7 +227,7 @@ struct tty_struct {
                unsigned long unused[0];
        } __aligned(sizeof(unsigned long)) ctrl;
 
-       int hw_stopped;
+       bool hw_stopped;
        unsigned int receive_room;
        int flow_change;
 
index 848db1b..919d999 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <linux/string.h>
 
-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)
+#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE)
 #include <asm/vga.h>
 #endif
 
index a703780..eb67884 100644 (file)
@@ -43,10 +43,25 @@ struct gsm_config_ext {
        __u32 keep_alive;       /* Control channel keep-alive in 1/100th of a
                                 * second (0 to disable)
                                 */
-       __u32 reserved[7];      /* For future use, must be initialized to zero */
+       __u32 wait_config;      /* Wait for DLCI config before opening virtual link? */
+       __u32 reserved[6];      /* For future use, must be initialized to zero */
 };
 
 #define GSMIOC_GETCONF_EXT     _IOR('G', 5, struct gsm_config_ext)
 #define GSMIOC_SETCONF_EXT     _IOW('G', 6, struct gsm_config_ext)
 
+/* Set channel accordingly before calling GSMIOC_GETCONF_DLCI. */
+struct gsm_dlci_config {
+       __u32 channel;          /* DLCI (0 for the associated DLCI) */
+       __u32 adaption;         /* Convergence layer type */
+       __u32 mtu;              /* Maximum transfer unit */
+       __u32 priority;         /* Priority (0 for default value) */
+       __u32 i;                /* Frame type (1 = UIH, 2 = UI) */
+       __u32 k;                /* Window size (0 for default value) */
+       __u32 reserved[8];      /* For future use, must be initialized to zero */
+};
+
+#define GSMIOC_GETCONF_DLCI    _IOWR('G', 7, struct gsm_dlci_config)
+#define GSMIOC_SETCONF_DLCI    _IOW('G', 8, struct gsm_dlci_config)
+
 #endif