diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-11-03 15:44:25 -1000 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-11-03 15:44:25 -1000 |
commit | 1f24458a1071f006e3f7449c08ae0f12af493923 (patch) | |
tree | 3ed2b1f8de10f6638ce37dc4a41377e2b086f301 | |
parent | 4c7a0c95adc3ed8cc5e4c2187521aea3e40ba1aa (diff) | |
parent | 64ebf8797249e792af2143eb9e4bd404d10a022e (diff) | |
download | linux-1f24458a1071f006e3f7449c08ae0f12af493923.tar.gz linux-1f24458a1071f006e3f7449c08ae0f12af493923.tar.bz2 linux-1f24458a1071f006e3f7449c08ae0f12af493923.zip |
Merge tag 'tty-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty and serial updates from Greg KH:
"Here is the big set of tty/serial driver changes for 6.7-rc1. Included
in here are:
- console/vgacon cleanups and removals from Arnd
- tty core and n_tty cleanups from Jiri
- lots of 8250 driver updates and cleanups
- sc16is7xx serial driver updates
- dt binding updates
- first set of port lock wrapers from Thomas for the printk fixes
coming in future releases
- other small serial and tty core cleanups and updates
All of these have been in linux-next for a while with no reported
issues"
* tag 'tty-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (193 commits)
serdev: Replace custom code with device_match_acpi_handle()
serdev: Simplify devm_serdev_device_open() function
serdev: Make use of device_set_node()
tty: n_gsm: add copyright Siemens Mobility GmbH
tty: n_gsm: fix race condition in status line change on dead connections
serial: core: Fix runtime PM handling for pending tx
vgacon: fix mips/sibyte build regression
dt-bindings: serial: drop unsupported samsung bindings
tty: serial: samsung: drop earlycon support for unsupported platforms
tty: 8250: Add note for PX-835
tty: 8250: Fix IS-200 PCI ID comment
tty: 8250: Add Brainboxes Oxford Semiconductor-based quirks
tty: 8250: Add support for Intashield IX cards
tty: 8250: Add support for additional Brainboxes PX cards
tty: 8250: Fix up PX-803/PX-857
tty: 8250: Fix port count of PX-257
tty: 8250: Add support for Intashield IS-100
tty: 8250: Add support for Brainboxes UP cards
tty: 8250: Add support for additional Brainboxes UC cards
tty: 8250: Remove UC-257 and UC-431
...
172 files changed, 4055 insertions, 2326 deletions
diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index 820e412d38a8..895c47f05f6f 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -87,19 +87,22 @@ What: /sys/class/tty/ttyS<x>/close_delay Date: October 2012 Contact: Alan Cox <alan@linux.intel.com> Description: - Show the closing delay time for this port in ms. + Show the closing delay time for this port in centiseconds. - These sysfs values expose the TIOCGSERIAL interface via - sysfs rather than via ioctls. + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. What: /sys/class/tty/ttyS<x>/closing_wait Date: October 2012 Contact: Alan Cox <alan@linux.intel.com> Description: - Show the close wait time for this port in ms. + Show the close wait time for this port in centiseconds. - These sysfs values expose the TIOCGSERIAL interface via - sysfs rather than via ioctls. + Waiting forever is represented as 0. If waiting on close is + disabled then the value is 65535. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. What: /sys/class/tty/ttyS<x>/custom_divisor Date: October 2012 diff --git a/Documentation/devicetree/bindings/serial/esp,esp32-acm.yaml b/Documentation/devicetree/bindings/serial/esp,esp32-acm.yaml new file mode 100644 index 000000000000..77fbb2c72171 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/esp,esp32-acm.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause + +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/esp,esp32-acm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ESP32S3 ACM gadget controller + +maintainers: + - Max Filippov <jcmvbkbc@gmail.com> + +description: + Fixed function USB CDC-ACM gadget controller of the Espressif ESP32S3 SoC. + +allOf: + - $ref: serial.yaml# + +properties: + compatible: + const: esp,esp32s3-acm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + serial@60038000 { + compatible = "esp,esp32s3-acm"; + reg = <0x60038000 0x1000>; + interrupts = <96 3 0>; + }; diff --git a/Documentation/devicetree/bindings/serial/esp,esp32-uart.yaml b/Documentation/devicetree/bindings/serial/esp,esp32-uart.yaml new file mode 100644 index 000000000000..2a80ca997a0c --- /dev/null +++ b/Documentation/devicetree/bindings/serial/esp,esp32-uart.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause + +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/esp,esp32-uart.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ESP32xx UART controllers + +maintainers: + - Max Filippov <jcmvbkbc@gmail.com> + +description: + ESP32 UART controller is a part of the ESP32 SoC. + ESP32S3 UART controller is a part of the ESP32S3 SoC. + Both SoCs are produced by Espressif Systems Co. Ltd. + +allOf: + - $ref: serial.yaml# + +properties: + compatible: + enum: + - esp,esp32-uart + - esp,esp32s3-uart + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + serial@60000000 { + compatible = "esp,esp32s3-uart"; + reg = <0x60000000 0x80>; + interrupts = <27 1 0>; + clocks = <&serial_clk>; + }; diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml b/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml index 40414247d61a..83035553044a 100644 --- a/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml +++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml @@ -70,6 +70,8 @@ properties: interrupts: maxItems: 1 + wakeup-source: true + fsl,dte-mode: $ref: /schemas/types.yaml#/definitions/flag description: | diff --git a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml index 6a400a5e6fc7..da032effffe6 100644 --- a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml +++ b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml @@ -14,10 +14,13 @@ allOf: properties: compatible: - enum: - - fsl,imx23-auart - - fsl,imx28-auart - - alphascale,asm9260-auart + oneOf: + - const: fsl,imx23-auart + - const: alphascale,asm9260-auart + - items: + - enum: + - fsl,imx28-auart + - const: fsl,imx23-auart reg: maxItems: 1 @@ -82,7 +85,7 @@ examples: }; auart0: serial@8006a000 { - compatible = "fsl,imx28-auart"; + compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x8006a000 0x2000>; interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; diff --git a/Documentation/devicetree/bindings/serial/maxim,max310x.txt b/Documentation/devicetree/bindings/serial/maxim,max310x.txt deleted file mode 100644 index 79e10a05a96a..000000000000 --- a/Documentation/devicetree/bindings/serial/maxim,max310x.txt +++ /dev/null @@ -1,48 +0,0 @@ -* Maxim MAX310X advanced Universal Asynchronous Receiver-Transmitter (UART) - -Required properties: -- compatible: Should be one of the following: - - "maxim,max3107" for Maxim MAX3107, - - "maxim,max3108" for Maxim MAX3108, - - "maxim,max3109" for Maxim MAX3109, - - "maxim,max14830" for Maxim MAX14830. -- reg: SPI chip select number. -- interrupts: Specifies the interrupt source of the parent interrupt - controller. The format of the interrupt specifier depends on the - parent interrupt controller. -- clocks: phandle to the IC source clock. -- clock-names: Should be "xtal" if clock is an external crystal or - "osc" if an external clock source is used. - -Optional properties: -- gpio-controller: Marks the device node as a GPIO controller. -- #gpio-cells: Should be two. The first cell is the GPIO number and - the second cell is used to specify the GPIO polarity: - 0 = active high, - 1 = active low. - -Example: - -/ { - clocks { - spi_uart_clk: osc_max14830 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <3686400>; - }; - - }; -}; - -&spi0 { - max14830: max14830@0 { - compatible = "maxim,max14830"; - reg = <0>; - clocks = <&spi_uart_clk>; - clock-names = "osc"; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - gpio-controller; - #gpio-cells = <2>; - }; -}; diff --git a/Documentation/devicetree/bindings/serial/maxim,max310x.yaml b/Documentation/devicetree/bindings/serial/maxim,max310x.yaml new file mode 100644 index 000000000000..889eeaca64a0 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/maxim,max310x.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/maxim,max310x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX310X Advanced Universal Asynchronous Receiver-Transmitter (UART) + +maintainers: + - Hugo Villeneuve <hvilleneuve@dimonoff.com> + +properties: + compatible: + enum: + - maxim,max3107 + - maxim,max3108 + - maxim,max3109 + - maxim,max14830 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + enum: + - xtal # External crystal + - osc # External clock source + + gpio-controller: true + + "#gpio-cells": + const: 2 + + gpio-line-names: + minItems: 1 + maxItems: 16 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + - $ref: /schemas/serial/serial.yaml# + - $ref: /schemas/serial/rs485.yaml# + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + serial@2c { + compatible = "maxim,max3107"; + reg = <0x2c>; + clocks = <&xtal4m>; + clock-names = "xtal"; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + gpio-controller; + #gpio-cells = <2>; + }; + }; diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.yaml b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.yaml index 04d55fecf47c..a5d67563cd53 100644 --- a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.yaml +++ b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.yaml @@ -91,11 +91,6 @@ properties: - description: range upper bound - description: adjustment (in permyriad, i.e. 0.01%) -allOf: - - $ref: serial.yaml - -unevaluatedProperties: false - required: - compatible - reg @@ -106,6 +101,11 @@ required: - dmas - dma-names +allOf: + - $ref: serial.yaml + +unevaluatedProperties: false + examples: - | #include <dt-bindings/clock/tegra30-car.h> diff --git a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt deleted file mode 100644 index 1a7e4bff0456..000000000000 --- a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt +++ /dev/null @@ -1,118 +0,0 @@ -* NXP SC16IS7xx advanced Universal Asynchronous Receiver-Transmitter (UART) -* i2c as bus - -Required properties: -- compatible: Should be one of the following: - - "nxp,sc16is740" for NXP SC16IS740, - - "nxp,sc16is741" for NXP SC16IS741, - - "nxp,sc16is750" for NXP SC16IS750, - - "nxp,sc16is752" for NXP SC16IS752, - - "nxp,sc16is760" for NXP SC16IS760, - - "nxp,sc16is762" for NXP SC16IS762. -- reg: I2C address of the SC16IS7xx device. -- interrupts: Should contain the UART interrupt -- clocks: Reference to the IC source clock. - OR (when there is no clock provider visible to the platform) -- clock-frequency: The source clock frequency for the IC. - -Optional properties: -- gpio-controller: Marks the device node as a GPIO controller. -- #gpio-cells: Should be two. The first cell is the GPIO number and - the second cell is used to specify the GPIO polarity: - 0 = active high, - 1 = active low. -- irda-mode-ports: An array that lists the indices of the port that - should operate in IrDA mode. -- nxp,modem-control-line-ports: An array that lists the indices of the port that - should have shared GPIO lines configured as - modem control lines. - -Example: - sc16is750: sc16is750@51 { - compatible = "nxp,sc16is750"; - reg = <0x51>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - gpio-controller; - #gpio-cells = <2>; - }; - - sc16is752: sc16is752@53 { - compatible = "nxp,sc16is752"; - reg = <0x53>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ - gpio-controller; /* Port 0 as GPIOs */ - #gpio-cells = <2>; - }; - - sc16is752: sc16is752@54 { - compatible = "nxp,sc16is752"; - reg = <0x54>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ - }; - -* spi as bus - -Required properties: -- compatible: Should be one of the following: - - "nxp,sc16is740" for NXP SC16IS740, - - "nxp,sc16is741" for NXP SC16IS741, - - "nxp,sc16is750" for NXP SC16IS750, - - "nxp,sc16is752" for NXP SC16IS752, - - "nxp,sc16is760" for NXP SC16IS760, - - "nxp,sc16is762" for NXP SC16IS762. -- reg: SPI chip select number. -- interrupts: Specifies the interrupt source of the parent interrupt - controller. The format of the interrupt specifier depends on the - parent interrupt controller. -- clocks: phandle to the IC source clock. - -Optional properties: -- gpio-controller: Marks the device node as a GPIO controller. -- #gpio-cells: Should be two. The first cell is the GPIO number and - the second cell is used to specify the GPIO polarity: - 0 = active high, - 1 = active low. -- irda-mode-ports: An array that lists the indices of the port that - should operate in IrDA mode. -- nxp,modem-control-line-ports: An array that lists the indices of the port that - should have shared GPIO lines configured as - modem control lines. - -Example: - sc16is750: sc16is750@0 { - compatible = "nxp,sc16is750"; - reg = <0>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - gpio-controller; - #gpio-cells = <2>; - }; - - sc16is752: sc16is752@1 { - compatible = "nxp,sc16is752"; - reg = <1>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ - gpio-controller; /* Port 0 as GPIOs */ - #gpio-cells = <2>; - }; - - sc16is752: sc16is752@2 { - compatible = "nxp,sc16is752"; - reg = <2>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ - }; diff --git a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.yaml b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.yaml new file mode 100644 index 000000000000..5dec15b7e7c3 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.yaml @@ -0,0 +1,127 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/nxp,sc16is7xx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP SC16IS7xx Advanced Universal Asynchronous Receiver-Transmitter (UART) + +maintainers: + - Hugo Villeneuve <hvilleneuve@dimonoff.com> + +properties: + compatible: + enum: + - nxp,sc16is740 + - nxp,sc16is741 + - nxp,sc16is750 + - nxp,sc16is752 + - nxp,sc16is760 + - nxp,sc16is762 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-frequency: + description: + When there is no clock provider visible to the platform, this + is the source crystal or external clock frequency for the IC in Hz. + minimum: 1 + maximum: 80000000 + + gpio-controller: true + + "#gpio-cells": + const: 2 + + gpio-line-names: + minItems: 1 + maxItems: 8 + + irda-mode-ports: + description: | + An array that lists the indices of the port that should operate in IrDA + mode: + 0: port A + 1: port B + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 2 + items: + minimum: 0 + maximum: 1 + + nxp,modem-control-line-ports: + description: | + An array that lists the indices of the port that should have shared GPIO + lines configured as modem control lines: + 0: port A + 1: port B + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 2 + items: + minimum: 0 + maximum: 1 + +required: + - compatible + - reg + - interrupts + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + - $ref: /schemas/serial/serial.yaml# + - $ref: /schemas/serial/rs485.yaml# + +oneOf: + - required: + - clocks + - required: + - clock-frequency + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + serial@51 { + compatible = "nxp,sc16is750"; + reg = <0x51>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + gpio-controller; + #gpio-cells = <2>; + }; + + serial@53 { + compatible = "nxp,sc16is752"; + reg = <0x53>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ + gpio-controller; /* Port 0 as GPIOs */ + #gpio-cells = <2>; + }; + + serial@54 { + compatible = "nxp,sc16is752"; + reg = <0x54>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ + }; + }; diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml b/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml index a052aaef21f4..ea6abfe2d95e 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml @@ -40,11 +40,11 @@ required: - interrupts - reg -unevaluatedProperties: false - allOf: - $ref: /schemas/serial/serial.yaml# +unevaluatedProperties: false + examples: - | serial@a9c00000 { diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml index 484b9a51f6a9..ee52bf8e8917 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml @@ -78,8 +78,6 @@ required: - interrupts - reg -unevaluatedProperties: false - allOf: - $ref: /schemas/serial/serial.yaml# @@ -97,6 +95,8 @@ allOf: reg: maxItems: 1 +unevaluatedProperties: false + examples: - | #include <dt-bindings/interrupt-controller/arm-gic.h> diff --git a/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml b/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml index 3fc2601f1338..89f1eb0f2c5a 100644 --- a/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml @@ -38,6 +38,13 @@ properties: - const: sclk - const: pclk +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + allOf: - $ref: serial.yaml# @@ -53,13 +60,6 @@ allOf: clock-names: minItems: 2 -required: - - compatible - - reg - - interrupts - - clocks - - clock-names - unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml index 1c7f1276aed6..2046e2dc0a3d 100644 --- a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml @@ -111,8 +111,6 @@ required: - clock-names - power-domains -unevaluatedProperties: false - if: properties: compatible: @@ -125,6 +123,8 @@ then: required: - resets +unevaluatedProperties: false + examples: - | #include <dt-bindings/clock/r8a7795-cpg-mssr.h> diff --git a/Documentation/devicetree/bindings/serial/renesas,scif.yaml b/Documentation/devicetree/bindings/serial/renesas,scif.yaml index 99030fc18c45..4610a5bd580c 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scif.yaml @@ -79,6 +79,7 @@ properties: - enum: - renesas,scif-r9a07g043 # RZ/G2UL and RZ/Five - renesas,scif-r9a07g054 # RZ/V2L + - renesas,scif-r9a08g045 # RZ/G3S - const: renesas,scif-r9a07g044 # RZ/G2{L,LC} fallback reg: diff --git a/Documentation/devicetree/bindings/serial/renesas,scifa.yaml b/Documentation/devicetree/bindings/serial/renesas,scifa.yaml index 499507678cdf..c98657cf4666 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scifa.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scifa.yaml @@ -77,8 +77,6 @@ required: - clock-names - power-domains -unevaluatedProperties: false - if: properties: compatible: @@ -89,6 +87,8 @@ then: required: - resets +unevaluatedProperties: false + examples: - | #include <dt-bindings/clock/r8a7790-cpg-mssr.h> diff --git a/Documentation/devicetree/bindings/serial/renesas,scifb.yaml b/Documentation/devicetree/bindings/serial/renesas,scifb.yaml index 810d8a991fdd..fb695b3111ac 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scifb.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scifb.yaml @@ -77,8 +77,6 @@ required: - clock-names - power-domains -unevaluatedProperties: false - if: properties: compatible: @@ -89,6 +87,8 @@ then: required: - resets +unevaluatedProperties: false + examples: - | #include <dt-bindings/clock/r8a7740-clock.h> diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml index 303a443d9e29..9418fd66a8e9 100644 --- a/Documentation/devicetree/bindings/serial/rs485.yaml +++ b/Documentation/devicetree/bindings/serial/rs485.yaml @@ -29,6 +29,10 @@ properties: default: 0 maximum: 100 + rs485-rts-active-high: + description: drive RTS high when sending (this is the default). + $ref: /schemas/types.yaml#/definitions/flag + rs485-rts-active-low: description: drive RTS low when sending (default is high). $ref: /schemas/types.yaml#/definitions/flag diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml index 8bd88d5cbb11..ac60ab1e35e3 100644 --- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml +++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml @@ -24,9 +24,6 @@ properties: - enum: - apple,s5l-uart - axis,artpec8-uart - - samsung,s3c2410-uart - - samsung,s3c2412-uart - - samsung,s3c2440-uart - samsung,s3c6400-uart - samsung,s5pv210-uart - samsung,exynos4210-uart @@ -86,8 +83,6 @@ required: - interrupts - reg -unevaluatedProperties: false - allOf: - $ref: serial.yaml# @@ -96,7 +91,6 @@ allOf: compatible: contains: enum: - - samsung,s3c2410-uart - samsung,s5pv210-uart then: properties: @@ -128,6 +122,8 @@ allOf: - const: uart - const: clk_uart_baud0 +unevaluatedProperties: false + examples: - | #include <dt-bindings/clock/samsung,s3c64xx-clock.h> diff --git a/Documentation/devicetree/bindings/serial/serial.yaml b/Documentation/devicetree/bindings/serial/serial.yaml index ea277560a596..65804ca274ae 100644 --- a/Documentation/devicetree/bindings/serial/serial.yaml +++ b/Documentation/devicetree/bindings/serial/serial.yaml @@ -87,16 +87,8 @@ properties: description: TX FIFO threshold configuration (in bytes). -if: - required: - - uart-has-rtscts -then: - properties: - cts-gpios: false - rts-gpios: false - patternProperties: - "^bluetooth|gnss|gps|mcu$": + "^(bluetooth|bluetooth-gnss|gnss|gps|mcu)$": if: type: object then: @@ -136,6 +128,14 @@ patternProperties: required: - compatible +if: + required: + - uart-has-rtscts +then: + properties: + cts-gpios: false + rts-gpios: false + additionalProperties: true examples: diff --git a/Documentation/driver-api/tty/index.rst b/Documentation/driver-api/tty/index.rst index 2d32606a4278..b490da11f257 100644 --- a/Documentation/driver-api/tty/index.rst +++ b/Documentation/driver-api/tty/index.rst @@ -36,6 +36,7 @@ In-detail description of the named TTY structures is in separate documents: tty_struct tty_ldisc tty_buffer + tty_ioctl tty_internals Writing TTY Driver diff --git a/Documentation/driver-api/tty/tty_ioctl.rst b/Documentation/driver-api/tty/tty_ioctl.rst new file mode 100644 index 000000000000..3ff1ac5e07f1 --- /dev/null +++ b/Documentation/driver-api/tty/tty_ioctl.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================= +TTY IOCTL Helpers +================= + +.. kernel-doc:: drivers/tty/tty_ioctl.c + +.. kernel-doc:: include/linux/tty.h + :identifiers: tty_get_baud_rate diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 5816a31c1b38..2c89c1c55712 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include <linux/interrupt.h> +#include <linux/screen_info.h> #include <linux/io.h> /* Prototypes of functions used across modules here in this directory. */ @@ -113,6 +114,7 @@ extern int boot_cpuid; #ifdef CONFIG_VERBOSE_MCHECK extern unsigned long alpha_verbose_mcheck; #endif +extern struct screen_info vgacon_screen_info; /* srmcons.c */ #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index c80258ec332f..0738f9396f95 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -131,13 +131,14 @@ static void determine_cpu_caches (unsigned int); static char __initdata command_line[COMMAND_LINE_SIZE]; +#ifdef CONFIG_VGA_CONSOLE /* * The format of "screen_info" is strange, and due to early * i386-setup code. This is just enough to make the console * code think we're on a VGA color display. */ -struct screen_info screen_info = { +struct screen_info vgacon_screen_info = { .orig_x = 0, .orig_y = 25, .orig_video_cols = 80, @@ -145,8 +146,7 @@ struct screen_info screen_info = { .orig_video_isVGA = 1, .orig_video_points = 16 }; - -EXPORT_SYMBOL(screen_info); +#endif /* * The direct map I/O window, if any. This should be the same @@ -652,7 +652,7 @@ setup_arch(char **cmdline_p) #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; + vgacon_register_screen(&vgacon_screen_info); #endif #endif diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index 7c420d8dac53..086488ed83a7 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -57,11 +57,13 @@ sio_init_irq(void) static inline void __init alphabook1_init_arch(void) { +#ifdef CONFIG_VGA_CONSOLE /* The AlphaBook1 has LCD video fixed at 800x600, 37 rows and 100 cols. */ - screen_info.orig_y = 37; - screen_info.orig_video_cols = 100; - screen_info.orig_video_lines = 37; + vgacon_screen_info.orig_y = 37; + vgacon_screen_info.orig_video_cols = 100; + vgacon_screen_info.orig_video_lines = 37; +#endif lca_init_arch(); } diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 546af8b1e3f6..cc106f946c69 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -11,6 +11,7 @@ #ifndef __ASMARM_SETUP_H #define __ASMARM_SETUP_H +#include <linux/screen_info.h> #include <uapi/asm/setup.h> @@ -35,4 +36,8 @@ void early_mm_init(const struct machine_desc *); void adjust_lowmem_bounds(void); void setup_dma_zone(const struct machine_desc *desc); +#ifdef CONFIG_VGA_CONSOLE +extern struct screen_info vgacon_screen_info; +#endif + #endif diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h index 7c0bee57855a..6c430ec371df 100644 --- a/arch/arm/include/asm/vga.h +++ b/arch/arm/include/asm/vga.h @@ -5,6 +5,7 @@ #include <linux/io.h> extern unsigned long vga_base; +extern struct screen_info vgacon_screen_info; #define VGA_MAP_MEM(x,s) (vga_base + (x)) diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c index 33f6eb5213a5..4ec591bde3df 100644 --- a/arch/arm/kernel/atags_parse.c +++ b/arch/arm/kernel/atags_parse.c @@ -69,18 +69,18 @@ static int __init parse_tag_mem32(const struct tag *tag) __tagtable(ATAG_MEM, parse_tag_mem32); -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) +#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_VGA_CONSOLE) static int __init parse_tag_videotext(const struct tag *tag) { - screen_info.orig_x = tag->u.videotext.x; - screen_info.orig_y = tag->u.videotext.y; - screen_info.orig_video_page = tag->u.videotext.video_page; - screen_info.orig_video_mode = tag->u.videotext.video_mode; - screen_info.orig_video_cols = tag->u.videotext.video_cols; - screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; - screen_info.orig_video_lines = tag->u.videotext.video_lines; - screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; - screen_info.orig_video_points = tag->u.videotext.video_points; + vgacon_screen_info.orig_x = tag->u.videotext.x; + vgacon_screen_info.orig_y = tag->u.videotext.y; + vgacon_screen_info.orig_video_page = tag->u.videotext.video_page; + vgacon_screen_info.orig_video_mode = tag->u.videotext.video_mode; + vgacon_screen_info.orig_video_cols = tag->u.videotext.video_cols; + vgacon_screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; + vgacon_screen_info.orig_video_lines = tag->u.videotext.video_lines; + vgacon_screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; + vgacon_screen_info.orig_video_points = tag->u.videotext.video_points; return 0; } diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c index e94655ef16bb..6f9ec7d28a71 100644 --- a/arch/arm/kernel/efi.c +++ b/arch/arm/kernel/efi.c @@ -123,12 +123,6 @@ void __init arm_efi_init(void) { efi_init(); - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) { - /* dummycon on ARM needs non-zero values for columns/lines */ - screen_info.orig_video_cols = 80; - screen_info.orig_video_lines = 25; - } - /* ARM does not permit early mappings to persist across paging_init() */ efi_memmap_unmap(); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b01cac05bd4c..ff2299ce1ad7 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -928,9 +928,8 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) request_resource(&ioport_resource, &lp2); } -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) || \ - defined(CONFIG_EFI) -struct screen_info screen_info = { +#if defined(CONFIG_VGA_CONSOLE) +struct screen_info vgacon_screen_info = { .orig_video_lines = 30, .orig_video_cols = 80, .orig_video_mode = 0, @@ -1194,7 +1193,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; + vgacon_register_screen(&vgacon_screen_info); #endif #endif diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 3f8c9c143552..0228001347be 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -71,10 +71,6 @@ static __init pteval_t create_mapping_protection(efi_memory_desc_t *md) return pgprot_val(PAGE_KERNEL_EXEC); } -/* we will fill this structure from the stub, so don't put it in .bss */ -struct screen_info screen_info __section(".data"); -EXPORT_SYMBOL(screen_info); - int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) { pteval_t prot_val = create_mapping_protection(md); diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index 35f3c7959513..5e4dc72ab1bd 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -27,7 +27,9 @@ PROVIDE(__efistub__text = _text); PROVIDE(__efistub__end = _end); PROVIDE(__efistub___inittext_end = __inittext_end); PROVIDE(__efistub__edata = _edata); +#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) PROVIDE(__efistub_screen_info = screen_info); +#endif PROVIDE(__efistub__ctype = _ctype); PROVIDE(__pi___memcpy = __pi_memcpy); diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c index 106fbf0b6f3b..51012e90780d 100644 --- a/arch/csky/kernel/setup.c +++ b/arch/csky/kernel/setup.c @@ -8,22 +8,10 @@ #include <linux/of_fdt.h> #include <linux/start_kernel.h> #include <linux/dma-map-ops.h> -#include <linux/screen_info.h> #include <asm/sections.h> #include <asm/mmu_context.h> #include <asm/pgalloc.h> -#ifdef CONFIG_DUMMY_CONSOLE -struct screen_info screen_info = { - .orig_video_lines = 30, - .orig_video_cols = 80, - .orig_video_mode = 0, - .orig_video_ega_bx = 0, - .orig_video_isVGA = 1, - .orig_video_points = 8 -}; -#endif - static void __init csky_memblock_init(void) { unsigned long lowmem_size = PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); diff --git a/arch/hexagon/kernel/Makefile b/arch/hexagon/kernel/Makefile index e73cb321630e..3fdf937eb572 100644 --- a/arch/hexagon/kernel/Makefile +++ b/arch/hexagon/kernel/Makefile @@ -17,5 +17,3 @@ obj-y += vm_vectors.o obj-$(CONFIG_HAS_DMA) += dma.o obj-$(CONFIG_STACKTRACE) += stacktrace.o - -obj-$(CONFIG_VGA_CONSOLE) += screen_info.o diff --git a/arch/hexagon/kernel/screen_info.c b/arch/hexagon/kernel/screen_info.c deleted file mode 100644 index 1e1ceb18bafe..000000000000 --- a/arch/hexagon/kernel/screen_info.c +++ /dev/null @@ -1,3 +0,0 @@ -#include <linux/screen_info.h> - -struct screen_info screen_info; diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 9fc10cea21e1..acb5d3385675 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -68,6 +68,11 @@ void __init efi_runtime_init(void) unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; +#if defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON) +struct screen_info screen_info __section(".data"); +EXPORT_SYMBOL_GPL(screen_info); +#endif + static void __init init_screen_info(void) { struct screen_info *si; @@ -115,7 +120,8 @@ void __init efi_init(void) set_bit(EFI_CONFIG_TABLES, &efi.flags); - init_screen_info(); + if (IS_ENABLED(CONFIG_EFI_EARLYCON) || IS_ENABLED(CONFIG_SYSFB)) + init_screen_info(); if (boot_memmap == EFI_INVALID_TABLE_ADDR) return; diff --git a/arch/loongarch/kernel/image-vars.h b/arch/loongarch/kernel/image-vars.h index e561989d02de..5087416b9678 100644 --- a/arch/loongarch/kernel/image-vars.h +++ b/arch/loongarch/kernel/image-vars.h @@ -12,7 +12,9 @@ __efistub_kernel_entry = kernel_entry; __efistub_kernel_asize = kernel_asize; __efistub_kernel_fsize = kernel_fsize; __efistub_kernel_offset = kernel_offset; +#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) __efistub_screen_info = screen_info; +#endif #endif diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index b35186f7b254..d183a745fb85 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -16,7 +16,6 @@ #include <linux/dmi.h> #include <linux/efi.h> #include <linux/export.h> -#include <linux/screen_info.h> #include <linux/memblock.h> #include <linux/initrd.h> #include <linux/ioport.h> @@ -57,8 +56,6 @@ #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 #define LOONGSON_EFI_ENABLE (1 << 3) -struct screen_info screen_info __section(".data"); - unsigned long fw_arg0, fw_arg1, fw_arg2; DEFINE_PER_CPU(unsigned long, kernelsp); struct cpuinfo_loongarch cpu_data[NR_CPUS] __read_mostly; diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index 04aab419a0fc..e318ea11c858 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -13,7 +13,6 @@ #include <linux/init.h> #include <linux/ioport.h> #include <linux/console.h> -#include <linux/screen_info.h> #include <linux/platform_device.h> #include <linux/serial_8250.h> #include <linux/dma-mapping.h> @@ -76,14 +75,6 @@ void __init plat_mem_setup(void) _machine_restart = jazz_machine_restart; -#ifdef CONFIG_VT - screen_info = (struct screen_info) { - .orig_video_cols = 160, - .orig_video_lines = 64, - .orig_video_points = 16, - }; -#endif - add_preferred_console("ttyS", 0, "9600"); } diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 08321c945ac4..2d2ca024bd47 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -15,7 +15,6 @@ #include <linux/delay.h> #include <linux/ioport.h> #include <linux/export.h> -#include <linux/screen_info.h> #include <linux/memblock.h> #include <linux/initrd.h> #include <linux/root_dev.h> @@ -54,10 +53,6 @@ struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; EXPORT_SYMBOL(cpu_data); -#ifdef CONFIG_VT -struct screen_info screen_info; -#endif - /* * Setup information * @@ -793,12 +788,6 @@ void __init setup_arch(char **cmdline_p) if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64)) check_bugs64_early(); -#if defined(CONFIG_VT) -#if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; -#endif -#endif - arch_mem_init(cmdline_p); dmi_setup(); diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index 21cb3ac1237b..3a2836e9d856 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -161,7 +161,7 @@ static void __init pci_clock_check(void) #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) static void __init screen_info_setup(void) { - screen_info = (struct screen_info) { + static struct screen_info si = { .orig_x = 0, .orig_y = 25, .ext_mem_k = 0, @@ -175,6 +175,8 @@ static void __init screen_info_setup(void) .orig_video_isVGA = VIDEO_TYPE_VGAC, .orig_video_points = 16 }; + + vgacon_register_screen(&si); } #endif diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index 76683993cdd3..38c90b5e8754 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c @@ -13,6 +13,7 @@ #include <linux/memblock.h> #include <linux/init.h> #include <linux/kernel.h> +#include <linux/console.h> #include <linux/screen_info.h> #include <linux/initrd.h> @@ -112,6 +113,19 @@ int update_persistent_clock64(struct timespec64 now) } } +#ifdef CONFIG_VGA_CONSOLE +static struct screen_info vgacon_screen_info = { + .orig_video_page = 52, + .orig_video_mode = 3, + .orig_video_cols = 80, + .flags = 12, + .orig_video_ega_bx = 3, + .orig_video_lines = 25, + .orig_video_isVGA = 0x22, + .orig_video_points = 16, +}; +#endif + void __init plat_mem_setup(void) { #ifdef CONFIG_SIBYTE_BCM1x80 @@ -129,17 +143,8 @@ void __init plat_mem_setup(void) if (m41t81_probe()) swarm_rtc_type = RTC_M41T81; -#ifdef CONFIG_VT - screen_info = (struct screen_info) { - .orig_video_page = 52, - .orig_video_mode = 3, - .orig_video_cols = 80, - .flags = 12, - .orig_video_ega_bx = 3, - .orig_video_lines = 25, - .orig_video_isVGA = 0x22, - .orig_video_points = 16, - }; +#ifdef CONFIG_VGA_CONSOLE + vgacon_register_screen(&vgacon_screen_info); /* XXXKW for CFE, get lines/cols from environment */ #endif } diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index efad85c8c823..42fdb939c88d 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c @@ -38,19 +38,21 @@ extern void sni_machine_power_off(void); static void __init sni_display_setup(void) { -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_FW_ARC) - struct screen_info *si = &screen_info; +#if defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_FW_ARC) + static struct screen_info si; DISPLAY_STATUS *di; di = ArcGetDisplayStatus(1); if (di) { - si->orig_x = di->CursorXPosition; - si->orig_y = di->CursorYPosition; - si->orig_video_cols = di->CursorMaxXPosition; - si->orig_video_lines = di->CursorMaxYPosition; - si->orig_video_isVGA = VIDEO_TYPE_VGAC; - si->orig_video_points = 16; + si.orig_x = di->CursorXPosition; + si.orig_y = di->CursorYPosition; + si.orig_video_cols = di->CursorMaxXPosition; + si.orig_video_lines = di->CursorMaxYPosition; + si.orig_video_isVGA = VIDEO_TYPE_VGAC; + si.orig_video_points = 16; + + vgacon_register_screen(&si); } #endif } diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c index 8582ed965844..da122a5fa43b 100644 --- a/arch/nios2/kernel/setup.c +++ b/arch/nios2/kernel/setup.c @@ -19,7 +19,6 @@ #include <linux/memblock.h> #include <linux/initrd.h> #include <linux/of_fdt.h> -#include <linux/screen_info.h> #include <asm/mmu_context.h> #include <asm/sections.h> @@ -36,10 +35,6 @@ static struct pt_regs fake_regs = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -#ifdef CONFIG_VT -struct screen_info screen_info; -#endif - /* Copy a short hook instruction sequence to the exception address */ static inline void copy_exception_handler(unsigned int addr) { diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index ca92cf0ffde1..9b142b9d5187 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -22,7 +22,6 @@ #include <linux/seq_file.h> #include <linux/ioport.h> #include <linux/console.h> -#include <linux/screen_info.h> #include <linux/root_dev.h> #include <linux/cpu.h> #include <linux/unistd.h> @@ -98,21 +97,6 @@ int boot_cpu_hwid = -1; int dcache_bsize; int icache_bsize; -/* - * This still seems to be needed... -- paulus - */ -struct screen_info screen_info = { - .orig_x = 0, - .orig_y = 25, - .orig_video_cols = 80, - .orig_video_lines = 25, - .orig_video_isVGA = 1, - .orig_video_points = 16 -}; -#if defined(CONFIG_FB_VGA16_MODULE) -EXPORT_SYMBOL(screen_info); -#endif - /* Variables required to store legacy IO irq routing */ int of_i8042_kbd_irq; EXPORT_SYMBOL_GPL(of_i8042_kbd_irq); diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h index ea1a10355ce9..3df30dd1c458 100644 --- a/arch/riscv/kernel/image-vars.h +++ b/arch/riscv/kernel/image-vars.h @@ -28,7 +28,9 @@ __efistub__start_kernel = _start_kernel; __efistub__end = _end; __efistub__edata = _edata; __efistub___init_text_end = __init_text_end; +#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) __efistub_screen_info = screen_info; +#endif #endif diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index aac853ae4eb7..0624f44d43ec 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -15,7 +15,6 @@ #include <linux/memblock.h> #include <linux/sched.h> #include <linux/console.h> -#include <linux/screen_info.h> #include <linux/of_fdt.h> #include <linux/sched/task.h> #include <linux/smp.h> @@ -40,17 +39,6 @@ #include "head.h" -#if defined(CONFIG_DUMMY_CONSOLE) || defined(CONFIG_EFI) -struct screen_info screen_info __section(".data") = { - .orig_video_lines = 30, - .orig_video_cols = 80, - .orig_video_mode = 0, - .orig_video_ega_bx = 0, - .orig_video_isVGA = 1, - .orig_video_points = 8 -}; -#endif - /* * The lucky hart to first increment this variable will boot the other cores. * This is used before the kernel initializes the BSS so it can't be in the diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index b3da2757faaf..3d80515298d2 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -7,7 +7,6 @@ * Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2002 - 2010 Paul Mundt */ -#include <linux/screen_info.h> #include <linux/ioport.h> #include <linux/init.h> #include <linux/initrd.h> @@ -69,10 +68,6 @@ EXPORT_SYMBOL(cpu_data); struct sh_machine_vector sh_mv = { .mv_name = "generic", }; EXPORT_SYMBOL(sh_mv); -#ifdef CONFIG_VT -struct screen_info screen_info; -#endif - extern int root_mountflags; #define RAMDISK_IMAGE_START_MASK 0x07FF diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 34ef7febf0d5..e3b72a7b46d3 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -17,7 +17,6 @@ #include <linux/initrd.h> #include <asm/smp.h> #include <linux/user.h> -#include <linux/screen_info.h> #include <linux/delay.h> #include <linux/fs.h> #include <linux/seq_file.h> @@ -51,18 +50,6 @@ #include "kernel.h" -struct screen_info screen_info = { - 0, 0, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig-video-page */ - 0, /* orig-video-mode */ - 128, /* orig-video-cols */ - 0,0,0, /* ega_ax, ega_bx, ega_cx */ - 54, /* orig-video-lines */ - 0, /* orig-video-isVGA */ - 16 /* orig-video-points */ -}; - /* Typing sync at the prom prompt calls the function pointed to by * romvec->pv_synchook which I set to the following function. * This should sync all filesystems and return, for now it just diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 6546ca9d4d3f..6a4797dec34b 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -15,7 +15,6 @@ #include <linux/ptrace.h> #include <asm/smp.h> #include <linux/user.h> -#include <linux/screen_info.h> #include <linux/delay.h> #include <linux/fs.h> #include <linux/seq_file.h> @@ -68,18 +67,6 @@ DEFINE_SPINLOCK(ns87303_lock); EXPORT_SYMBOL(ns87303_lock); -struct screen_info screen_info = { - 0, 0, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig-video-page */ - 0, /* orig-video-mode */ - 128, /* orig-video-cols */ - 0, 0, 0, /* unused, ega_bx, unused */ - 54, /* orig-video-lines */ - 0, /* orig-video-isVGA */ - 16 /* orig-video-points */ -}; - static void prom_console_write(struct console *con, const char *s, unsigned int n) { diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 163c35db3d04..1526747bedf2 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1167,7 +1167,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) if (!efi_enabled(EFI_BOOT) || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) - conswitchp = &vga_con; + vgacon_register_screen(&screen_info); #endif #endif x86_init.oem.banner(); diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 52d6e4870a04..bdec4a773af0 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -19,7 +19,6 @@ #include <linux/init.h> #include <linux/mm.h> #include <linux/proc_fs.h> -#include <linux/screen_info.h> #include <linux/kernel.h> #include <linux/percpu.h> #include <linux/reboot.h> @@ -49,17 +48,6 @@ #include <asm/timex.h> #include <asm/traps.h> -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) -struct screen_info screen_info = { - .orig_x = 0, - .orig_y = 24, - .orig_video_cols = 80, - .orig_video_lines = 24, - .orig_video_isVGA = 1, - .orig_video_points = 16, -}; -#endif - #ifdef CONFIG_BLK_DEV_INITRD extern unsigned long initrd_start; extern unsigned long initrd_end; diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c index ef0820f1a924..d4987d013080 100644 --- a/drivers/firmware/efi/efi-init.c +++ b/drivers/firmware/efi/efi-init.c @@ -55,6 +55,15 @@ static phys_addr_t __init efi_to_phys(unsigned long addr) extern __weak const efi_config_table_type_t efi_arch_tables[]; +/* + * x86 defines its own screen_info and uses it even without EFI, + * everything else can get it from here. + */ +#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)) +struct screen_info screen_info __section(".data"); +EXPORT_SYMBOL_GPL(screen_info); +#endif + static void __init init_screen_info(void) { struct screen_info *si; @@ -240,5 +249,8 @@ void __init efi_init(void) memblock_reserve(data.phys_map & PAGE_MASK, PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK))); - init_screen_info(); + if (IS_ENABLED(CONFIG_X86) || + IS_ENABLED(CONFIG_SYSFB) || + IS_ENABLED(CONFIG_EFI_EARLYCON)) + init_screen_info(); } diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c index 2f1902e5d407..a6c049835190 100644 --- a/drivers/firmware/efi/libstub/efi-stub-entry.c +++ b/drivers/firmware/efi/libstub/efi-stub-entry.c @@ -13,7 +13,13 @@ struct screen_info *alloc_screen_info(void) { if (IS_ENABLED(CONFIG_ARM)) return __alloc_screen_info(); - return (void *)&screen_info + screen_info_offset; + + if (IS_ENABLED(CONFIG_X86) || + IS_ENABLED(CONFIG_EFI_EARLYCON) || + IS_ENABLED(CONFIG_SYSFB)) + return (void *)&screen_info + screen_info_offset; + + return NULL; } /* diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c index 58b0b46a21e6..d511d17c5bdf 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -73,9 +73,10 @@ static int hyperv_setup_vram(struct hyperv_drm_device *hv, struct drm_device *dev = &hv->dev; int ret; - drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, - screen_info.lfb_size, - &hyperv_driver); + if (IS_ENABLED(CONFIG_SYSFB)) + drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, + screen_info.lfb_size, + &hyperv_driver); hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index edbb38f6956b..b33d5abd9beb 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -2100,8 +2100,10 @@ static void __maybe_unused vmbus_reserve_fb(void) if (efi_enabled(EFI_BOOT)) { /* Gen2 VM: get FB base from EFI framebuffer */ - start = screen_info.lfb_base; - size = max_t(__u32, screen_info.lfb_size, 0x800000); + if (IS_ENABLED(CONFIG_SYSFB)) { + start = screen_info.lfb_base; + size = max_t(__u32, screen_info.lfb_size, 0x800000); + } } else { /* Gen1 VM: get FB base from PCI */ pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 98764e740c07..34c01874f45b 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -377,18 +377,21 @@ void xen_console_resume(void) #ifdef CONFIG_HVC_XEN_FRONTEND static void xencons_disconnect_backend(struct xencons_info *info) { - if (info->irq > 0) - unbind_from_irqhandler(info->irq, NULL); - info->irq = 0; + if (info->hvc != NULL) + hvc_remove(info->hvc); + info->hvc = NULL; + if (info->irq > 0) { + evtchn_put(info->evtchn); + info->irq = 0; + info->evtchn = 0; + } + /* evtchn_put() will also close it so this is only an error path */ if (info->evtchn > 0) xenbus_free_evtchn(info->xbdev, info->evtchn); info->evtchn = 0; if (info->gntref > 0) gnttab_free_grant_references(info->gntref); info->gntref = 0; - if (info->hvc != NULL) - hvc_remove(info->hvc); - info->hvc = NULL; } static void xencons_free(struct xencons_info *info) @@ -433,7 +436,7 @@ static int xencons_connect_backend(struct xenbus_device *dev, if (ret) return ret; info->evtchn = evtchn; - irq = bind_interdomain_evtchn_to_irq_lateeoi(dev, evtchn); + irq = bind_evtchn_to_irq_lateeoi(evtchn); if (irq < 0) return irq; info->irq = irq; @@ -553,10 +556,23 @@ static void xencons_backend_changed(struct xenbus_device *dev, if (dev->state == XenbusStateClosed) break; fallthrough; /* Missed the backend's CLOSING state */ - case XenbusStateClosing: + case XenbusStateClosing: { + struct xencons_info *info = dev_get_drvdata(&dev->dev);; + + /* + * Don't tear down the evtchn and grant ref before the other + * end has disconnected, but do stop userspace from trying + * to use the device before we allow the backend to close. + */ + if (info->hvc) { + hvc_remove(info->hvc); + info->hvc = NULL; + } + xenbus_frontend_closed(dev); break; } + } } static const struct xenbus_device_id xencons_ids[] = { @@ -588,7 +604,7 @@ static int __init xen_hvc_init(void) ops = &dom0_hvc_ops; r = xen_initial_domain_console_init(); if (r < 0) - return r; + goto register_fe; info = vtermno_to_xencons(HVC_COOKIE); } else { ops = &domU_hvc_ops; @@ -597,7 +613,7 @@ static int __init xen_hvc_init(void) else r = xen_pv_console_init(); if (r < 0) - return r; + goto register_fe; info = vtermno_to_xencons(HVC_COOKIE); info->irq = bind_evtchn_to_irq_lateeoi(info->evtchn); @@ -616,12 +632,13 @@ static int __init xen_hvc_init(void) list_del(&info->list); spin_unlock_irqrestore(&xencons_lock, flags); if (info->irq) - unbind_from_irqhandler(info->irq, NULL); + evtchn_put(info->evtchn); kfree(info); return r; } r = 0; + register_fe: #ifdef CONFIG_HVC_XEN_FRONTEND r = xenbus_register_frontend(&xencons_driver); #endif diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 98433a53bae1..f57fd9095f75 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -664,7 +664,6 @@ static void hvcs_return_index(int index) static void hvcs_destruct_port(struct tty_port *p) { struct hvcs_struct *hvcsd = container_of(p, struct hvcs_struct, port); - struct vio_dev *vdev; struct completion *comp; unsigned long flags; @@ -686,7 +685,6 @@ static void hvcs_destruct_port(struct tty_port *p) printk(KERN_INFO "HVCS: Destroyed hvcs_struct for vty-server@%X.\n", hvcsd->vdev->unit_address); - vdev = hvcsd->vdev; hvcsd->vdev = NULL; hvcsd->p_unit_address = 0; diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 10aa4ed38793..6ce7f259968f 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -288,7 +288,7 @@ struct mxser_board { enum mxser_must_hwid must_hwid; speed_t max_baud; - struct mxser_port ports[]; + struct mxser_port ports[] __counted_by(nports); }; static DECLARE_BITMAP(mxser_boards, MXSER_BOARDS); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 1f3aba607cd5..a3ab3946e4ad 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2,6 +2,7 @@ /* * n_gsm.c GSM 0710 tty multiplexor * Copyright (c) 2009/10 Intel Corporation + * Copyright (c) 2022/23 Siemens Mobility GmbH * * * THIS IS A DEVELOPMENT SNAPSHOT IT IS NOT A FINAL RELEASE * * @@ -4108,6 +4109,8 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk) static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk) { + if (dlci->gsm->dead) + return -EL2HLT; if (dlci->adaption == 2) { /* Send convergence layer type 2 empty data frame. */ gsm_modem_upd_via_data(dlci, brk); diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 6c9a408d67cd..f252d0b5a434 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -249,15 +249,12 @@ static void n_tty_check_throttle(struct tty_struct *tty) if (ldata->icanon && ldata->canon_head == ldata->read_tail) return; - while (1) { - int throttled; + do { tty_set_flow_change(tty, TTY_THROTTLE_SAFE); if (N_TTY_BUF_SIZE - read_cnt(ldata) >= TTY_THRESHOLD_THROTTLE) break; - throttled = tty_throttle_safe(tty); - if (!throttled) - break; - } + } while (!tty_throttle_safe(tty)); + __tty_set_flow_change(tty, 0); } @@ -279,16 +276,14 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) * we won't get any more characters. */ - while (1) { - int unthrottled; + do { tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE); if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) break; + n_tty_kick_worker(tty); - unthrottled = tty_unthrottle_safe(tty); - if (!unthrottled) - break; - } + } while (!tty_unthrottle_safe(tty)); + __tty_set_flow_change(tty, 0); } @@ -1965,26 +1960,27 @@ static bool copy_from_read_buf(const struct tty_struct *tty, u8 **kbp, size_t head = smp_load_acquire(&ldata->commit_head); size_t tail = MASK(ldata->read_tail); - n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail); - n = min(*nr, n); - if (n) { - u8 *from = read_buf_addr(ldata, tail); - memcpy(*kbp, from, n); - is_eof = n == 1 && *from == EOF_CHAR(tty); - tty_audit_add_data(tty, from, n); - zero_buffer(tty, from, n); - smp_store_release(&ldata->read_tail, ldata->read_tail + n); - /* Turn single EOF into zero-length read */ - if (L_EXTPROC(tty) && ldata->icanon && is_eof && - (head == ldata->read_tail)) - return false; - *kbp += n; - *nr -= n; - - /* If we have more to copy, let the caller know */ - return head != ldata->read_tail; - } - return false; + n = min3(head - ldata->read_tail, N_TTY_BUF_SIZE - tail, *nr); + if (!n) + return false; + + u8 *from = read_buf_addr(ldata, tail); + memcpy(*kbp, from, n); + is_eof = n == 1 && *from == EOF_CHAR(tty); + tty_audit_add_data(tty, from, n); + zero_buffer(tty, from, n); + smp_store_release(&ldata->read_tail, ldata->read_tail + n); + + /* Turn single EOF into zero-length read */ + if (L_EXTPROC(tty) && ldata->icanon && is_eof && + head == ldata->read_tail) + return false; + + *kbp += n; + *nr -= n; + + /* If we have more to copy, let the caller know */ + return head != ldata->read_tail; } /** @@ -2154,9 +2150,8 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf, struct n_tty_data *ldata = tty->disc_data; u8 *kb = kbuf; DEFINE_WAIT_FUNC(wait, woken_wake_function); - int c; int minimum, time; - ssize_t retval = 0; + ssize_t retval; long timeout; bool packet; size_t old_tail; @@ -2192,9 +2187,9 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf, return kb - kbuf; } - c = job_control(tty, file); - if (c < 0) - return c; + retval = job_control(tty, file); + if (retval < 0) + return retval; /* * Internal serialization of reads. @@ -2499,7 +2494,7 @@ static int n_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct n_tty_data *ldata = tty->disc_data; - int retval; + unsigned int num; switch (cmd) { case TIOCOUTQ: @@ -2507,11 +2502,11 @@ static int n_tty_ioctl(struct tty_struct *tty, unsigned int cmd, case TIOCINQ: down_write(&tty->termios_rwsem); if (L_ICANON(tty) && !L_EXTPROC(tty)) - retval = inq_canon(ldata); + num = inq_canon(ldata); else - retval = read_cnt(ldata); + num = read_cnt(ldata); up_write(&tty->termios_rwsem); - return put_user(retval, (unsigned int __user *) arg); + return put_user(num, (unsigned int __user *) arg); default: return n_tty_ioctl_helper(tty, cmd, arg); } diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index e7d663901c07..a5fdaf5e148e 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -15,9 +15,11 @@ #include <linux/of_device.h> #include <linux/pm_domain.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/sched.h> #include <linux/serdev.h> #include <linux/slab.h> + #include <linux/platform_data/x86/apple.h> static bool is_registered; @@ -185,30 +187,20 @@ void serdev_device_close(struct serdev_device *serdev) } EXPORT_SYMBOL_GPL(serdev_device_close); -static void devm_serdev_device_release(struct device *dev, void *dr) +static void devm_serdev_device_close(void *serdev) { - serdev_device_close(*(struct serdev_device **)dr); + serdev_device_close(serdev); } int devm_serdev_device_open(struct device *dev, struct serdev_device *serdev) { - struct serdev_device **dr; int ret; - dr = devres_alloc(devm_serdev_device_release, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - ret = serdev_device_open(serdev); - if (ret) { - devres_free(dr); + if (ret) return ret; - } - - *dr = serdev; - devres_add(dev, dr); - return 0; + return devm_add_action_or_reset(dev, devm_serdev_device_close, serdev); } EXPORT_SYMBOL_GPL(devm_serdev_device_open); @@ -510,7 +502,7 @@ struct serdev_controller *serdev_controller_alloc(struct device *parent, ctrl->dev.type = &serdev_ctrl_type; ctrl->dev.bus = &serdev_bus_type; ctrl->dev.parent = parent; - ctrl->dev.of_node = parent->of_node; + device_set_node(&ctrl->dev, dev_fwnode(parent)); serdev_controller_set_drvdata(ctrl, &ctrl[1]); dev_set_name(&ctrl->dev, "serial%d", id); @@ -673,7 +665,7 @@ static int acpi_serdev_check_resources(struct serdev_controller *ctrl, acpi_get_parent(adev->handle, &lookup.controller_handle); /* Make sure controller and ResourceSource handle match */ - if (ACPI_HANDLE(ctrl->dev.parent) != lookup.controller_handle) + if (!device_match_acpi_handle(ctrl->dev.parent, lookup.controller_handle)) return -ENODEV; return 0; diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index d756fcc884cb..4de0c975ebdc 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -185,14 +185,14 @@ static void serial21285_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int h_lcr; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); h_lcr = *CSR_H_UBRLCR; if (break_state) h_lcr |= H_UBRLCR_BREAK; else h_lcr &= ~H_UBRLCR_BREAK; *CSR_H_UBRLCR = h_lcr; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int serial21285_startup(struct uart_port *port) @@ -272,7 +272,7 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, if (port->fifosize) h_lcr |= H_UBRLCR_FIFO; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Update the per-port timeout. @@ -309,7 +309,7 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, *CSR_H_UBRLCR = h_lcr; *CSR_UARTCON = 1; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *serial21285_type(struct uart_port *port) diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 4a9e71b2dbbc..d7482ae33a1c 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -34,7 +34,6 @@ struct aspeed_vuart { struct device *dev; - struct clk *clk; int line; struct timer_list unthrottle_timer; struct uart_8250_port *port; @@ -288,9 +287,9 @@ static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle) struct uart_8250_port *up = up_to_u8250p(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); __aspeed_vuart_set_throttle(up, throttle); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void aspeed_vuart_throttle(struct uart_port *port) @@ -340,7 +339,7 @@ static int aspeed_vuart_handle_irq(struct uart_port *port) if (iir & UART_IIR_NO_INT) return 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); lsr = serial_port_in(port, UART_LSR); @@ -415,12 +414,14 @@ static int aspeed_vuart_map_irq_polarity(u32 dt) static int aspeed_vuart_probe(struct platform_device *pdev) { struct of_phandle_args sirq_polarity_sense_args; + struct device *dev = &pdev->dev; struct uart_8250_port port; struct aspeed_vuart *vuart; struct device_node *np; struct resource *res; u32 clk, prop, sirq[2]; int rc, sirq_polarity; + struct clk *vclk; np = pdev->dev.of_node; @@ -453,19 +454,13 @@ static int aspeed_vuart_probe(struct platform_device *pdev) return rc; if (of_property_read_u32(np, "clock-frequency", &clk)) { - vuart->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(vuart->clk)) { - dev_warn(&pdev->dev, - "clk or clock-frequency not defined\n"); - rc = PTR_ERR(vuart->clk); + vclk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(vclk)) { + rc = dev_err_probe(dev, PTR_ERR(vclk), "clk or clock-frequency not defined\n"); goto err_sysfs_remove; } - rc = clk_prepare_enable(vuart->clk); - if (rc < 0) - goto err_sysfs_remove; - - clk = clk_get_rate(vuart->clk); + clk = clk_get_rate(vclk); } /* If current-speed was set, then try not to change it. */ @@ -533,7 +528,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev) rc = aspeed_vuart_set_lpc_address(vuart, prop); if (rc < 0) { - dev_err(&pdev->dev, "invalid value in aspeed,lpc-io-reg property\n"); + dev_err_probe(dev, rc, "invalid value in aspeed,lpc-io-reg property\n"); goto err_clk_disable; } @@ -545,14 +540,14 @@ static int aspeed_vuart_probe(struct platform_device *pdev) rc = aspeed_vuart_set_sirq(vuart, sirq[0]); if (rc < 0) { - dev_err(&pdev->dev, "invalid sirq number in aspeed,lpc-interrupts property\n"); + dev_err_probe(dev, rc, "invalid sirq number in aspeed,lpc-interrupts property\n"); goto err_clk_disable; } sirq_polarity = aspeed_vuart_map_irq_polarity(sirq[1]); if (sirq_polarity < 0) { - dev_err(&pdev->dev, "invalid sirq polarity in aspeed,lpc-interrupts property\n"); - rc = sirq_polarity; + rc = dev_err_probe(dev, sirq_polarity, + "invalid sirq polarity in aspeed,lpc-interrupts property\n"); goto err_clk_disable; } @@ -565,7 +560,6 @@ static int aspeed_vuart_probe(struct platform_device *pdev) return 0; err_clk_disable: - clk_disable_unprepare(vuart->clk); irq_dispose_mapping(port.port.irq); err_sysfs_remove: sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); @@ -580,7 +574,6 @@ static int aspeed_vuart_remove(struct platform_device *pdev) aspeed_vuart_set_enabled(vuart, false); serial8250_unregister_port(vuart->line); sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); - clk_disable_unprepare(vuart->clk); return 0; } diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index aa5aff046756..55dea2539c47 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -567,7 +567,7 @@ static irqreturn_t brcmuart_isr(int irq, void *dev_id) if (interrupts == 0) return IRQ_NONE; - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); /* Clear all interrupts */ udma_writel(priv, REGS_DMA_ISR, UDMA_INTR_CLEAR, interrupts); @@ -581,7 +581,7 @@ static irqreturn_t brcmuart_isr(int irq, void *dev_id) if ((rval | tval) == 0) dev_warn(dev, "Spurious interrupt: 0x%x\n", interrupts); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); return IRQ_HANDLED; } @@ -608,10 +608,10 @@ static int brcmuart_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); up->ier &= ~UART_IER_RDI; serial_port_out(port, UART_IER, up->ier); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); priv->tx_running = false; priv->dma.rx_dma = NULL; @@ -629,7 +629,7 @@ static void brcmuart_shutdown(struct uart_port *port) struct brcmuart_priv *priv = up->port.private_data; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); priv->shutdown = true; if (priv->dma_enabled) { stop_rx_dma(up); @@ -645,7 +645,7 @@ static void brcmuart_shutdown(struct uart_port *port) */ up->dma = NULL; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_do_shutdown(port); } @@ -788,7 +788,7 @@ static int brcmuart_handle_irq(struct uart_port *p) * interrupt but there is no data ready. */ if (((iir & UART_IIR_ID) == UART_IIR_RX_TIMEOUT) && !(priv->shutdown)) { - spin_lock_irqsave(&p->lock, flags); + uart_port_lock_irqsave(p, &flags); status = serial_port_in(p, UART_LSR); if ((status & UART_LSR_DR) == 0) { @@ -813,7 +813,7 @@ static int brcmuart_handle_irq(struct uart_port *p) handled = 1; } - spin_unlock_irqrestore(&p->lock, flags); + uart_port_unlock_irqrestore(p, flags); if (handled) return 1; } @@ -831,7 +831,7 @@ static enum hrtimer_restart brcmuart_hrtimer_func(struct hrtimer *t) if (priv->shutdown) return HRTIMER_NORESTART; - spin_lock_irqsave(&p->lock, flags); + uart_port_lock_irqsave(p, &flags); status = serial_port_in(p, UART_LSR); /* @@ -855,7 +855,7 @@ static enum hrtimer_restart brcmuart_hrtimer_func(struct hrtimer *t) status |= UART_MCR_RTS; serial_port_out(p, UART_MCR, status); } - spin_unlock_irqrestore(&p->lock, flags); + uart_port_unlock_irqrestore(p, flags); return HRTIMER_NORESTART; } @@ -984,10 +984,9 @@ static int brcmuart_probe(struct platform_device *pdev) } /* We should have just the uart base registers or all the registers */ - if (x != 1 && x != REGS_MAX) { - dev_warn(dev, "%s registers not specified\n", reg_names[x]); - return -EINVAL; - } + if (x != 1 && x != REGS_MAX) + return dev_err_probe(dev, -EINVAL, "%s registers not specified\n", + reg_names[x]); /* if the DMA registers were specified, try to enable DMA */ if (x > REGS_DMA_RX) { @@ -1016,27 +1015,23 @@ static int brcmuart_probe(struct platform_device *pdev) of_property_read_u32(np, "clock-frequency", &clk_rate); /* See if a Baud clock has been specified */ - baud_mux_clk = devm_clk_get(dev, "sw_baud"); - if (IS_ERR(baud_mux_clk)) { - if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; - goto release_dma; - } - dev_dbg(dev, "BAUD MUX clock not specified\n"); - } else { + baud_mux_clk = devm_clk_get_optional_enabled(dev, "sw_baud"); + ret = PTR_ERR_OR_ZERO(baud_mux_clk); + if (ret) + goto release_dma; + if (baud_mux_clk) { dev_dbg(dev, "BAUD MUX clock found\n"); - ret = clk_prepare_enable(baud_mux_clk); - if (ret) - goto release_dma; + priv->baud_mux_clk = baud_mux_clk; init_real_clk_rates(dev, priv); clk_rate = priv->default_mux_rate; + } else { + dev_dbg(dev, "BAUD MUX clock not specified\n"); } if (clk_rate == 0) { - dev_err(dev, "clock-frequency or clk not defined\n"); - ret = -EINVAL; - goto err_clk_disable; + ret = dev_err_probe(dev, -EINVAL, "clock-frequency or clk not defined\n"); + goto release_dma; } dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not "); @@ -1093,7 +1088,7 @@ static int brcmuart_probe(struct platform_device *pdev) ret = serial8250_register_8250_port(&up); if (ret < 0) { - dev_err(dev, "unable to register 8250 port\n"); + dev_err_probe(dev, ret, "unable to register 8250 port\n"); goto err; } priv->line = ret; @@ -1102,14 +1097,13 @@ static int brcmuart_probe(struct platform_device *pdev) if (priv->dma_enabled) { dma_irq = platform_get_irq_byname(pdev, "dma"); if (dma_irq < 0) { - ret = dma_irq; - dev_err(dev, "no IRQ resource info\n"); + ret = dev_err_probe(dev, dma_irq, "no IRQ resource info\n"); goto err1; } ret = devm_request_irq(dev, dma_irq, brcmuart_isr, IRQF_SHARED, "uart DMA irq", &new_port->port); if (ret) { - dev_err(dev, "unable to register IRQ handler\n"); + dev_err_probe(dev, ret, "unable to register IRQ handler\n"); goto err1; } } @@ -1121,8 +1115,6 @@ err1: serial8250_unregister_port(priv->line); err: brcmuart_free_bufs(dev, priv); -err_clk_disable: - clk_disable_unprepare(baud_mux_clk); release_dma: if (priv->dma_enabled) brcmuart_arbitration(priv, 0); @@ -1137,7 +1129,6 @@ static int brcmuart_remove(struct platform_device *pdev) hrtimer_cancel(&priv->hrt); serial8250_unregister_port(priv->line); brcmuart_free_bufs(&pdev->dev, priv); - clk_disable_unprepare(priv->baud_mux_clk); if (priv->dma_enabled) brcmuart_arbitration(priv, 0); return 0; @@ -1154,10 +1145,10 @@ static int __maybe_unused brcmuart_suspend(struct device *dev) * This will prevent resume from enabling RTS before the * baud rate has been restored. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); priv->saved_mctrl = port->mctrl; port->mctrl &= ~TIOCM_RTS; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_suspend_port(priv->line); clk_disable_unprepare(priv->baud_mux_clk); @@ -1196,10 +1187,10 @@ static int __maybe_unused brcmuart_resume(struct device *dev) if (priv->saved_mctrl & TIOCM_RTS) { /* Restore RTS */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->mctrl |= TIOCM_RTS; port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } return 0; diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 3449f8790e46..912733151858 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -259,7 +259,7 @@ static void serial8250_backup_timeout(struct timer_list *t) unsigned int iir, ier = 0, lsr; unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Must disable interrupts or else we risk racing with the interrupt @@ -292,7 +292,7 @@ static void serial8250_backup_timeout(struct timer_list *t) if (up->port.irq) serial_out(up, UART_IER, ier); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* Standard timer interval plus 0.2s to keep the port running */ mod_timer(&up->timer, @@ -611,7 +611,7 @@ static int univ8250_console_setup(struct console *co, char *options) * if so, search for the first available port that does have * console support. */ - if (co->index >= UART_NR) + if (co->index < 0 || co->index >= UART_NR) co->index = 0; /* @@ -992,11 +992,11 @@ static void serial_8250_overrun_backoff_work(struct work_struct *work) struct uart_port *port = &up->port; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->ier |= UART_IER_RLSI | UART_IER_RDI; up->port.read_status_mask |= UART_LSR_DR; serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /** @@ -1194,9 +1194,9 @@ void serial8250_unregister_port(int line) if (uart->em485) { unsigned long flags; - spin_lock_irqsave(&uart->port.lock, flags); + uart_port_lock_irqsave(&uart->port, &flags); serial8250_em485_destroy(uart); - spin_unlock_irqrestore(&uart->port.lock, flags); + uart_port_unlock_irqrestore(&uart->port, flags); } uart_remove_one_port(&serial8250_reg, &uart->port); diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index 7fa66501792d..8b30ca8fdd3f 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -22,7 +22,7 @@ static void __dma_tx_complete(void *param) dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); dma->tx_running = 0; @@ -35,7 +35,7 @@ static void __dma_tx_complete(void *param) if (ret || !dma->tx_running) serial8250_set_THRI(p); - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); } static void __dma_rx_complete(struct uart_8250_port *p) @@ -70,7 +70,7 @@ static void dma_rx_complete(void *param) struct uart_8250_dma *dma = p->dma; unsigned long flags; - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); if (dma->rx_running) __dma_rx_complete(p); @@ -80,7 +80,7 @@ static void dma_rx_complete(void *param) */ if (!dma->rx_running && (serial_lsr_in(p) & UART_LSR_DR)) p->dma->rx_dma(p); - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); } int serial8250_tx_dma(struct uart_8250_port *p) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index f4cafca1a7da..b94f567647cb 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -263,20 +263,20 @@ static int dw8250_handle_irq(struct uart_port *p) * so we limit the workaround only to non-DMA mode. */ if (!up->dma && rx_timeout) { - spin_lock_irqsave(&p->lock, flags); + uart_port_lock_irqsave(p, &flags); status = serial_lsr_in(up); if (!(status & (UART_LSR_DR | UART_LSR_BI))) (void) p->serial_in(p, UART_RX); - spin_unlock_irqrestore(&p->lock, flags); + uart_port_unlock_irqrestore(p, flags); } /* Manually stop the Rx DMA transfer when acting as flow controller */ if (quirks & DW_UART_QUIRK_IS_DMA_FC && up->dma && up->dma->rx_running && rx_timeout) { - spin_lock_irqsave(&p->lock, flags); + uart_port_lock_irqsave(p, &flags); status = serial_lsr_in(up); - spin_unlock_irqrestore(&p->lock, flags); + uart_port_unlock_irqrestore(p, flags); if (status & (UART_LSR_DR | UART_LSR_BI)) { dw8250_writel_ext(p, RZN1_UART_RDMACR, 0); @@ -498,11 +498,6 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) } } -static void dw8250_clk_disable_unprepare(void *data) -{ - clk_disable_unprepare(data); -} - static void dw8250_reset_control_assert(void *data) { reset_control_assert(data); @@ -598,23 +593,15 @@ static int dw8250_probe(struct platform_device *pdev) device_property_read_u32(dev, "clock-frequency", &p->uartclk); /* If there is separate baudclk, get the rate from it. */ - data->clk = devm_clk_get_optional(dev, "baudclk"); + data->clk = devm_clk_get_optional_enabled(dev, "baudclk"); if (data->clk == NULL) - data->clk = devm_clk_get_optional(dev, NULL); + data->clk = devm_clk_get_optional_enabled(dev, NULL); if (IS_ERR(data->clk)) return PTR_ERR(data->clk); INIT_WORK(&data->clk_work, dw8250_clk_work_cb); data->clk_notifier.notifier_call = dw8250_clk_notifier_cb; - err = clk_prepare_enable(data->clk); - if (err) - return dev_err_probe(dev, err, "could not enable optional baudclk\n"); - - err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->clk); - if (err) - return err; - if (data->clk) p->uartclk = clk_get_rate(data->clk); @@ -622,18 +609,10 @@ static int dw8250_probe(struct platform_device *pdev) if (!p->uartclk) return dev_err_probe(dev, -EINVAL, "clock rate not defined\n"); - data->pclk = devm_clk_get_optional(dev, "apb_pclk"); + data->pclk = devm_clk_get_optional_enabled(dev, "apb_pclk"); if (IS_ERR(data->pclk)) return PTR_ERR(data->pclk); - err = clk_prepare_enable(data->pclk); - if (err) - return dev_err_probe(dev, err, "could not enable apb_pclk\n"); - - err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->pclk); - if (err) - return err; - data->rst = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(data->rst)) return PTR_ERR(data->rst); diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 077c3ba3539e..6085d356ad86 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -18,7 +18,6 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/tty.h> -#include <linux/8250_pci.h> #include <linux/delay.h> #include <asm/byteorder.h> @@ -47,12 +46,6 @@ #define PCI_SUBDEVICE_ID_USR_2980 0x0128 #define PCI_SUBDEVICE_ID_USR_2981 0x0129 -#define PCI_DEVICE_ID_SEALEVEL_710xC 0x1001 -#define PCI_DEVICE_ID_SEALEVEL_720xC 0x1002 -#define PCI_DEVICE_ID_SEALEVEL_740xC 0x1004 -#define PCI_DEVICE_ID_SEALEVEL_780xC 0x1008 -#define PCI_DEVICE_ID_SEALEVEL_716xC 0x1010 - #define UART_EXAR_INT0 0x80 #define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */ #define UART_EXAR_SLEEP 0x8b /* Sleep mode */ @@ -84,6 +77,9 @@ #define UART_EXAR_RS485_DLY(x) ((x) << 4) +#define UART_EXAR_DLD 0x02 /* Divisor Fractional */ +#define UART_EXAR_DLD_485_POLARITY 0x80 /* RS-485 Enable Signal Polarity */ + /* * IOT2040 MPIO wiring semantics: * @@ -201,9 +197,9 @@ static int xr17v35x_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial_port_out(port, UART_IER, 0); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); return serial8250_do_startup(port); } @@ -445,6 +441,44 @@ static int generic_rs485_config(struct uart_port *port, struct ktermios *termios return 0; } +static int sealevel_rs485_config(struct uart_port *port, struct ktermios *termios, + struct serial_rs485 *rs485) +{ + u8 __iomem *p = port->membase; + u8 old_lcr; + u8 efr; + u8 dld; + int ret; + + ret = generic_rs485_config(port, termios, rs485); + if (ret) + return ret; + + if (rs485->flags & SER_RS485_ENABLED) { + old_lcr = readb(p + UART_LCR); + + /* Set EFR[4]=1 to enable enhanced feature registers */ + efr = readb(p + UART_XR_EFR); + efr |= UART_EFR_ECB; + writeb(efr, p + UART_XR_EFR); + + /* Set MCR to use DTR as Auto-RS485 Enable signal */ + writeb(UART_MCR_OUT1, p + UART_MCR); + + /* Set LCR[7]=1 to enable access to DLD register */ + writeb(old_lcr | UART_LCR_DLAB, p + UART_LCR); + + /* Set DLD[7]=1 for inverted RS485 Enable logic */ + dld = readb(p + UART_EXAR_DLD); + dld |= UART_EXAR_DLD_485_POLARITY; + writeb(dld, p + UART_EXAR_DLD); + + writeb(old_lcr, p + UART_LCR); + } + + return 0; +} + static const struct serial_rs485 generic_rs485_supported = { .flags = SER_RS485_ENABLED, }; @@ -566,6 +600,9 @@ pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev, port->port.rs485_config = platform->rs485_config; port->port.rs485_supported = *(platform->rs485_supported); + if (pcidev->subsystem_vendor == PCI_VENDOR_ID_SEALEVEL) + port->port.rs485_config = sealevel_rs485_config; + /* * Setup the UART clock for the devices on expansion slot to * half the clock speed of the main chip (which is 125MHz) @@ -652,8 +689,6 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) nr_ports = BIT(((pcidev->device & 0x38) >> 3) - 1); else if (board->num_ports) nr_ports = board->num_ports; - else if (pcidev->vendor == PCI_VENDOR_ID_SEALEVEL) - nr_ports = pcidev->device & 0xff; else nr_ports = pcidev->device & 0x0f; @@ -893,12 +928,6 @@ static const struct pci_device_id exar_pci_tbl[] = { EXAR_DEVICE(COMMTECH, 4224PCI335, pbn_fastcom335_4), EXAR_DEVICE(COMMTECH, 2324PCI335, pbn_fastcom335_4), EXAR_DEVICE(COMMTECH, 2328PCI335, pbn_fastcom335_8), - - EXAR_DEVICE(SEALEVEL, 710xC, pbn_exar_XR17V35x), - EXAR_DEVICE(SEALEVEL, 720xC, pbn_exar_XR17V35x), - EXAR_DEVICE(SEALEVEL, 740xC, pbn_exar_XR17V35x), - EXAR_DEVICE(SEALEVEL, 780xC, pbn_exar_XR17V35x), - EXAR_DEVICE(SEALEVEL, 716xC, pbn_exar_XR17V35x), { 0, } }; MODULE_DEVICE_TABLE(pci, exar_pci_tbl); diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index 6af4e1c1210a..f522eb5026c9 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -30,11 +30,11 @@ int fsl8250_handle_irq(struct uart_port *port) unsigned int iir; struct uart_8250_port *up = up_to_u8250p(port); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); iir = port->serial_in(port, UART_IIR); if (iir & UART_IIR_NO_INT) { - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } @@ -54,7 +54,7 @@ int fsl8250_handle_irq(struct uart_port *port) if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) { up->lsr_saved_flags &= ~UART_LSR_BI; port->serial_in(port, UART_RX); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 1; } diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index 2cc78a4bf7a1..8ec03863606e 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c @@ -12,7 +12,6 @@ #include <linux/rational.h> #include <linux/dma/hsu.h> -#include <linux/8250_pci.h> #include "8250.h" @@ -32,9 +31,9 @@ struct mid8250; struct mid8250_board { - unsigned int flags; unsigned long freq; unsigned int base_baud; + unsigned int bar; int (*setup)(struct mid8250 *, struct uart_port *p); void (*exit)(struct mid8250 *); }; @@ -169,7 +168,6 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p) { struct hsu_dma_chip *chip = &mid->dma_chip; struct pci_dev *pdev = to_pci_dev(p->dev); - unsigned int bar = FL_GET_BASE(mid->board->flags); int ret; pci_set_master(pdev); @@ -183,7 +181,7 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p) chip->dev = &pdev->dev; chip->irq = pci_irq_vector(pdev, 0); chip->regs = p->membase; - chip->length = pci_resource_len(pdev, bar); + chip->length = pci_resource_len(pdev, mid->board->bar); chip->offset = DNV_DMA_CHAN_OFFSET; /* Falling back to PIO mode if DMA probing fails */ @@ -291,7 +289,6 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct uart_8250_port uart; struct mid8250 *mid; - unsigned int bar; int ret; ret = pcim_enable_device(pdev); @@ -303,7 +300,6 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM; mid->board = (struct mid8250_board *)id->driver_data; - bar = FL_GET_BASE(mid->board->flags); memset(&uart, 0, sizeof(struct uart_8250_port)); @@ -316,8 +312,8 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE; uart.port.set_termios = mid8250_set_termios; - uart.port.mapbase = pci_resource_start(pdev, bar); - uart.port.membase = pcim_iomap(pdev, bar, 0); + uart.port.mapbase = pci_resource_start(pdev, mid->board->bar); + uart.port.membase = pcim_iomap(pdev, mid->board->bar, 0); if (!uart.port.membase) return -ENOMEM; @@ -353,25 +349,25 @@ static void mid8250_remove(struct pci_dev *pdev) } static const struct mid8250_board pnw_board = { - .flags = FL_BASE0, .freq = 50000000, .base_baud = 115200, + .bar = 0, .setup = pnw_setup, .exit = pnw_exit, }; static const struct mid8250_board tng_board = { - .flags = FL_BASE0, .freq = 38400000, .base_baud = 1843200, + .bar = 0, .setup = tng_setup, .exit = tng_exit, }; static const struct mid8250_board dnv_board = { - .flags = FL_BASE1, .freq = 133333333, .base_baud = 115200, + .bar = 1, .setup = dnv_setup, .exit = dnv_exit, }; diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 74da5676ce67..23457daae8a1 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -102,7 +102,7 @@ static void mtk8250_dma_rx_complete(void *param) if (data->rx_status == DMA_RX_SHUTDOWN) return; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); total = dma->rx_size - state.residue; @@ -128,7 +128,7 @@ static void mtk8250_dma_rx_complete(void *param) mtk8250_rx_dma(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void mtk8250_rx_dma(struct uart_8250_port *up) @@ -368,7 +368,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Update the per-port timeout. @@ -416,7 +416,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, if (uart_console(port)) up->port.cons->cflag = termios->c_cflag; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index 51329625c48a..ef3e745bd09c 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -33,7 +33,8 @@ static int of_platform_serial_setup(struct platform_device *ofdev, struct of_serial_info *info) { struct resource resource; - struct device_node *np = ofdev->dev.of_node; + struct device *dev = &ofdev->dev; + struct device_node *np = dev->of_node; struct uart_port *port = &up->port; u32 clk, spd, prop; int ret, irq; @@ -46,19 +47,12 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (of_property_read_u32(np, "clock-frequency", &clk)) { /* Get clk rate through clk driver if present */ - info->clk = devm_clk_get(&ofdev->dev, NULL); + info->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(info->clk)) { - ret = PTR_ERR(info->clk); - if (ret != -EPROBE_DEFER) - dev_warn(&ofdev->dev, - "failed to get clock: %d\n", ret); + ret = dev_err_probe(dev, PTR_ERR(info->clk), "failed to get clock\n"); goto err_pmruntime; } - ret = clk_prepare_enable(info->clk); - if (ret < 0) - goto err_pmruntime; - clk = clk_get_rate(info->clk); } /* If current-speed was set, then try not to change it. */ @@ -67,8 +61,8 @@ static int of_platform_serial_setup(struct platform_device *ofdev, ret = of_address_to_resource(np, 0, &resource); if (ret) { - dev_warn(&ofdev->dev, "invalid address\n"); - goto err_unprepare; + dev_err_probe(dev, ret, "invalid address\n"); + goto err_pmruntime; } port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | @@ -85,10 +79,9 @@ static int of_platform_serial_setup(struct platform_device *ofdev, /* Check for shifted address mapping */ if (of_property_read_u32(np, "reg-offset", &prop) == 0) { if (prop >= port->mapsize) { - dev_warn(&ofdev->dev, "reg-offset %u exceeds region size %pa\n", - prop, &port->mapsize); - ret = -EINVAL; - goto err_unprepare; + ret = dev_err_probe(dev, -EINVAL, "reg-offset %u exceeds region size %pa\n", + prop, &port->mapsize); + goto err_pmruntime; } port->mapbase += prop; @@ -109,10 +102,9 @@ static int of_platform_serial_setup(struct platform_device *ofdev, UPIO_MEM32BE : UPIO_MEM32; break; default: - dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", - prop); - ret = -EINVAL; - goto err_unprepare; + ret = dev_err_probe(dev, -EINVAL, "unsupported reg-io-width (%u)\n", + prop); + goto err_pmruntime; } } port->flags |= UPF_IOREMAP; @@ -139,7 +131,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (irq < 0) { if (irq == -EPROBE_DEFER) { ret = -EPROBE_DEFER; - goto err_unprepare; + goto err_pmruntime; } /* IRQ support not mandatory */ irq = 0; @@ -150,12 +142,12 @@ static int of_platform_serial_setup(struct platform_device *ofdev, info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL); if (IS_ERR(info->rst)) { ret = PTR_ERR(info->rst); - goto err_unprepare; + goto err_pmruntime; } ret = reset_control_deassert(info->rst); if (ret) - goto err_unprepare; + goto err_pmruntime; port->type = type; port->uartclk = clk; @@ -173,7 +165,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev, case PORT_RT2880: ret = rt288x_setup(port); if (ret) - goto err_unprepare; + goto err_pmruntime; break; } @@ -185,8 +177,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev, } return 0; -err_unprepare: - clk_disable_unprepare(info->clk); err_pmruntime: pm_runtime_put_sync(&ofdev->dev); pm_runtime_disable(&ofdev->dev); @@ -253,7 +243,6 @@ err_dispose: irq_dispose_mapping(port8250.port.irq); pm_runtime_put_sync(&ofdev->dev); pm_runtime_disable(&ofdev->dev); - clk_disable_unprepare(info->clk); err_free: kfree(info); return ret; @@ -271,7 +260,6 @@ static int of_platform_serial_remove(struct platform_device *ofdev) reset_control_assert(info->rst); pm_runtime_put_sync(&ofdev->dev); pm_runtime_disable(&ofdev->dev); - clk_disable_unprepare(info->clk); kfree(info); return 0; } diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index ca972fd37725..2d42f485c987 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -8,6 +8,7 @@ * */ +#include <linux/atomic.h> #include <linux/clk.h> #include <linux/device.h> #include <linux/io.h> @@ -27,6 +28,7 @@ #include <linux/pm_wakeirq.h> #include <linux/dma-mapping.h> #include <linux/sys_soc.h> +#include <linux/pm_domain.h> #include "8250.h" @@ -114,6 +116,12 @@ /* RX FIFO occupancy indicator */ #define UART_OMAP_RX_LVL 0x19 +/* + * Copy of the genpd flags for the console. + * Only used if console suspend is disabled + */ +static unsigned int genpd_flags_console; + struct omap8250_priv { void __iomem *membase; int line; @@ -130,6 +138,7 @@ struct omap8250_priv { u8 tx_trigger; u8 rx_trigger; + atomic_t active; bool is_suspending; int wakeirq; int wakeups_enabled; @@ -401,7 +410,7 @@ static void omap_8250_set_termios(struct uart_port *port, * interrupts disabled. */ pm_runtime_get_sync(port->dev); - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); /* * Update the per-port timeout. @@ -504,7 +513,7 @@ static void omap_8250_set_termios(struct uart_port *port, } omap8250_restore_regs(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); @@ -529,7 +538,7 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state, pm_runtime_get_sync(port->dev); /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); efr = serial_in(up, UART_EFR); @@ -541,7 +550,7 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state, serial_out(up, UART_EFR, efr); serial_out(up, UART_LCR, 0); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); @@ -632,14 +641,23 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) unsigned int iir, lsr; int ret; + pm_runtime_get_noresume(port->dev); + + /* Shallow idle state wake-up to an IO interrupt? */ + if (atomic_add_unless(&priv->active, 1, 1)) { + priv->latency = priv->calc_latency; + schedule_work(&priv->qos_work); + } + #ifdef CONFIG_SERIAL_8250_DMA if (up->dma) { ret = omap_8250_dma_handle_irq(port); + pm_runtime_mark_last_busy(port->dev); + pm_runtime_put(port->dev); return IRQ_RETVAL(ret); } #endif - serial8250_rpm_get(up); lsr = serial_port_in(port, UART_LSR); iir = serial_port_in(port, UART_IIR); ret = serial8250_handle_irq(port, iir); @@ -660,7 +678,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) unsigned long delay; /* Synchronize UART_IER access against the console. */ - spin_lock(&port->lock); + uart_port_lock(port); up->ier = port->serial_in(port, UART_IER); if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { port->ops->stop_rx(port); @@ -670,13 +688,14 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) */ cancel_delayed_work(&up->overrun_backoff); } - spin_unlock(&port->lock); + uart_port_unlock(port); delay = msecs_to_jiffies(up->overrun_backoff_time_ms); schedule_delayed_work(&up->overrun_backoff, delay); } - serial8250_rpm_put(up); + pm_runtime_mark_last_busy(port->dev); + pm_runtime_put(port->dev); return IRQ_RETVAL(ret); } @@ -717,10 +736,10 @@ static int omap_8250_startup(struct uart_port *port) } /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); #ifdef CONFIG_PM up->capabilities |= UART_CAP_RPM; @@ -733,9 +752,9 @@ static int omap_8250_startup(struct uart_port *port) serial_out(up, UART_OMAP_WER, priv->wer); if (up->dma && !(priv->habit & UART_HAS_EFR2)) { - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); up->dma->rx_dma(up); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } enable_irq(up->port.irq); @@ -761,10 +780,10 @@ static void omap_8250_shutdown(struct uart_port *port) serial_out(up, UART_OMAP_EFR2, 0x0); /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); up->ier = 0; serial_out(up, UART_IER, 0); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); disable_irq_nosync(up->port.irq); dev_pm_clear_wake_irq(port->dev); @@ -789,10 +808,10 @@ static void omap_8250_throttle(struct uart_port *port) pm_runtime_get_sync(port->dev); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->ops->stop_rx(port); priv->throttled = true; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); @@ -807,14 +826,14 @@ static void omap_8250_unthrottle(struct uart_port *port) pm_runtime_get_sync(port->dev); /* Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); priv->throttled = false; if (up->dma) up->dma->rx_dma(up); up->ier |= UART_IER_RLSI | UART_IER_RDI; port->read_status_mask |= UART_LSR_DR; serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); @@ -958,7 +977,7 @@ static void __dma_rx_complete(void *param) unsigned long flags; /* Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); /* * If the tx status is not DMA_COMPLETE, then this is a delayed @@ -967,7 +986,7 @@ static void __dma_rx_complete(void *param) */ if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) != DMA_COMPLETE) { - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); return; } __dma_rx_do_complete(p); @@ -978,7 +997,7 @@ static void __dma_rx_complete(void *param) omap_8250_rx_dma(p); } - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); } static void omap_8250_rx_dma_flush(struct uart_8250_port *p) @@ -1083,7 +1102,7 @@ static void omap_8250_dma_tx_complete(void *param) dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); dma->tx_running = 0; @@ -1112,7 +1131,7 @@ static void omap_8250_dma_tx_complete(void *param) serial8250_set_THRI(p); } - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); } static int omap_8250_tx_dma(struct uart_8250_port *p) @@ -1270,15 +1289,12 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) u16 status; u8 iir; - serial8250_rpm_get(up); - iir = serial_port_in(port, UART_IIR); if (iir & UART_IIR_NO_INT) { - serial8250_rpm_put(up); return IRQ_HANDLED; } - spin_lock(&port->lock); + uart_port_lock(port); status = serial_port_in(port, UART_LSR); @@ -1305,7 +1321,6 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) uart_unlock_and_check_sysrq(port); - serial8250_rpm_put(up); return 1; } @@ -1503,8 +1518,6 @@ static int omap8250_probe(struct platform_device *pdev) if (!of_get_available_child_count(pdev->dev.of_node)) pm_runtime_set_autosuspend_delay(&pdev->dev, -1); - pm_runtime_irq_safe(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); omap_serial_fill_features_erratas(&up, priv); @@ -1617,6 +1630,7 @@ static int omap8250_suspend(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); int err = 0; serial8250_suspend_port(priv->line); @@ -1627,8 +1641,19 @@ static int omap8250_suspend(struct device *dev) if (!device_may_wakeup(dev)) priv->wer = 0; serial_out(up, UART_OMAP_WER, priv->wer); - if (uart_console(&up->port) && console_suspend_enabled) - err = pm_runtime_force_suspend(dev); + if (uart_console(&up->port)) { + if (console_suspend_enabled) + err = pm_runtime_force_suspend(dev); + else { + /* + * The pd shall not be powered-off (no console suspend). + * Make copy of genpd flags before to set it always on. + * The original value is restored during the resume. + */ + genpd_flags_console = genpd->flags; + genpd->flags |= GENPD_FLAG_ALWAYS_ON; + } + } flush_work(&priv->qos_work); return err; @@ -1638,12 +1663,16 @@ static int omap8250_resume(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); int err; if (uart_console(&up->port) && console_suspend_enabled) { - err = pm_runtime_force_resume(dev); - if (err) - return err; + if (console_suspend_enabled) { + err = pm_runtime_force_resume(dev); + if (err) + return err; + } else + genpd->flags = genpd_flags_console; } serial8250_resume_port(priv->line); @@ -1743,6 +1772,7 @@ static int omap8250_runtime_suspend(struct device *dev) priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; schedule_work(&priv->qos_work); + atomic_set(&priv->active, 0); return 0; } @@ -1752,23 +1782,29 @@ static int omap8250_runtime_resume(struct device *dev) struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = NULL; + /* Did the hardware wake to a device IO interrupt before a wakeirq? */ + if (atomic_read(&priv->active)) + return 0; + if (priv->line >= 0) up = serial8250_get_port(priv->line); if (up && omap8250_lost_context(up)) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); omap8250_restore_regs(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); omap_8250_rx_dma(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } + atomic_set(&priv->active, 1); priv->latency = priv->calc_latency; schedule_work(&priv->qos_work); + return 0; } diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 62a9bd30b4db..614be0f13a31 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -26,6 +26,84 @@ #include "8250.h" #include "8250_pcilib.h" +#define PCI_VENDOR_ID_SBSMODULARIO 0x124B +#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B +#define PCI_DEVICE_ID_OCTPRO 0x0001 +#define PCI_SUBDEVICE_ID_OCTPRO232 0x0108 +#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 +#define PCI_SUBDEVICE_ID_POCTAL232 0x0308 +#define PCI_SUBDEVICE_ID_POCTAL422 0x0408 +#define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500 +#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 +#define PCI_VENDOR_ID_ADVANTECH 0x13fe +#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 +#define PCI_DEVICE_ID_ADVANTECH_PCI1600 0x1600 +#define PCI_DEVICE_ID_ADVANTECH_PCI1600_1611 0x1611 +#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 +#define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618 +#define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618 +#define PCI_DEVICE_ID_TITAN_200I 0x8028 +#define PCI_DEVICE_ID_TITAN_400I 0x8048 +#define PCI_DEVICE_ID_TITAN_800I 0x8088 +#define PCI_DEVICE_ID_TITAN_800EH 0xA007 +#define PCI_DEVICE_ID_TITAN_800EHB 0xA008 +#define PCI_DEVICE_ID_TITAN_400EH 0xA009 +#define PCI_DEVICE_ID_TITAN_100E 0xA010 +#define PCI_DEVICE_ID_TITAN_200E 0xA012 +#define PCI_DEVICE_ID_TITAN_400E 0xA013 +#define PCI_DEVICE_ID_TITAN_800E 0xA014 +#define PCI_DEVICE_ID_TITAN_200EI 0xA016 +#define PCI_DEVICE_ID_TITAN_200EISI 0xA017 +#define PCI_DEVICE_ID_TITAN_200V3 0xA306 +#define PCI_DEVICE_ID_TITAN_400V3 0xA310 +#define PCI_DEVICE_ID_TITAN_410V3 0xA312 +#define PCI_DEVICE_ID_TITAN_800V3 0xA314 +#define PCI_DEVICE_ID_TITAN_800V3B 0xA315 +#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 +#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 +#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 +#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d +#define PCI_VENDOR_ID_WCH 0x4348 +#define PCI_DEVICE_ID_WCH_CH352_2S 0x3253 +#define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 +#define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 +#define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053 +#define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 +#define PCI_DEVICE_ID_WCH_CH355_4S 0x7173 +#define PCI_VENDOR_ID_AGESTAR 0x5372 +#define PCI_DEVICE_ID_AGESTAR_9375 0x6872 +#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a +#define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e + +#define PCIE_VENDOR_ID_WCH 0x1c00 +#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 +#define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 +#define PCIE_DEVICE_ID_WCH_CH384_8S 0x3853 +#define PCIE_DEVICE_ID_WCH_CH382_2S 0x3253 + +#define PCI_DEVICE_ID_MOXA_CP102E 0x1024 +#define PCI_DEVICE_ID_MOXA_CP102EL 0x1025 +#define PCI_DEVICE_ID_MOXA_CP102N 0x1027 +#define PCI_DEVICE_ID_MOXA_CP104EL_A 0x1045 +#define PCI_DEVICE_ID_MOXA_CP104N 0x1046 +#define PCI_DEVICE_ID_MOXA_CP112N 0x1121 +#define PCI_DEVICE_ID_MOXA_CP114EL 0x1144 +#define PCI_DEVICE_ID_MOXA_CP114N 0x1145 +#define PCI_DEVICE_ID_MOXA_CP116E_A_A 0x1160 +#define PCI_DEVICE_ID_MOXA_CP116E_A_B 0x1161 +#define PCI_DEVICE_ID_MOXA_CP118EL_A 0x1182 +#define PCI_DEVICE_ID_MOXA_CP118E_A_I 0x1183 +#define PCI_DEVICE_ID_MOXA_CP132EL 0x1322 +#define PCI_DEVICE_ID_MOXA_CP132N 0x1323 +#define PCI_DEVICE_ID_MOXA_CP134EL_A 0x1342 +#define PCI_DEVICE_ID_MOXA_CP134N 0x1343 +#define PCI_DEVICE_ID_MOXA_CP138E_A 0x1381 +#define PCI_DEVICE_ID_MOXA_CP168EL_A 0x1683 + +/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ +#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 +#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 + /* * init function returns: * > 0 - number of ports @@ -1887,6 +1965,49 @@ pci_sunix_setup(struct serial_private *priv, return setup_port(priv, port, bar, offset, 0); } +#define MOXA_PUART_GPIO_EN 0x09 +#define MOXA_PUART_GPIO_OUT 0x0A + +#define MOXA_GPIO_PIN2 BIT(2) + +static bool pci_moxa_is_mini_pcie(unsigned short device) +{ + if (device == PCI_DEVICE_ID_MOXA_CP102N || + device == PCI_DEVICE_ID_MOXA_CP104N || + device == PCI_DEVICE_ID_MOXA_CP112N || + device == PCI_DEVICE_ID_MOXA_CP114N || + device == PCI_DEVICE_ID_MOXA_CP132N || + device == PCI_DEVICE_ID_MOXA_CP134N) + return true; + + return false; +} + +static int pci_moxa_init(struct pci_dev *dev) +{ + unsigned short device = dev->device; + resource_size_t iobar_addr = pci_resource_start(dev, 2); + unsigned int num_ports = (device & 0x00F0) >> 4; + u8 val; + + /* + * Enable hardware buffer to prevent break signal output when system boots up. + * This hardware buffer is only supported on Mini PCIe series. + */ + if (pci_moxa_is_mini_pcie(device)) { + /* Set GPIO direction */ + val = inb(iobar_addr + MOXA_PUART_GPIO_EN); + val |= MOXA_GPIO_PIN2; + outb(val, iobar_addr + MOXA_PUART_GPIO_EN); + /* Enable low GPIO */ + val = inb(iobar_addr + MOXA_PUART_GPIO_OUT); + val &= ~MOXA_GPIO_PIN2; + outb(val, iobar_addr + MOXA_PUART_GPIO_OUT); + } + + return num_ports; +} + static int pci_moxa_setup(struct serial_private *priv, const struct pciserial_board *board, @@ -1903,78 +2024,6 @@ pci_moxa_setup(struct serial_private *priv, return setup_port(priv, port, bar, offset, 0); } -#define PCI_VENDOR_ID_SBSMODULARIO 0x124B -#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B -#define PCI_DEVICE_ID_OCTPRO 0x0001 -#define PCI_SUBDEVICE_ID_OCTPRO232 0x0108 -#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 -#define PCI_SUBDEVICE_ID_POCTAL232 0x0308 -#define PCI_SUBDEVICE_ID_POCTAL422 0x0408 -#define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500 -#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 -#define PCI_VENDOR_ID_ADVANTECH 0x13fe -#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 -#define PCI_DEVICE_ID_ADVANTECH_PCI1600 0x1600 -#define PCI_DEVICE_ID_ADVANTECH_PCI1600_1611 0x1611 -#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 -#define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618 -#define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618 -#define PCI_DEVICE_ID_TITAN_200I 0x8028 -#define PCI_DEVICE_ID_TITAN_400I 0x8048 -#define PCI_DEVICE_ID_TITAN_800I 0x8088 -#define PCI_DEVICE_ID_TITAN_800EH 0xA007 -#define PCI_DEVICE_ID_TITAN_800EHB 0xA008 -#define PCI_DEVICE_ID_TITAN_400EH 0xA009 -#define PCI_DEVICE_ID_TITAN_100E 0xA010 -#define PCI_DEVICE_ID_TITAN_200E 0xA012 -#define PCI_DEVICE_ID_TITAN_400E 0xA013 -#define PCI_DEVICE_ID_TITAN_800E 0xA014 -#define PCI_DEVICE_ID_TITAN_200EI 0xA016 -#define PCI_DEVICE_ID_TITAN_200EISI 0xA017 -#define PCI_DEVICE_ID_TITAN_200V3 0xA306 -#define PCI_DEVICE_ID_TITAN_400V3 0xA310 -#define PCI_DEVICE_ID_TITAN_410V3 0xA312 -#define PCI_DEVICE_ID_TITAN_800V3 0xA314 -#define PCI_DEVICE_ID_TITAN_800V3B 0xA315 -#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 -#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 -#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 -#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d -#define PCI_VENDOR_ID_WCH 0x4348 -#define PCI_DEVICE_ID_WCH_CH352_2S 0x3253 -#define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 -#define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 -#define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053 -#define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 -#define PCI_DEVICE_ID_WCH_CH355_4S 0x7173 -#define PCI_VENDOR_ID_AGESTAR 0x5372 -#define PCI_DEVICE_ID_AGESTAR_9375 0x6872 -#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a -#define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e - -#define PCIE_VENDOR_ID_WCH 0x1c00 -#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 -#define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 -#define PCIE_DEVICE_ID_WCH_CH384_8S 0x3853 -#define PCIE_DEVICE_ID_WCH_CH382_2S 0x3253 - -#define PCI_DEVICE_ID_MOXA_CP102E 0x1024 -#define PCI_DEVICE_ID_MOXA_CP102EL 0x1025 -#define PCI_DEVICE_ID_MOXA_CP104EL_A 0x1045 -#define PCI_DEVICE_ID_MOXA_CP114EL 0x1144 -#define PCI_DEVICE_ID_MOXA_CP116E_A_A 0x1160 -#define PCI_DEVICE_ID_MOXA_CP116E_A_B 0x1161 -#define PCI_DEVICE_ID_MOXA_CP118EL_A 0x1182 -#define PCI_DEVICE_ID_MOXA_CP118E_A_I 0x1183 -#define PCI_DEVICE_ID_MOXA_CP132EL 0x1322 -#define PCI_DEVICE_ID_MOXA_CP134EL_A 0x1342 -#define PCI_DEVICE_ID_MOXA_CP138E_A 0x1381 -#define PCI_DEVICE_ID_MOXA_CP168EL_A 0x1683 - -/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ -#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 -#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 - /* * Master list of serial port init/setup/exit quirks. * This does not describe the general nature of the port. @@ -2429,6 +2478,153 @@ static struct pci_serial_quirk pci_serial_quirks[] = { .init = pci_oxsemi_tornado_init, .setup = pci_oxsemi_tornado_setup, }, + /* + * Brainboxes devices - all Oxsemi based + */ + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4027, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4028, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4029, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4019, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4016, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4015, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400A, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400E, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400C, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400B, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400F, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4010, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4011, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x401D, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x401E, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4013, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4017, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4018, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8811, @@ -2635,6 +2831,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = { .device = PCI_ANY_ID, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, + .init = pci_moxa_init, .setup = pci_moxa_setup, }, { @@ -2854,9 +3051,9 @@ enum pci_board_num_t { pbn_titan_2_4000000, pbn_titan_4_4000000, pbn_titan_8_4000000, - pbn_moxa8250_2p, - pbn_moxa8250_4p, - pbn_moxa8250_8p, + pbn_moxa_2, + pbn_moxa_4, + pbn_moxa_8, }; /* @@ -3628,19 +3825,19 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 0x200, .first_offset = 0x1000, }, - [pbn_moxa8250_2p] = { + [pbn_moxa_2] = { .flags = FL_BASE1, .num_ports = 2, .base_baud = 921600, .uart_offset = 0x200, }, - [pbn_moxa8250_4p] = { + [pbn_moxa_4] = { .flags = FL_BASE1, .num_ports = 4, .base_baud = 921600, .uart_offset = 0x200, }, - [pbn_moxa8250_8p] = { + [pbn_moxa_8] = { .flags = FL_BASE1, .num_ports = 8, .base_baud = 921600, @@ -4914,10 +5111,16 @@ static const struct pci_device_id serial_pci_tbl[] = { pbn_b1_bt_1_115200 }, /* + * IntaShield IS-100 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0D60, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b2_1_115200 }, + /* * IntaShield IS-200 */ { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0d80 */ pbn_b2_2_115200 }, /* * IntaShield IS-400 @@ -4925,6 +5128,27 @@ static const struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ pbn_b2_4_115200 }, + /* + * IntaShield IX-100 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4027, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_1_15625000 }, + /* + * IntaShield IX-200 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4028, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_2_15625000 }, + /* + * IntaShield IX-400 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4029, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, /* Brainboxes Devices */ /* * Brainboxes UC-101 @@ -4940,10 +5164,14 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AA2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_1_115200 }, /* - * Brainboxes UC-257 + * Brainboxes UC-253/UC-734 */ - { PCI_VENDOR_ID_INTASHIELD, 0x0861, + { PCI_VENDOR_ID_INTASHIELD, 0x0CA1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_2_115200 }, @@ -4979,6 +5207,14 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08E2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08E3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, /* * Brainboxes UC-310 */ @@ -4989,6 +5225,14 @@ static const struct pci_device_id serial_pci_tbl[] = { /* * Brainboxes UC-313 */ + { PCI_VENDOR_ID_INTASHIELD, 0x08A1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08A2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x08A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5003,6 +5247,10 @@ static const struct pci_device_id serial_pci_tbl[] = { /* * Brainboxes UC-346 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0B01, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_4_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x0B02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5014,6 +5262,10 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0A82, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x0A83, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5026,13 +5278,95 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_b2_4_115200 }, /* - * Brainboxes UC-420/431 + * Brainboxes UC-420 */ { PCI_VENDOR_ID_INTASHIELD, 0x0921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_4_115200 }, /* + * Brainboxes UC-607 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x09A1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x09A2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x09A3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UC-836 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0D41, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_4_115200 }, + /* + * Brainboxes UP-189 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0AC1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AC2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AC3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-200 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0B21, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0B22, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0B23, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-869 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0C01, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C02, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C03, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-880 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0C21, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C22, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C23, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* * Brainboxes PX-101 */ { PCI_VENDOR_ID_INTASHIELD, 0x4005, @@ -5064,7 +5398,7 @@ static const struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_INTASHIELD, 0x4015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_4_15625000 }, + pbn_oxsemi_2_15625000 }, /* * Brainboxes PX-260/PX-701 */ @@ -5073,6 +5407,13 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_oxsemi_4_15625000 }, /* + * Brainboxes PX-275/279 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0E41, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_8_115200 }, + /* * Brainboxes PX-310 */ { PCI_VENDOR_ID_INTASHIELD, 0x400E, @@ -5119,18 +5460,40 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_oxsemi_4_15625000 }, /* - * Brainboxes PX-803 + * Brainboxes PX-475 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x401D, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_1_15625000 }, + /* + * Brainboxes PX-803/PX-857 */ { PCI_VENDOR_ID_INTASHIELD, 0x4009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_115200 }, + pbn_b0_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4018, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_2_15625000 }, { PCI_VENDOR_ID_INTASHIELD, 0x401E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_15625000 }, + pbn_oxsemi_2_15625000 }, + /* + * Brainboxes PX-820 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4002, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_4_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4013, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, /* - * Brainboxes PX-846 + * Brainboxes PX-835/PX-846 */ { PCI_VENDOR_ID_INTASHIELD, 0x4008, PCI_ANY_ID, PCI_ANY_ID, @@ -5349,42 +5712,24 @@ static const struct pci_device_id serial_pci_tbl[] = { /* * MOXA */ - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102E, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_2p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102EL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_2p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_4p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114EL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_4p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_B, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118E_A_I, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132EL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_2p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134EL_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_4p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP138E_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102E), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102EL), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102N), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL_A), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104N), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP112N), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114EL), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114N), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_A), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_B), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL_A), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118E_A_I), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132EL), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132N), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134EL_A), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134N), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP138E_A), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL_A), pbn_moxa_8 }, /* * ADDI-DATA GmbH communication cards <info@addi-data.com> diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c b/drivers/tty/serial/8250/8250_pci1xxxx.c index a3b25779d921..9f9e21981929 100644 --- a/drivers/tty/serial/8250/8250_pci1xxxx.c +++ b/drivers/tty/serial/8250/8250_pci1xxxx.c @@ -107,7 +107,7 @@ static const int logical_to_physical_port_idx[][MAX_PORTS] = { struct pci1xxxx_8250 { unsigned int nr; void __iomem *membase; - int line[]; + int line[] __counted_by(nr); }; static int pci1xxxx_get_num_ports(struct pci_dev *dev) @@ -225,10 +225,10 @@ static bool pci1xxxx_port_suspend(int line) if (port->suspended == 0 && port->dev) { wakeup_mask = readb(up->port.membase + UART_WAKE_MASK_REG); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->mctrl &= ~TIOCM_OUT2; port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = (wakeup_mask & UART_WAKE_SRCS) != UART_WAKE_SRCS; } @@ -251,10 +251,10 @@ static void pci1xxxx_port_resume(int line) writeb(UART_WAKE_SRCS, port->membase + UART_WAKE_REG); if (port->suspended == 0) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->mctrl |= TIOCM_OUT2; port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } mutex_unlock(&tport->mutex); } diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 141627370aab..925ee1d61afb 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -689,7 +689,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) if (p->capabilities & UART_CAP_SLEEP) { /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&p->port.lock); + uart_port_lock_irq(&p->port); if (p->capabilities & UART_CAP_EFR) { lcr = serial_in(p, UART_LCR); efr = serial_in(p, UART_EFR); @@ -703,7 +703,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) serial_out(p, UART_EFR, efr); serial_out(p, UART_LCR, lcr); } - spin_unlock_irq(&p->port.lock); + uart_port_unlock_irq(&p->port); } serial8250_rpm_put(p); @@ -746,9 +746,9 @@ static void enable_rsa(struct uart_8250_port *up) { if (up->port.type == PORT_RSA) { if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); __enable_rsa(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) serial_out(up, UART_RSA_FRR, 0); @@ -768,7 +768,7 @@ static void disable_rsa(struct uart_8250_port *up) if (up->port.type == PORT_RSA && up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); mode = serial_in(up, UART_RSA_MSR); result = !(mode & UART_RSA_MSR_FIFO); @@ -781,7 +781,7 @@ static void disable_rsa(struct uart_8250_port *up) if (result) up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } } #endif /* CONFIG_SERIAL_8250_RSA */ @@ -1008,12 +1008,11 @@ static void autoconfig_16550a(struct uart_8250_port *up) serial_out(up, UART_LCR, 0); serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); - status1 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | - UART_IIR_FIFO_ENABLED); + status1 = serial_in(up, UART_IIR) & UART_IIR_FIFO_ENABLED_16750; serial_out(up, UART_FCR, 0); serial_out(up, UART_LCR, 0); - if (status1 == (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED)) + if (status1 == UART_IIR_FIFO_ENABLED_16750) up->port.type = PORT_16550A_FSL64; else DEBUG_AUTOCONF("Motorola 8xxx DUART "); @@ -1081,12 +1080,12 @@ static void autoconfig_16550a(struct uart_8250_port *up) */ serial_out(up, UART_LCR, 0); serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); - status1 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED); + status1 = serial_in(up, UART_IIR) & UART_IIR_FIFO_ENABLED_16750; serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); - status2 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED); + status2 = serial_in(up, UART_IIR) & UART_IIR_FIFO_ENABLED_16750; serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); serial_out(up, UART_LCR, 0); @@ -1094,7 +1093,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); if (status1 == UART_IIR_FIFO_ENABLED_16550A && - status2 == (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED_16550A)) { + status2 == UART_IIR_FIFO_ENABLED_16750) { up->port.type = PORT_16750; up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; return; @@ -1172,7 +1171,7 @@ static void autoconfig(struct uart_8250_port *up) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->capabilities = 0; up->bugs = 0; @@ -1211,7 +1210,7 @@ static void autoconfig(struct uart_8250_port *up) /* * We failed; there's nothing here */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", scratch2, scratch3); goto out; @@ -1235,7 +1234,7 @@ static void autoconfig(struct uart_8250_port *up) status1 = serial_in(up, UART_MSR) & UART_MSR_STATUS_BITS; serial8250_out_MCR(up, save_mcr); if (status1 != (UART_MSR_DCD | UART_MSR_CTS)) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); DEBUG_AUTOCONF("LOOP test failed (%02x) ", status1); goto out; @@ -1304,7 +1303,7 @@ static void autoconfig(struct uart_8250_port *up) serial8250_clear_IER(up); out_unlock: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* * Check if the device is a Fintek F81216A @@ -1344,9 +1343,9 @@ static void autoconfig_irq(struct uart_8250_port *up) probe_irq_off(probe_irq_on()); save_mcr = serial8250_in_MCR(up); /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); save_ier = serial_in(up, UART_IER); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); serial8250_out_MCR(up, UART_MCR_OUT1 | UART_MCR_OUT2); irqs = probe_irq_on(); @@ -1359,9 +1358,9 @@ static void autoconfig_irq(struct uart_8250_port *up) UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); } /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial_out(up, UART_IER, UART_IER_ALL_INTR); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); serial_in(up, UART_LSR); serial_in(up, UART_RX); serial_in(up, UART_IIR); @@ -1372,9 +1371,9 @@ static void autoconfig_irq(struct uart_8250_port *up) serial8250_out_MCR(up, save_mcr); /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial_out(up, UART_IER, save_ier); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); if (port->flags & UPF_FOURPORT) outb_p(save_ICP, ICP); @@ -1442,13 +1441,13 @@ static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) unsigned long flags; serial8250_rpm_get(p); - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); if (em485->active_timer == &em485->stop_tx_timer) { p->rs485_stop_tx(p); em485->active_timer = NULL; em485->tx_stopped = true; } - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); serial8250_rpm_put(p); return HRTIMER_NORESTART; @@ -1630,12 +1629,12 @@ static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t) struct uart_8250_port *p = em485->port; unsigned long flags; - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); if (em485->active_timer == &em485->start_tx_timer) { __start_tx(&p->port); em485->active_timer = NULL; } - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); return HRTIMER_NORESTART; } @@ -1918,7 +1917,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) if (iir & UART_IIR_NO_INT) return 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = serial_lsr_in(up); @@ -1988,9 +1987,9 @@ static int serial8250_tx_threshold_handle_irq(struct uart_port *port) if ((iir & UART_IIR_ID) == UART_IIR_THRI) { struct uart_8250_port *up = up_to_u8250p(port); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); serial8250_tx_chars(up); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } iir = serial_port_in(port, UART_IIR); @@ -2005,10 +2004,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (!serial8250_tx_dma_running(up) && uart_lsr_tx_empty(serial_lsr_in(up))) result = TIOCSER_TEMT; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_rpm_put(up); @@ -2070,13 +2069,13 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) unsigned long flags; serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_port_out(port, UART_LCR, up->lcr); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_rpm_put(up); } @@ -2211,7 +2210,7 @@ int serial8250_do_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->acr = 0; serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); serial_port_out(port, UART_EFR, UART_EFR_ECB); @@ -2221,7 +2220,7 @@ int serial8250_do_startup(struct uart_port *port) serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); serial_port_out(port, UART_EFR, UART_EFR_ECB); serial_port_out(port, UART_LCR, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } if (port->type == PORT_DA830) { @@ -2230,10 +2229,10 @@ int serial8250_do_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); serial_port_out(port, UART_IER, 0); serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); mdelay(10); /* Enable Tx, Rx and free run mode */ @@ -2347,7 +2346,7 @@ int serial8250_do_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); wait_for_xmitr(up, UART_LSR_THRE); serial_port_out_sync(port, UART_IER, UART_IER_THRI); @@ -2359,7 +2358,7 @@ int serial8250_do_startup(struct uart_port *port) iir = serial_port_in(port, UART_IIR); serial_port_out(port, UART_IER, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (port->irqflags & IRQF_SHARED) enable_irq(port->irq); @@ -2382,7 +2381,7 @@ int serial8250_do_startup(struct uart_port *port) */ serial_port_out(port, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (up->port.flags & UPF_FOURPORT) { if (!up->port.irq) up->port.mctrl |= TIOCM_OUT1; @@ -2428,7 +2427,7 @@ int serial8250_do_startup(struct uart_port *port) } dont_test_tx_en: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* * Clear the interrupt registers again for luck, and clear the @@ -2499,17 +2498,17 @@ void serial8250_do_shutdown(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->ier = 0; serial_port_out(port, UART_IER, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); synchronize_irq(port->irq); if (up->dma) serial8250_release_dma(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (port->flags & UPF_FOURPORT) { /* reset interrupts on the AST Fourport board */ inb((port->iobase & 0xfe0) | 0x1f); @@ -2518,7 +2517,7 @@ void serial8250_do_shutdown(struct uart_port *port) port->mctrl &= ~TIOCM_OUT2; serial8250_set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* * Disable break condition and FIFOs @@ -2754,14 +2753,14 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) quot = serial8250_get_divisor(port, baud, &frac); serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); serial8250_set_divisor(port, baud, quot, frac); serial_port_out(port, UART_LCR, up->lcr); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_rpm_put(up); out_unlock: @@ -2798,7 +2797,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, * Synchronize UART_IER access against the console. */ serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->lcr = cval; /* Save computed LCR */ @@ -2901,7 +2900,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, serial_port_out(port, UART_FCR, up->fcr); /* set fcr */ } serial8250_set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_rpm_put(up); /* Don't rewrite B0 */ @@ -2924,15 +2923,15 @@ void serial8250_do_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial8250_enable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } else { port->flags &= ~UPF_HARDPPS_CD; if (!UART_ENABLE_MS(port, termios->c_cflag)) { - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial8250_disable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } } } @@ -3406,9 +3405,9 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, touch_nmi_watchdog(); if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * First save the IER then disable the interrupts @@ -3478,7 +3477,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, serial8250_modem_status(up); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static unsigned int probe_baud(struct uart_port *port) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c12978311a09..8b9a2c4902e2 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -148,7 +148,7 @@ config SERIAL_8250_PCI config SERIAL_8250_EXAR tristate "8250/16550 Exar/Commtech PCI/PCIe device support" - depends on SERIAL_8250_PCI + depends on SERIAL_8250 && PCI default SERIAL_8250 help This builds support for XR17C1xx, XR17V3xx and some Commtech diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 628b75be312e..ea2e81f58eac 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -13,39 +13,41 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o 8250_base-$(CONFIG_SERIAL_8250_DWLIB) += 8250_dwlib.o 8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o 8250_base-$(CONFIG_SERIAL_8250_PCILIB) += 8250_pcilib.o -obj-$(CONFIG_SERIAL_8250_PARISC) += 8250_parisc.o -obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o -obj-$(CONFIG_SERIAL_8250_EXAR) += 8250_exar.o -obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o -obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o + +obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o + +obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o obj-$(CONFIG_SERIAL_8250_ASPEED_VUART) += 8250_aspeed_vuart.o obj-$(CONFIG_SERIAL_8250_BCM2835AUX) += 8250_bcm2835aux.o -obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o -obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o -obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o +obj-$(CONFIG_SERIAL_8250_BCM7271) += 8250_bcm7271.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o -obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o -obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o -obj-$(CONFIG_SERIAL_8250_PCI1XXXX) += 8250_pci1xxxx.o -obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o -obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o obj-$(CONFIG_SERIAL_8250_DFL) += 8250_dfl.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o +obj-$(CONFIG_SERIAL_8250_EXAR) += 8250_exar.o +obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o +obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o +obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o +obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o +obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o +obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o -obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o -obj-$(CONFIG_SERIAL_8250_RT288X) += 8250_rt288x.o obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o -obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o -obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o -obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o +obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o +obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o +obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o +obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o +obj-$(CONFIG_SERIAL_8250_PARISC) += 8250_parisc.o +obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +obj-$(CONFIG_SERIAL_8250_PCI1XXXX) += 8250_pci1xxxx.o obj-$(CONFIG_SERIAL_8250_PERICOM) += 8250_pericom.o obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o +obj-$(CONFIG_SERIAL_8250_RT288X) += 8250_rt288x.o +obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o +obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o obj-$(CONFIG_SERIAL_8250_TEGRA) += 8250_tegra.o -obj-$(CONFIG_SERIAL_8250_BCM7271) += 8250_bcm7271.o -obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index bdc568a4ab66..732c893c8d16 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1578,6 +1578,32 @@ config SERIAL_NUVOTON_MA35D1_CONSOLE but you can alter that using a kernel command line option such as "console=ttyNVTx". +config SERIAL_ESP32 + tristate "Espressif ESP32 UART support" + depends on XTENSA_PLATFORM_ESP32 || (COMPILE_TEST && OF) + select SERIAL_CORE + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON + help + Driver for the UART controllers of the Espressif ESP32xx SoCs. + When earlycon option is enabled the following kernel command line + snippets may be used: + earlycon=esp32s3uart,mmio32,0x60000000,115200n8,40000000 + earlycon=esp32uart,mmio32,0x3ff40000,115200n8 + +config SERIAL_ESP32_ACM + tristate "Espressif ESP32 USB ACM gadget support" + depends on XTENSA_PLATFORM_ESP32 || (COMPILE_TEST && OF) + select SERIAL_CORE + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON + help + Driver for the CDC ACM gadget controller of the Espressif ESP32S3 + SoCs that share separate USB controller with the JTAG adapter. + When earlycon option is enabled the following kernel command line + snippet may be used: + earlycon=esp32s3acm,mmio32,0x60038000 + endmenu config SERIAL_MCTRL_GPIO diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 138abbc89738..b25e9b54a660 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -24,70 +24,72 @@ obj-$(CONFIG_SERIAL_21285) += 21285.o # Now bring in any enabled 8250/16450/16550 type drivers. obj-y += 8250/ -obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o -obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o -obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o -obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o -obj-$(CONFIG_SERIAL_SA1100) += sa1100.o -obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o -obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o -obj-$(CONFIG_SERIAL_MAX3100) += max3100.o -obj-$(CONFIG_SERIAL_MAX310X) += max310x.o -obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o -obj-$(CONFIG_SERIAL_MUX) += mux.o -obj-$(CONFIG_SERIAL_MCF) += mcf.o -obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o -obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o -obj-$(CONFIG_SERIAL_DZ) += dz.o -obj-$(CONFIG_SERIAL_ZS) += zs.o -obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o -obj-$(CONFIG_SERIAL_CPM) += cpm_uart.o -obj-$(CONFIG_SERIAL_IMX) += imx.o -obj-$(CONFIG_SERIAL_IMX_EARLYCON) += imx_earlycon.o -obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o -obj-$(CONFIG_SERIAL_ICOM) += icom.o -obj-$(CONFIG_SERIAL_MESON) += meson_uart.o -obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o -obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o -obj-$(CONFIG_SERIAL_SC16IS7XX_CORE) += sc16is7xx.o -obj-$(CONFIG_SERIAL_JSM) += jsm/ -obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o -obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o -obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o -obj-$(CONFIG_SERIAL_MSM) += msm_serial.o -obj-$(CONFIG_SERIAL_QCOM_GENI) += qcom_geni_serial.o -obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o -obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o -obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o -obj-$(CONFIG_SERIAL_QE) += ucc_uart.o -obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o +obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o +obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o +obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o +obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o -obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o -obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o -obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o -obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o -obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o -obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o -obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o -obj-$(CONFIG_SERIAL_TEGRA_TCU) += tegra-tcu.o -obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o -obj-$(CONFIG_SERIAL_ARC) += arc_uart.o -obj-$(CONFIG_SERIAL_RP2) += rp2.o -obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o -obj-$(CONFIG_SERIAL_FSL_LINFLEXUART) += fsl_linflexuart.o +obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o +obj-$(CONFIG_SERIAL_ARC) += arc_uart.o +obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o +obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o +obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o +obj-$(CONFIG_SERIAL_CPM) += cpm_uart.o obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o -obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o -obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o -obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o -obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o -obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o -obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o -obj-$(CONFIG_SERIAL_OWL) += owl-uart.o -obj-$(CONFIG_SERIAL_RDA) += rda-uart.o -obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += milbeaut_usio.o -obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o -obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o -obj-$(CONFIG_SERIAL_SUNPLUS) += sunplus-uart.o +obj-$(CONFIG_SERIAL_DZ) += dz.o +obj-$(CONFIG_SERIAL_ESP32) += esp32_uart.o +obj-$(CONFIG_SERIAL_ESP32_ACM) += esp32_acm.o +obj-$(CONFIG_SERIAL_FSL_LINFLEXUART) += fsl_linflexuart.o +obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o +obj-$(CONFIG_SERIAL_ICOM) += icom.o +obj-$(CONFIG_SERIAL_IMX) += imx.o +obj-$(CONFIG_SERIAL_IMX_EARLYCON) += imx_earlycon.o +obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o +obj-$(CONFIG_SERIAL_JSM) += jsm/ +obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o +obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o +obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o +obj-$(CONFIG_SERIAL_MAX3100) += max3100.o +obj-$(CONFIG_SERIAL_MAX310X) += max310x.o +obj-$(CONFIG_SERIAL_MCF) += mcf.o +obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o +obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += milbeaut_usio.o +obj-$(CONFIG_SERIAL_MESON) += meson_uart.o +obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o +obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o +obj-$(CONFIG_SERIAL_MSM) += msm_serial.o +obj-$(CONFIG_SERIAL_MUX) += mux.o +obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o +obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o +obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o +obj-$(CONFIG_SERIAL_OWL) += owl-uart.o +obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o +obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o +obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o +obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o +obj-$(CONFIG_SERIAL_QCOM_GENI) += qcom_geni_serial.o +obj-$(CONFIG_SERIAL_QE) += ucc_uart.o +obj-$(CONFIG_SERIAL_RDA) += rda-uart.o +obj-$(CONFIG_SERIAL_RP2) += rp2.o +obj-$(CONFIG_SERIAL_SA1100) += sa1100.o +obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o +obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o +obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o +obj-$(CONFIG_SERIAL_SC16IS7XX_CORE) += sc16is7xx.o +obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o +obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o +obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o +obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o +obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o +obj-$(CONFIG_SERIAL_SUNPLUS) += sunplus-uart.o +obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o +obj-$(CONFIG_SERIAL_TEGRA_TCU) += tegra-tcu.o +obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o +obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o +obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o +obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o +obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o +obj-$(CONFIG_SERIAL_ZS) += zs.o # GPIOLIB helpers for modem control lines obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 5fab4c978891..7090b251dd4d 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -147,14 +147,14 @@ static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) isr = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) >> ALTERA_JTAGUART_CONTROL_RI_OFF) & port->read_status_mask; - spin_lock(&port->lock); + uart_port_lock(port); if (isr & ALTERA_JTAGUART_CONTROL_RE_MSK) altera_jtaguart_rx_chars(port); if (isr & ALTERA_JTAGUART_CONTROL_WE_MSK) altera_jtaguart_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_RETVAL(isr); } @@ -180,14 +180,14 @@ static int altera_jtaguart_startup(struct uart_port *port) return ret; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Enable RX interrupts now */ port->read_status_mask = ALTERA_JTAGUART_CONTROL_RE_MSK; writel(port->read_status_mask, port->membase + ALTERA_JTAGUART_CONTROL_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -196,14 +196,14 @@ static void altera_jtaguart_shutdown(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable all interrupts now */ port->read_status_mask = 0; writel(port->read_status_mask, port->membase + ALTERA_JTAGUART_CONTROL_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -264,33 +264,33 @@ static void altera_jtaguart_console_putc(struct uart_port *port, unsigned char c unsigned long flags; u32 status; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (!altera_jtaguart_tx_space(port, &status)) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0) { return; /* no connection activity */ } cpu_relax(); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); } writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #else static void altera_jtaguart_console_putc(struct uart_port *port, unsigned char c) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (!altera_jtaguart_tx_space(port, NULL)) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); cpu_relax(); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); } writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #endif diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index a9c41942190c..77835ac68df2 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -164,13 +164,13 @@ static void altera_uart_break_ctl(struct uart_port *port, int break_state) struct altera_uart *pp = container_of(port, struct altera_uart, port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (break_state == -1) pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK; else pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK; altera_uart_update_ctrl_reg(pp); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void altera_uart_set_termios(struct uart_port *port, @@ -187,10 +187,10 @@ static void altera_uart_set_termios(struct uart_port *port, tty_termios_copy_hw(termios, old); tty_termios_encode_baud_rate(termios, baud, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); altera_uart_writel(port, baudclk, ALTERA_UART_DIVISOR_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* * FIXME: port->read_status_mask and port->ignore_status_mask @@ -264,12 +264,12 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data) isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (isr & ALTERA_UART_STATUS_RRDY_MSK) altera_uart_rx_chars(port); if (isr & ALTERA_UART_STATUS_TRDY_MSK) altera_uart_tx_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_RETVAL(isr); } @@ -313,13 +313,13 @@ static int altera_uart_startup(struct uart_port *port) } } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Enable RX interrupts now */ pp->imr = ALTERA_UART_CONTROL_RRDY_MSK; altera_uart_update_ctrl_reg(pp); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -329,13 +329,13 @@ static void altera_uart_shutdown(struct uart_port *port) struct altera_uart *pp = container_of(port, struct altera_uart, port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable all interrupts now */ pp->imr = 0; altera_uart_update_ctrl_reg(pp); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (port->irq) free_irq(port->irq, port); diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index b5a7404cbacb..eabbf8afc9b5 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -207,7 +207,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id) unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; int handled = 0; - spin_lock(&port->lock); + uart_port_lock(port); status = readb(port->membase + UART010_IIR); if (status) { @@ -228,7 +228,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id) handled = 1; } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_RETVAL(handled); } @@ -270,14 +270,14 @@ static void pl010_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int lcr_h; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); lcr_h = readb(port->membase + UART010_LCRH); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; writel(lcr_h, port->membase + UART010_LCRH); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int pl010_startup(struct uart_port *port) @@ -385,7 +385,7 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, if (port->fifosize > 1) lcr_h |= UART01x_LCRH_FEN; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Update the per-port timeout. @@ -438,22 +438,22 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, writel(lcr_h, port->membase + UART010_LCRH); writel(old_cr, port->membase + UART010_CR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void pl010_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); pl010_enable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } else { port->flags &= ~UPF_HARDPPS_CD; if (!UART_ENABLE_MS(port, termios->c_cflag)) { - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); pl010_disable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } } } diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 3dc9b0fcab1c..61cc24cd90e4 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -345,9 +345,9 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) flag = TTY_FRAME; } - spin_unlock(&uap->port.lock); + uart_port_unlock(&uap->port); sysrq = uart_handle_sysrq_char(&uap->port, ch & 255); - spin_lock(&uap->port.lock); + uart_port_lock(&uap->port); if (!sysrq) uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); @@ -421,7 +421,7 @@ static void pl011_dma_probe(struct uart_amba_port *uap) /* We need platform data */ if (!plat || !plat->dma_filter) { - dev_info(uap->port.dev, "no DMA platform data\n"); + dev_dbg(uap->port.dev, "no DMA platform data\n"); return; } @@ -550,7 +550,7 @@ static void pl011_dma_tx_callback(void *data) unsigned long flags; u16 dmacr; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); if (uap->dmatx.queued) dma_unmap_sg(dmatx->chan->device->dev, &dmatx->sg, 1, DMA_TO_DEVICE); @@ -571,7 +571,7 @@ static void pl011_dma_tx_callback(void *data) if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) || uart_circ_empty(&uap->port.state->xmit)) { uap->dmatx.queued = false; - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); return; } @@ -582,7 +582,7 @@ static void pl011_dma_tx_callback(void *data) */ pl011_start_tx_pio(uap); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } /* @@ -1009,7 +1009,7 @@ static void pl011_dma_rx_callback(void *data) * routine to flush out the secondary DMA buffer while * we immediately trigger the next DMA job. */ - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); /* * Rx data can be taken by the UART interrupts during * the DMA irq handler. So we check the residue here. @@ -1025,7 +1025,7 @@ static void pl011_dma_rx_callback(void *data) ret = pl011_dma_rx_trigger_dma(uap); pl011_dma_rx_chars(uap, pending, lastbuf, false); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); /* * Do this check after we picked the DMA chars so we don't * get some IRQ immediately from RX. @@ -1091,11 +1091,11 @@ static void pl011_dma_rx_poll(struct timer_list *t) if (jiffies_to_msecs(jiffies - dmarx->last_jiffies) > uap->dmarx.poll_timeout) { - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); pl011_dma_rx_stop(uap); uap->im |= UART011_RXIM; pl011_write(uap->im, uap, REG_IMSC); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); uap->dmarx.running = false; dmaengine_terminate_all(rxchan); @@ -1191,10 +1191,10 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy) cpu_relax(); - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); pl011_write(uap->dmacr, uap, REG_DMACR); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); if (uap->using_tx_dma) { /* In theory, this should already be done by pl011_dma_flush_buffer */ @@ -1374,9 +1374,9 @@ static void pl011_throttle_rx(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pl011_stop_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void pl011_enable_ms(struct uart_port *port) @@ -1394,7 +1394,7 @@ __acquires(&uap->port.lock) { pl011_fifo_to_tty(uap); - spin_unlock(&uap->port.lock); + uart_port_unlock(&uap->port); tty_flip_buffer_push(&uap->port.state->port); /* * If we were temporarily out of DMA mode for a while, @@ -1419,7 +1419,7 @@ __acquires(&uap->port.lock) #endif } } - spin_lock(&uap->port.lock); + uart_port_lock(&uap->port); } static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, @@ -1555,7 +1555,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; int handled = 0; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); status = pl011_read(uap, REG_RIS) & uap->im; if (status) { do { @@ -1585,7 +1585,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) handled = 1; } - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); return IRQ_RETVAL(handled); } @@ -1657,14 +1657,14 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int lcr_h; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); lcr_h = pl011_read(uap, REG_LCRH_TX); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; pl011_write(lcr_h, uap, REG_LCRH_TX); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } #ifdef CONFIG_CONSOLE_POLL @@ -1803,7 +1803,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap) unsigned long flags; unsigned int i; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); /* Clear out any spuriously appearing RX interrupts */ pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR); @@ -1825,7 +1825,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap) if (!pl011_dma_rx_running(uap)) uap->im |= UART011_RXIM; pl011_write(uap->im, uap, REG_IMSC); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } static void pl011_unthrottle_rx(struct uart_port *port) @@ -1833,7 +1833,7 @@ static void pl011_unthrottle_rx(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); unsigned long flags; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); uap->im = UART011_RTIM; if (!pl011_dma_rx_running(uap)) @@ -1841,7 +1841,7 @@ static void pl011_unthrottle_rx(struct uart_port *port) pl011_write(uap->im, uap, REG_IMSC); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } static int pl011_startup(struct uart_port *port) @@ -1861,7 +1861,7 @@ static int pl011_startup(struct uart_port *port) pl011_write(uap->vendor->ifls, uap, REG_IFLS); - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); cr = pl011_read(uap, REG_CR); cr &= UART011_CR_RTS | UART011_CR_DTR; @@ -1872,7 +1872,7 @@ static int pl011_startup(struct uart_port *port) pl011_write(cr, uap, REG_CR); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); /* * initialise the old status of the modem signals @@ -1933,12 +1933,12 @@ static void pl011_disable_uart(struct uart_amba_port *uap) unsigned int cr; uap->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS); - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); cr = pl011_read(uap, REG_CR); cr &= UART011_CR_RTS | UART011_CR_DTR; cr |= UART01x_CR_UARTEN | UART011_CR_TXE; pl011_write(cr, uap, REG_CR); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); /* * disable break condition and fifos @@ -1950,14 +1950,14 @@ static void pl011_disable_uart(struct uart_amba_port *uap) static void pl011_disable_interrupts(struct uart_amba_port *uap) { - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); /* mask all interrupts and clear all pending ones */ uap->im = 0; pl011_write(uap->im, uap, REG_IMSC); pl011_write(0xffff, uap, REG_ICR); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); } static void pl011_shutdown(struct uart_port *port) @@ -2102,7 +2102,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, bits = tty_get_frame_size(termios->c_cflag); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Update the per-port timeout. @@ -2176,7 +2176,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, old_cr |= UART011_CR_RXE; pl011_write(old_cr, uap, REG_CR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void @@ -2194,10 +2194,10 @@ sbsa_uart_set_termios(struct uart_port *port, struct ktermios *termios, termios->c_cflag &= ~(CMSPAR | CRTSCTS); termios->c_cflag |= CS8 | CLOCAL; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, CS8, uap->fixed_baud); pl011_setup_status_masks(port, termios); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *pl011_type(struct uart_port *port) @@ -2336,9 +2336,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) if (uap->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&uap->port.lock); + locked = uart_port_trylock(&uap->port); else - spin_lock(&uap->port.lock); + uart_port_lock(&uap->port); /* * First save the CR then disable the interrupts @@ -2364,7 +2364,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) pl011_write(old_cr, uap, REG_CR); if (locked) - spin_unlock(&uap->port.lock); + uart_port_unlock(&uap->port); local_irq_restore(flags); clk_disable(uap->clk); diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index d7658f380838..716cb014c028 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -133,7 +133,7 @@ static irqreturn_t apbuart_int(int irq, void *dev_id) struct uart_port *port = dev_id; unsigned int status; - spin_lock(&port->lock); + uart_port_lock(port); status = UART_GET_STATUS(port); if (status & UART_STATUS_DR) @@ -141,7 +141,7 @@ static irqreturn_t apbuart_int(int irq, void *dev_id) if (status & UART_STATUS_THE) apbuart_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -228,7 +228,7 @@ static void apbuart_set_termios(struct uart_port *port, if (termios->c_cflag & CRTSCTS) cr |= UART_CTRL_FL; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); @@ -251,7 +251,7 @@ static void apbuart_set_termios(struct uart_port *port, UART_PUT_SCAL(port, quot); UART_PUT_CTRL(port, cr); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *apbuart_type(struct uart_port *port) diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 924c1a89347c..ffd234673177 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -133,9 +133,9 @@ static unsigned int ar933x_uart_tx_empty(struct uart_port *port) unsigned long flags; unsigned int rdata; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT; } @@ -220,14 +220,14 @@ static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) container_of(port, struct ar933x_uart_port, port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (break_state == -1) ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, AR933X_UART_CS_TX_BREAK); else ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, AR933X_UART_CS_TX_BREAK); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } /* @@ -318,7 +318,7 @@ static void ar933x_uart_set_termios(struct uart_port *port, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* disable the UART */ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, @@ -352,7 +352,7 @@ static void ar933x_uart_set_termios(struct uart_port *port, AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S, AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); if (tty_termios_baud_rate(new)) tty_termios_encode_baud_rate(new, baud, baud); @@ -450,7 +450,7 @@ static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) if ((status & AR933X_UART_CS_HOST_INT) == 0) return IRQ_NONE; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); status = ar933x_uart_read(up, AR933X_UART_INT_REG); status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG); @@ -468,7 +468,7 @@ static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) ar933x_uart_tx_chars(up); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); return IRQ_HANDLED; } @@ -485,7 +485,7 @@ static int ar933x_uart_startup(struct uart_port *port) if (ret) return ret; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* Enable HOST interrupts */ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, @@ -498,7 +498,7 @@ static int ar933x_uart_startup(struct uart_port *port) /* Enable RX interrupts */ ar933x_uart_start_rx_interrupt(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } @@ -632,9 +632,9 @@ static void ar933x_uart_console_write(struct console *co, const char *s, if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); + locked = uart_port_trylock(&up->port); else - spin_lock(&up->port.lock); + uart_port_lock(&up->port); /* * First save the IER then disable the interrupts @@ -654,7 +654,7 @@ static void ar933x_uart_console_write(struct console *co, const char *s, ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS); if (locked) - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index ad4ae19b6ce3..1aa5b2b49c26 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -279,9 +279,9 @@ static irqreturn_t arc_serial_isr(int irq, void *dev_id) if (status & RXIENB) { /* already in ISR, no need of xx_irqsave */ - spin_lock(&port->lock); + uart_port_lock(port); arc_serial_rx_chars(port, status); - spin_unlock(&port->lock); + uart_port_unlock(port); } if ((status & TXIENB) && (status & TXEMPTY)) { @@ -291,12 +291,12 @@ static irqreturn_t arc_serial_isr(int irq, void *dev_id) */ UART_TX_IRQ_DISABLE(port); - spin_lock(&port->lock); + uart_port_lock(port); if (!uart_tx_stopped(port)) arc_serial_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); } return IRQ_HANDLED; @@ -366,7 +366,7 @@ arc_serial_set_termios(struct uart_port *port, struct ktermios *new, uartl = hw_val & 0xFF; uarth = (hw_val >> 8) & 0xFF; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); UART_ALL_IRQ_DISABLE(port); @@ -391,7 +391,7 @@ arc_serial_set_termios(struct uart_port *port, struct ktermios *new, uart_update_timeout(port, new->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *arc_serial_type(struct uart_port *port) @@ -521,9 +521,9 @@ static void arc_serial_console_write(struct console *co, const char *s, struct uart_port *port = &arc_uart_ports[co->index].port; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_console_write(port, s, count, arc_serial_console_putchar); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static struct console arc_console = { diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 88cdafa5ac54..1946fafc3f3e 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -861,7 +861,7 @@ static void atmel_complete_tx_dma(void *arg) struct dma_chan *chan = atmel_port->chan_tx; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (chan) dmaengine_terminate_all(chan); @@ -893,7 +893,7 @@ static void atmel_complete_tx_dma(void *arg) atmel_port->tx_done_mask); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void atmel_release_tx_dma(struct uart_port *port) @@ -1711,9 +1711,9 @@ static void atmel_tasklet_rx_func(struct tasklet_struct *t) struct uart_port *port = &atmel_port->uart; /* The interrupt handler does not take the lock */ - spin_lock(&port->lock); + uart_port_lock(port); atmel_port->schedule_rx(port); - spin_unlock(&port->lock); + uart_port_unlock(port); } static void atmel_tasklet_tx_func(struct tasklet_struct *t) @@ -1723,9 +1723,9 @@ static void atmel_tasklet_tx_func(struct tasklet_struct *t) struct uart_port *port = &atmel_port->uart; /* The interrupt handler does not take the lock */ - spin_lock(&port->lock); + uart_port_lock(port); atmel_port->schedule_tx(port); - spin_unlock(&port->lock); + uart_port_unlock(port); } static void atmel_init_property(struct atmel_uart_port *atmel_port, @@ -2175,7 +2175,7 @@ static void atmel_set_termios(struct uart_port *port, } else mode |= ATMEL_US_PAR_NONE; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->read_status_mask = ATMEL_US_OVRE; if (termios->c_iflag & INPCK) @@ -2377,22 +2377,22 @@ gclk_fail: else atmel_disable_ms(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void atmel_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); atmel_enable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } else { port->flags &= ~UPF_HARDPPS_CD; if (!UART_ENABLE_MS(port, termios->c_cflag)) { - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); atmel_disable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } } } diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 0dd8cceb837c..4a08fd5ee61b 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -201,7 +201,7 @@ static void bcm_uart_break_ctl(struct uart_port *port, int ctl) unsigned long flags; unsigned int val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = bcm_uart_readl(port, UART_CTL_REG); if (ctl) @@ -210,7 +210,7 @@ static void bcm_uart_break_ctl(struct uart_port *port, int ctl) val &= ~UART_CTL_XMITBRK_MASK; bcm_uart_writel(port, val, UART_CTL_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* @@ -332,7 +332,7 @@ static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id) unsigned int irqstat; port = dev_id; - spin_lock(&port->lock); + uart_port_lock(port); irqstat = bcm_uart_readl(port, UART_IR_REG); if (irqstat & UART_RX_INT_STAT) @@ -353,7 +353,7 @@ static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id) estat & UART_EXTINP_DCD_MASK); } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -451,9 +451,9 @@ static void bcm_uart_shutdown(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); bcm_uart_writel(port, 0, UART_IR_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); bcm_uart_disable(port); bcm_uart_flush(port); @@ -470,7 +470,7 @@ static void bcm_uart_set_termios(struct uart_port *port, struct ktermios *new, unsigned long flags; int tries; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Drain the hot tub fully before we power it off for the winter. */ for (tries = 3; !bcm_uart_tx_empty(port) && tries; tries--) @@ -546,7 +546,7 @@ static void bcm_uart_set_termios(struct uart_port *port, struct ktermios *new, uart_update_timeout(port, new->c_cflag, baud); bcm_uart_enable(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* @@ -712,9 +712,9 @@ static void bcm_console_write(struct console *co, const char *s, /* bcm_uart_interrupt() already took the lock */ locked = 0; } else if (oops_in_progress) { - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); } else { - spin_lock(&port->lock); + uart_port_lock(port); locked = 1; } @@ -725,7 +725,7 @@ static void bcm_console_write(struct console *co, const char *s, wait_for_xmitr(port); if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/cpm_uart.c b/drivers/tty/serial/cpm_uart.c index 626423022d62..be4af6eda4c2 100644 --- a/drivers/tty/serial/cpm_uart.c +++ b/drivers/tty/serial/cpm_uart.c @@ -569,7 +569,7 @@ static void cpm_uart_set_termios(struct uart_port *port, if ((termios->c_cflag & CREAD) == 0) port->read_status_mask &= ~BD_SC_EMPTY; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (IS_SMC(pinfo)) { unsigned int bits = tty_get_frame_size(termios->c_cflag); @@ -609,7 +609,7 @@ static void cpm_uart_set_termios(struct uart_port *port, clk_set_rate(pinfo->clk, baud); else cpm_setbrg(pinfo->brg - 1, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *cpm_uart_type(struct uart_port *port) @@ -1386,9 +1386,9 @@ static void cpm_uart_console_write(struct console *co, const char *s, cpm_uart_early_write(pinfo, s, count, true); local_irq_restore(flags); } else { - spin_lock_irqsave(&pinfo->port.lock, flags); + uart_port_lock_irqsave(&pinfo->port, &flags); cpm_uart_early_write(pinfo, s, count, true); - spin_unlock_irqrestore(&pinfo->port.lock, flags); + uart_port_unlock_irqrestore(&pinfo->port, flags); } } diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c index 128b5479e813..5004125f3045 100644 --- a/drivers/tty/serial/digicolor-usart.c +++ b/drivers/tty/serial/digicolor-usart.c @@ -133,7 +133,7 @@ static void digicolor_uart_rx(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (1) { u8 status, ch, ch_flag; @@ -172,7 +172,7 @@ static void digicolor_uart_rx(struct uart_port *port) ch_flag); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); tty_flip_buffer_push(&port->state->port); } @@ -185,7 +185,7 @@ static void digicolor_uart_tx(struct uart_port *port) if (digicolor_uart_tx_full(port)) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (port->x_char) { writeb_relaxed(port->x_char, port->membase + UA_EMI_REC); @@ -211,7 +211,7 @@ static void digicolor_uart_tx(struct uart_port *port) uart_write_wakeup(port); out: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static irqreturn_t digicolor_uart_int(int irq, void *dev_id) @@ -333,7 +333,7 @@ static void digicolor_uart_set_termios(struct uart_port *port, port->ignore_status_mask |= UA_STATUS_OVERRUN_ERR | UA_STATUS_PARITY_ERR | UA_STATUS_FRAME_ERR; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); @@ -341,7 +341,7 @@ static void digicolor_uart_set_termios(struct uart_port *port, writeb_relaxed(divisor & 0xff, port->membase + UA_HBAUD_LO); writeb_relaxed(divisor >> 8, port->membase + UA_HBAUD_HI); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *digicolor_uart_type(struct uart_port *port) @@ -398,14 +398,14 @@ static void digicolor_uart_console_write(struct console *co, const char *c, int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_console_write(port, c, n, digicolor_uart_console_putchar); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Wait for transmitter to become empty */ do { diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 667f52e83277..6df7af9edc1c 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c @@ -268,9 +268,9 @@ static inline void dz_transmit_chars(struct dz_mux *mux) } /* If nothing to do or stopped or hardware stopped. */ if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) { - spin_lock(&dport->port.lock); + uart_port_lock(&dport->port); dz_stop_tx(&dport->port); - spin_unlock(&dport->port.lock); + uart_port_unlock(&dport->port); return; } @@ -287,9 +287,9 @@ static inline void dz_transmit_chars(struct dz_mux *mux) /* Are we are done. */ if (uart_circ_empty(xmit)) { - spin_lock(&dport->port.lock); + uart_port_lock(&dport->port); dz_stop_tx(&dport->port); - spin_unlock(&dport->port.lock); + uart_port_unlock(&dport->port); } } @@ -415,14 +415,14 @@ static int dz_startup(struct uart_port *uport) return ret; } - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); /* Enable interrupts. */ tmp = dz_in(dport, DZ_CSR); tmp |= DZ_RIE | DZ_TIE; dz_out(dport, DZ_CSR, tmp); - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); return 0; } @@ -443,9 +443,9 @@ static void dz_shutdown(struct uart_port *uport) int irq_guard; u16 tmp; - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); dz_stop_tx(&dport->port); - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); irq_guard = atomic_add_return(-1, &mux->irq_guard); if (!irq_guard) { @@ -491,14 +491,14 @@ static void dz_break_ctl(struct uart_port *uport, int break_state) unsigned long flags; unsigned short tmp, mask = 1 << dport->port.line; - spin_lock_irqsave(&uport->lock, flags); + uart_port_lock_irqsave(uport, &flags); tmp = dz_in(dport, DZ_TCR); if (break_state) tmp |= mask; else tmp &= ~mask; dz_out(dport, DZ_TCR, tmp); - spin_unlock_irqrestore(&uport->lock, flags); + uart_port_unlock_irqrestore(uport, flags); } static int dz_encode_baud_rate(unsigned int baud) @@ -608,7 +608,7 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios, if (termios->c_cflag & CREAD) cflag |= DZ_RXENAB; - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); uart_update_timeout(uport, termios->c_cflag, baud); @@ -631,7 +631,7 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios, if (termios->c_iflag & IGNBRK) dport->port.ignore_status_mask |= DZ_BREAK; - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); } /* @@ -645,12 +645,12 @@ static void dz_pm(struct uart_port *uport, unsigned int state, struct dz_port *dport = to_dport(uport); unsigned long flags; - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); if (state < 3) dz_start_tx(&dport->port); else dz_stop_tx(&dport->port); - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); } @@ -811,7 +811,7 @@ static void dz_console_putchar(struct uart_port *uport, unsigned char ch) unsigned short csr, tcr, trdy, mask; int loops = 10000; - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); csr = dz_in(dport, DZ_CSR); dz_out(dport, DZ_CSR, csr & ~DZ_TIE); tcr = dz_in(dport, DZ_TCR); @@ -819,7 +819,7 @@ static void dz_console_putchar(struct uart_port *uport, unsigned char ch) mask = tcr; dz_out(dport, DZ_TCR, mask); iob(); - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); do { trdy = dz_in(dport, DZ_CSR); diff --git a/drivers/tty/serial/esp32_acm.c b/drivers/tty/serial/esp32_acm.c new file mode 100644 index 000000000000..cb28a87736aa --- /dev/null +++ b/drivers/tty/serial/esp32_acm.c @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/serial_core.h> +#include <linux/slab.h> +#include <linux/tty_flip.h> +#include <asm/serial.h> + +#define DRIVER_NAME "esp32s3-acm" +#define DEV_NAME "ttyGS" +#define UART_NR 4 + +#define ESP32S3_ACM_TX_FIFO_SIZE 64 + +#define USB_SERIAL_JTAG_EP1_REG 0x00 +#define USB_SERIAL_JTAG_EP1_CONF_REG 0x04 +#define USB_SERIAL_JTAG_WR_DONE BIT(0) +#define USB_SERIAL_JTAG_SERIAL_IN_EP_DATA_FREE BIT(1) +#define USB_SERIAL_JTAG_INT_ST_REG 0x0c +#define USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ST BIT(2) +#define USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ST BIT(3) +#define USB_SERIAL_JTAG_INT_ENA_REG 0x10 +#define USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA BIT(2) +#define USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA BIT(3) +#define USB_SERIAL_JTAG_INT_CLR_REG 0x14 +#define USB_SERIAL_JTAG_IN_EP1_ST_REG 0x2c +#define USB_SERIAL_JTAG_IN_EP1_WR_ADDR GENMASK(8, 2) +#define USB_SERIAL_JTAG_OUT_EP1_ST_REG 0x3c +#define USB_SERIAL_JTAG_OUT_EP1_REC_DATA_CNT GENMASK(22, 16) + +static const struct of_device_id esp32s3_acm_dt_ids[] = { + { + .compatible = "esp,esp32s3-acm", + }, { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, esp32s3_acm_dt_ids); + +static struct uart_port *esp32s3_acm_ports[UART_NR]; + +static void esp32s3_acm_write(struct uart_port *port, unsigned long reg, u32 v) +{ + writel(v, port->membase + reg); +} + +static u32 esp32s3_acm_read(struct uart_port *port, unsigned long reg) +{ + return readl(port->membase + reg); +} + +static u32 esp32s3_acm_tx_fifo_free(struct uart_port *port) +{ + u32 status = esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_CONF_REG); + + return status & USB_SERIAL_JTAG_SERIAL_IN_EP_DATA_FREE; +} + +static u32 esp32s3_acm_tx_fifo_cnt(struct uart_port *port) +{ + u32 status = esp32s3_acm_read(port, USB_SERIAL_JTAG_IN_EP1_ST_REG); + + return FIELD_GET(USB_SERIAL_JTAG_IN_EP1_WR_ADDR, status); +} + +static u32 esp32s3_acm_rx_fifo_cnt(struct uart_port *port) +{ + u32 status = esp32s3_acm_read(port, USB_SERIAL_JTAG_OUT_EP1_ST_REG); + + return FIELD_GET(USB_SERIAL_JTAG_OUT_EP1_REC_DATA_CNT, status); +} + +/* return TIOCSER_TEMT when transmitter is not busy */ +static unsigned int esp32s3_acm_tx_empty(struct uart_port *port) +{ + return esp32s3_acm_tx_fifo_cnt(port) == 0 ? TIOCSER_TEMT : 0; +} + +static void esp32s3_acm_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +} + +static unsigned int esp32s3_acm_get_mctrl(struct uart_port *port) +{ + return TIOCM_CAR; +} + +static void esp32s3_acm_stop_tx(struct uart_port *port) +{ + u32 int_ena; + + int_ena = esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); + int_ena &= ~USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA; + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); +} + +static void esp32s3_acm_rxint(struct uart_port *port) +{ + struct tty_port *tty_port = &port->state->port; + u32 rx_fifo_cnt = esp32s3_acm_rx_fifo_cnt(port); + unsigned long flags; + u32 i; + + if (!rx_fifo_cnt) + return; + + spin_lock_irqsave(&port->lock, flags); + + for (i = 0; i < rx_fifo_cnt; ++i) { + u32 rx = esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_REG); + + ++port->icount.rx; + tty_insert_flip_char(tty_port, rx, TTY_NORMAL); + } + spin_unlock_irqrestore(&port->lock, flags); + + tty_flip_buffer_push(tty_port); +} + +static void esp32s3_acm_push(struct uart_port *port) +{ + if (esp32s3_acm_tx_fifo_free(port)) + esp32s3_acm_write(port, USB_SERIAL_JTAG_EP1_CONF_REG, + USB_SERIAL_JTAG_WR_DONE); +} + +static void esp32s3_acm_put_char(struct uart_port *port, u8 c) +{ + esp32s3_acm_write(port, USB_SERIAL_JTAG_EP1_REG, c); +} + +static void esp32s3_acm_put_char_sync(struct uart_port *port, u8 c) +{ + unsigned long timeout = jiffies + HZ; + + while (!esp32s3_acm_tx_fifo_free(port)) { + if (time_after(jiffies, timeout)) { + dev_warn(port->dev, "timeout waiting for TX FIFO\n"); + return; + } + cpu_relax(); + } + esp32s3_acm_put_char(port, c); + esp32s3_acm_push(port); +} + +static void esp32s3_acm_transmit_buffer(struct uart_port *port) +{ + u32 tx_fifo_used; + unsigned int pending; + u8 ch; + + if (!esp32s3_acm_tx_fifo_free(port)) + return; + + tx_fifo_used = esp32s3_acm_tx_fifo_cnt(port); + pending = uart_port_tx_limited(port, ch, + ESP32S3_ACM_TX_FIFO_SIZE - tx_fifo_used, + true, esp32s3_acm_put_char(port, ch), + ({})); + if (pending) { + u32 int_ena; + + int_ena = esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); + int_ena |= USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA; + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); + } + esp32s3_acm_push(port); +} + +static void esp32s3_acm_txint(struct uart_port *port) +{ + esp32s3_acm_transmit_buffer(port); +} + +static irqreturn_t esp32s3_acm_int(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + u32 status; + + status = esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ST_REG); + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_CLR_REG, status); + + if (status & USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ST) + esp32s3_acm_rxint(port); + if (status & USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ST) + esp32s3_acm_txint(port); + + return IRQ_RETVAL(status); +} + +static void esp32s3_acm_start_tx(struct uart_port *port) +{ + esp32s3_acm_transmit_buffer(port); +} + +static void esp32s3_acm_stop_rx(struct uart_port *port) +{ + u32 int_ena; + + int_ena = esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); + int_ena &= ~USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA; + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); +} + +static int esp32s3_acm_startup(struct uart_port *port) +{ + int ret; + + ret = request_irq(port->irq, esp32s3_acm_int, 0, DRIVER_NAME, port); + if (ret) + return ret; + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, + USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA); + + return 0; +} + +static void esp32s3_acm_shutdown(struct uart_port *port) +{ + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, 0); + free_irq(port->irq, port); +} + +static void esp32s3_acm_set_termios(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old) +{ +} + +static const char *esp32s3_acm_type(struct uart_port *port) +{ + return "ESP32S3 ACM"; +} + +/* configure/auto-configure the port */ +static void esp32s3_acm_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) + port->type = PORT_GENERIC; +} + +#ifdef CONFIG_CONSOLE_POLL +static void esp32s3_acm_poll_put_char(struct uart_port *port, unsigned char c) +{ + esp32s3_acm_put_char_sync(port, c); +} + +static int esp32s3_acm_poll_get_char(struct uart_port *port) +{ + if (esp32s3_acm_rx_fifo_cnt(port)) + return esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_REG); + else + return NO_POLL_CHAR; +} +#endif + +static const struct uart_ops esp32s3_acm_pops = { + .tx_empty = esp32s3_acm_tx_empty, + .set_mctrl = esp32s3_acm_set_mctrl, + .get_mctrl = esp32s3_acm_get_mctrl, + .stop_tx = esp32s3_acm_stop_tx, + .start_tx = esp32s3_acm_start_tx, + .stop_rx = esp32s3_acm_stop_rx, + .startup = esp32s3_acm_startup, + .shutdown = esp32s3_acm_shutdown, + .set_termios = esp32s3_acm_set_termios, + .type = esp32s3_acm_type, + .config_port = esp32s3_acm_config_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_put_char = esp32s3_acm_poll_put_char, + .poll_get_char = esp32s3_acm_poll_get_char, +#endif +}; + +static void esp32s3_acm_string_write(struct uart_port *port, const char *s, + unsigned int count) +{ + uart_console_write(port, s, count, esp32s3_acm_put_char_sync); +} + +static void +esp32s3_acm_console_write(struct console *co, const char *s, unsigned int count) +{ + struct uart_port *port = esp32s3_acm_ports[co->index]; + unsigned long flags; + bool locked = true; + + if (port->sysrq) + locked = false; + else if (oops_in_progress) + locked = spin_trylock_irqsave(&port->lock, flags); + else + spin_lock_irqsave(&port->lock, flags); + + esp32s3_acm_string_write(port, s, count); + + if (locked) + spin_unlock_irqrestore(&port->lock, flags); +} + +static struct uart_driver esp32s3_acm_reg; +static struct console esp32s3_acm_console = { + .name = DEV_NAME, + .write = esp32s3_acm_console_write, + .device = uart_console_device, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &esp32s3_acm_reg, +}; + +static void esp32s3_acm_earlycon_write(struct console *con, const char *s, + unsigned int n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, esp32s3_acm_put_char_sync); +} + +#ifdef CONFIG_CONSOLE_POLL +static int esp32s3_acm_earlycon_read(struct console *con, char *s, unsigned int n) +{ + struct earlycon_device *dev = con->data; + unsigned int num_read = 0; + + while (num_read < n) { + int c = esp32s3_acm_poll_get_char(&dev->port); + + if (c == NO_POLL_CHAR) + break; + s[num_read++] = c; + } + return num_read; +} +#endif + +static int __init esp32s3_acm_early_console_setup(struct earlycon_device *device, + const char *options) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = esp32s3_acm_earlycon_write; +#ifdef CONFIG_CONSOLE_POLL + device->con->read = esp32s3_acm_earlycon_read; +#endif + return 0; +} + +OF_EARLYCON_DECLARE(esp32s3acm, "esp,esp32s3-acm", + esp32s3_acm_early_console_setup); + +static struct uart_driver esp32s3_acm_reg = { + .owner = THIS_MODULE, + .driver_name = DRIVER_NAME, + .dev_name = DEV_NAME, + .nr = ARRAY_SIZE(esp32s3_acm_ports), + .cons = &esp32s3_acm_console, +}; + +static int esp32s3_acm_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct uart_port *port; + struct resource *res; + int ret; + + port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + ret = of_alias_get_id(np, "serial"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); + return ret; + } + if (ret >= UART_NR) { + dev_err(&pdev->dev, "driver limited to %d serial ports\n", + UART_NR); + return -ENOMEM; + } + + port->line = ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + port->mapbase = res->start; + port->membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(port->membase)) + return PTR_ERR(port->membase); + + port->dev = &pdev->dev; + port->type = PORT_GENERIC; + port->iotype = UPIO_MEM; + port->irq = platform_get_irq(pdev, 0); + port->ops = &esp32s3_acm_pops; + port->flags = UPF_BOOT_AUTOCONF; + port->has_sysrq = 1; + port->fifosize = ESP32S3_ACM_TX_FIFO_SIZE; + + esp32s3_acm_ports[port->line] = port; + + platform_set_drvdata(pdev, port); + + return uart_add_one_port(&esp32s3_acm_reg, port); +} + +static int esp32s3_acm_remove(struct platform_device *pdev) +{ + struct uart_port *port = platform_get_drvdata(pdev); + + uart_remove_one_port(&esp32s3_acm_reg, port); + return 0; +} + + +static struct platform_driver esp32s3_acm_driver = { + .probe = esp32s3_acm_probe, + .remove = esp32s3_acm_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = esp32s3_acm_dt_ids, + }, +}; + +static int __init esp32s3_acm_init(void) +{ + int ret; + + ret = uart_register_driver(&esp32s3_acm_reg); + if (ret) + return ret; + + ret = platform_driver_register(&esp32s3_acm_driver); + if (ret) + uart_unregister_driver(&esp32s3_acm_reg); + + return ret; +} + +static void __exit esp32s3_acm_exit(void) +{ + platform_driver_unregister(&esp32s3_acm_driver); + uart_unregister_driver(&esp32s3_acm_reg); +} + +module_init(esp32s3_acm_init); +module_exit(esp32s3_acm_exit); + +MODULE_AUTHOR("Max Filippov <jcmvbkbc@gmail.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/esp32_uart.c b/drivers/tty/serial/esp32_uart.c new file mode 100644 index 000000000000..85c9c5ad7cc5 --- /dev/null +++ b/drivers/tty/serial/esp32_uart.c @@ -0,0 +1,784 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/clk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/serial_core.h> +#include <linux/slab.h> +#include <linux/tty_flip.h> +#include <asm/serial.h> + +#define DRIVER_NAME "esp32-uart" +#define DEV_NAME "ttyS" +#define UART_NR 3 + +#define ESP32_UART_TX_FIFO_SIZE 127 +#define ESP32_UART_RX_FIFO_SIZE 127 + +#define UART_FIFO_REG 0x00 +#define UART_INT_RAW_REG 0x04 +#define UART_INT_ST_REG 0x08 +#define UART_INT_ENA_REG 0x0c +#define UART_INT_CLR_REG 0x10 +#define UART_RXFIFO_FULL_INT BIT(0) +#define UART_TXFIFO_EMPTY_INT BIT(1) +#define UART_BRK_DET_INT BIT(7) +#define UART_CLKDIV_REG 0x14 +#define ESP32_UART_CLKDIV GENMASK(19, 0) +#define ESP32S3_UART_CLKDIV GENMASK(11, 0) +#define UART_CLKDIV_SHIFT 0 +#define UART_CLKDIV_FRAG GENMASK(23, 20) +#define UART_STATUS_REG 0x1c +#define ESP32_UART_RXFIFO_CNT GENMASK(7, 0) +#define ESP32S3_UART_RXFIFO_CNT GENMASK(9, 0) +#define UART_RXFIFO_CNT_SHIFT 0 +#define UART_DSRN BIT(13) +#define UART_CTSN BIT(14) +#define ESP32_UART_TXFIFO_CNT GENMASK(23, 16) +#define ESP32S3_UART_TXFIFO_CNT GENMASK(25, 16) +#define UART_TXFIFO_CNT_SHIFT 16 +#define UART_CONF0_REG 0x20 +#define UART_PARITY BIT(0) +#define UART_PARITY_EN BIT(1) +#define UART_BIT_NUM GENMASK(3, 2) +#define UART_BIT_NUM_5 0 +#define UART_BIT_NUM_6 1 +#define UART_BIT_NUM_7 2 +#define UART_BIT_NUM_8 3 +#define UART_STOP_BIT_NUM GENMASK(5, 4) +#define UART_STOP_BIT_NUM_1 1 +#define UART_STOP_BIT_NUM_2 3 +#define UART_SW_RTS BIT(6) +#define UART_SW_DTR BIT(7) +#define UART_LOOPBACK BIT(14) +#define UART_TX_FLOW_EN BIT(15) +#define UART_RTS_INV BIT(23) +#define UART_DTR_INV BIT(24) +#define UART_CONF1_REG 0x24 +#define UART_RXFIFO_FULL_THRHD_SHIFT 0 +#define ESP32_UART_TXFIFO_EMPTY_THRHD_SHIFT 8 +#define ESP32S3_UART_TXFIFO_EMPTY_THRHD_SHIFT 10 +#define ESP32_UART_RX_FLOW_EN BIT(23) +#define ESP32S3_UART_RX_FLOW_EN BIT(22) +#define ESP32S3_UART_CLK_CONF_REG 0x78 +#define ESP32S3_UART_SCLK_DIV_B GENMASK(5, 0) +#define ESP32S3_UART_SCLK_DIV_A GENMASK(11, 6) +#define ESP32S3_UART_SCLK_DIV_NUM GENMASK(19, 12) +#define ESP32S3_UART_SCLK_SEL GENMASK(21, 20) +#define APB_CLK 1 +#define RC_FAST_CLK 2 +#define XTAL_CLK 3 +#define ESP32S3_UART_SCLK_EN BIT(22) +#define ESP32S3_UART_RST_CORE BIT(23) +#define ESP32S3_UART_TX_SCLK_EN BIT(24) +#define ESP32S3_UART_RX_SCLK_EN BIT(25) +#define ESP32S3_UART_TX_RST_CORE BIT(26) +#define ESP32S3_UART_RX_RST_CORE BIT(27) + +#define ESP32S3_UART_CLK_CONF_DEFAULT \ + (ESP32S3_UART_RX_SCLK_EN | \ + ESP32S3_UART_TX_SCLK_EN | \ + ESP32S3_UART_SCLK_EN | \ + FIELD_PREP(ESP32S3_UART_SCLK_SEL, XTAL_CLK)) + +struct esp32_port { + struct uart_port port; + struct clk *clk; +}; + +struct esp32_uart_variant { + u32 clkdiv_mask; + u32 rxfifo_cnt_mask; + u32 txfifo_cnt_mask; + u32 txfifo_empty_thrhd_shift; + u32 rx_flow_en; + const char *type; + bool has_clkconf; +}; + +static const struct esp32_uart_variant esp32_variant = { + .clkdiv_mask = ESP32_UART_CLKDIV, + .rxfifo_cnt_mask = ESP32_UART_RXFIFO_CNT, + .txfifo_cnt_mask = ESP32_UART_TXFIFO_CNT, + .txfifo_empty_thrhd_shift = ESP32_UART_TXFIFO_EMPTY_THRHD_SHIFT, + .rx_flow_en = ESP32_UART_RX_FLOW_EN, + .type = "ESP32 UART", +}; + +static const struct esp32_uart_variant esp32s3_variant = { + .clkdiv_mask = ESP32S3_UART_CLKDIV, + .rxfifo_cnt_mask = ESP32S3_UART_RXFIFO_CNT, + .txfifo_cnt_mask = ESP32S3_UART_TXFIFO_CNT, + .txfifo_empty_thrhd_shift = ESP32S3_UART_TXFIFO_EMPTY_THRHD_SHIFT, + .rx_flow_en = ESP32S3_UART_RX_FLOW_EN, + .type = "ESP32S3 UART", + .has_clkconf = true, +}; + +static const struct of_device_id esp32_uart_dt_ids[] = { + { + .compatible = "esp,esp32-uart", + .data = &esp32_variant, + }, { + .compatible = "esp,esp32s3-uart", + .data = &esp32s3_variant, + }, { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, esp32_uart_dt_ids); + +static struct esp32_port *esp32_uart_ports[UART_NR]; + +static const struct esp32_uart_variant *port_variant(struct uart_port *port) +{ + return port->private_data; +} + +static void esp32_uart_write(struct uart_port *port, unsigned long reg, u32 v) +{ + writel(v, port->membase + reg); +} + +static u32 esp32_uart_read(struct uart_port *port, unsigned long reg) +{ + return readl(port->membase + reg); +} + +static u32 esp32_uart_tx_fifo_cnt(struct uart_port *port) +{ + u32 status = esp32_uart_read(port, UART_STATUS_REG); + + return (status & port_variant(port)->txfifo_cnt_mask) >> UART_TXFIFO_CNT_SHIFT; +} + +static u32 esp32_uart_rx_fifo_cnt(struct uart_port *port) +{ + u32 status = esp32_uart_read(port, UART_STATUS_REG); + + return (status & port_variant(port)->rxfifo_cnt_mask) >> UART_RXFIFO_CNT_SHIFT; +} + +/* return TIOCSER_TEMT when transmitter is not busy */ +static unsigned int esp32_uart_tx_empty(struct uart_port *port) +{ + return esp32_uart_tx_fifo_cnt(port) ? 0 : TIOCSER_TEMT; +} + +static void esp32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + u32 conf0 = esp32_uart_read(port, UART_CONF0_REG); + + conf0 &= ~(UART_LOOPBACK | + UART_SW_RTS | UART_RTS_INV | + UART_SW_DTR | UART_DTR_INV); + + if (mctrl & TIOCM_RTS) + conf0 |= UART_SW_RTS; + if (mctrl & TIOCM_DTR) + conf0 |= UART_SW_DTR; + if (mctrl & TIOCM_LOOP) + conf0 |= UART_LOOPBACK; + + esp32_uart_write(port, UART_CONF0_REG, conf0); +} + +static unsigned int esp32_uart_get_mctrl(struct uart_port *port) +{ + u32 status = esp32_uart_read(port, UART_STATUS_REG); + unsigned int ret = TIOCM_CAR; + + if (status & UART_DSRN) + ret |= TIOCM_DSR; + if (status & UART_CTSN) + ret |= TIOCM_CTS; + + return ret; +} + +static void esp32_uart_stop_tx(struct uart_port *port) +{ + u32 int_ena; + + int_ena = esp32_uart_read(port, UART_INT_ENA_REG); + int_ena &= ~UART_TXFIFO_EMPTY_INT; + esp32_uart_write(port, UART_INT_ENA_REG, int_ena); +} + +static void esp32_uart_rxint(struct uart_port *port) +{ + struct tty_port *tty_port = &port->state->port; + u32 rx_fifo_cnt = esp32_uart_rx_fifo_cnt(port); + unsigned long flags; + u32 i; + + if (!rx_fifo_cnt) + return; + + spin_lock_irqsave(&port->lock, flags); + + for (i = 0; i < rx_fifo_cnt; ++i) { + u32 rx = esp32_uart_read(port, UART_FIFO_REG); + + if (!rx && + (esp32_uart_read(port, UART_INT_ST_REG) & UART_BRK_DET_INT)) { + esp32_uart_write(port, UART_INT_CLR_REG, UART_BRK_DET_INT); + ++port->icount.brk; + uart_handle_break(port); + } else { + if (uart_handle_sysrq_char(port, (unsigned char)rx)) + continue; + tty_insert_flip_char(tty_port, rx, TTY_NORMAL); + ++port->icount.rx; + } + } + spin_unlock_irqrestore(&port->lock, flags); + + tty_flip_buffer_push(tty_port); +} + +static void esp32_uart_put_char(struct uart_port *port, u8 c) +{ + esp32_uart_write(port, UART_FIFO_REG, c); +} + +static void esp32_uart_put_char_sync(struct uart_port *port, u8 c) +{ + unsigned long timeout = jiffies + HZ; + + while (esp32_uart_tx_fifo_cnt(port) >= ESP32_UART_TX_FIFO_SIZE) { + if (time_after(jiffies, timeout)) { + dev_warn(port->dev, "timeout waiting for TX FIFO\n"); + return; + } + cpu_relax(); + } + esp32_uart_put_char(port, c); +} + +static void esp32_uart_transmit_buffer(struct uart_port *port) +{ + u32 tx_fifo_used = esp32_uart_tx_fifo_cnt(port); + unsigned int pending; + u8 ch; + + if (tx_fifo_used >= ESP32_UART_TX_FIFO_SIZE) + return; + + pending = uart_port_tx_limited(port, ch, + ESP32_UART_TX_FIFO_SIZE - tx_fifo_used, + true, esp32_uart_put_char(port, ch), + ({})); + if (pending) { + u32 int_ena; + + int_ena = esp32_uart_read(port, UART_INT_ENA_REG); + int_ena |= UART_TXFIFO_EMPTY_INT; + esp32_uart_write(port, UART_INT_ENA_REG, int_ena); + } +} + +static void esp32_uart_txint(struct uart_port *port) +{ + esp32_uart_transmit_buffer(port); +} + +static irqreturn_t esp32_uart_int(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + u32 status; + + status = esp32_uart_read(port, UART_INT_ST_REG); + + if (status & (UART_RXFIFO_FULL_INT | UART_BRK_DET_INT)) + esp32_uart_rxint(port); + if (status & UART_TXFIFO_EMPTY_INT) + esp32_uart_txint(port); + + esp32_uart_write(port, UART_INT_CLR_REG, status); + + return IRQ_RETVAL(status); +} + +static void esp32_uart_start_tx(struct uart_port *port) +{ + esp32_uart_transmit_buffer(port); +} + +static void esp32_uart_stop_rx(struct uart_port *port) +{ + u32 int_ena; + + int_ena = esp32_uart_read(port, UART_INT_ENA_REG); + int_ena &= ~UART_RXFIFO_FULL_INT; + esp32_uart_write(port, UART_INT_ENA_REG, int_ena); +} + +static int esp32_uart_startup(struct uart_port *port) +{ + int ret = 0; + unsigned long flags; + struct esp32_port *sport = container_of(port, struct esp32_port, port); + + ret = clk_prepare_enable(sport->clk); + if (ret) + return ret; + + ret = request_irq(port->irq, esp32_uart_int, 0, DRIVER_NAME, port); + if (ret) { + clk_disable_unprepare(sport->clk); + return ret; + } + + spin_lock_irqsave(&port->lock, flags); + if (port_variant(port)->has_clkconf) + esp32_uart_write(port, ESP32S3_UART_CLK_CONF_REG, + ESP32S3_UART_CLK_CONF_DEFAULT); + esp32_uart_write(port, UART_CONF1_REG, + (1 << UART_RXFIFO_FULL_THRHD_SHIFT) | + (1 << port_variant(port)->txfifo_empty_thrhd_shift)); + esp32_uart_write(port, UART_INT_CLR_REG, UART_RXFIFO_FULL_INT | UART_BRK_DET_INT); + esp32_uart_write(port, UART_INT_ENA_REG, UART_RXFIFO_FULL_INT | UART_BRK_DET_INT); + spin_unlock_irqrestore(&port->lock, flags); + + return ret; +} + +static void esp32_uart_shutdown(struct uart_port *port) +{ + struct esp32_port *sport = container_of(port, struct esp32_port, port); + + esp32_uart_write(port, UART_INT_ENA_REG, 0); + free_irq(port->irq, port); + clk_disable_unprepare(sport->clk); +} + +static bool esp32_uart_set_baud(struct uart_port *port, u32 baud) +{ + u32 sclk = port->uartclk; + u32 div = sclk / baud; + + if (port_variant(port)->has_clkconf) { + u32 sclk_div = div / port_variant(port)->clkdiv_mask; + + if (div > port_variant(port)->clkdiv_mask) { + sclk /= (sclk_div + 1); + div = sclk / baud; + } + esp32_uart_write(port, ESP32S3_UART_CLK_CONF_REG, + FIELD_PREP(ESP32S3_UART_SCLK_DIV_NUM, sclk_div) | + ESP32S3_UART_CLK_CONF_DEFAULT); + } + + if (div <= port_variant(port)->clkdiv_mask) { + u32 frag = (sclk * 16) / baud - div * 16; + + esp32_uart_write(port, UART_CLKDIV_REG, + div | FIELD_PREP(UART_CLKDIV_FRAG, frag)); + return true; + } + + return false; +} + +static void esp32_uart_set_termios(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old) +{ + unsigned long flags; + u32 conf0, conf1; + u32 baud; + const u32 rx_flow_en = port_variant(port)->rx_flow_en; + u32 max_div = port_variant(port)->clkdiv_mask; + + termios->c_cflag &= ~CMSPAR; + + if (port_variant(port)->has_clkconf) + max_div *= FIELD_MAX(ESP32S3_UART_SCLK_DIV_NUM); + + baud = uart_get_baud_rate(port, termios, old, + port->uartclk / max_div, + port->uartclk / 16); + + spin_lock_irqsave(&port->lock, flags); + + conf0 = esp32_uart_read(port, UART_CONF0_REG); + conf0 &= ~(UART_PARITY_EN | UART_PARITY | UART_BIT_NUM | UART_STOP_BIT_NUM); + + conf1 = esp32_uart_read(port, UART_CONF1_REG); + conf1 &= ~rx_flow_en; + + if (termios->c_cflag & PARENB) { + conf0 |= UART_PARITY_EN; + if (termios->c_cflag & PARODD) + conf0 |= UART_PARITY; + } + + switch (termios->c_cflag & CSIZE) { + case CS5: + conf0 |= FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_5); + break; + case CS6: + conf0 |= FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_6); + break; + case CS7: + conf0 |= FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_7); + break; + case CS8: + conf0 |= FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_8); + break; + } + + if (termios->c_cflag & CSTOPB) + conf0 |= FIELD_PREP(UART_STOP_BIT_NUM, UART_STOP_BIT_NUM_2); + else + conf0 |= FIELD_PREP(UART_STOP_BIT_NUM, UART_STOP_BIT_NUM_1); + + if (termios->c_cflag & CRTSCTS) + conf1 |= rx_flow_en; + + esp32_uart_write(port, UART_CONF0_REG, conf0); + esp32_uart_write(port, UART_CONF1_REG, conf1); + + if (baud) { + esp32_uart_set_baud(port, baud); + uart_update_timeout(port, termios->c_cflag, baud); + } else { + if (esp32_uart_set_baud(port, 115200)) { + baud = 115200; + tty_termios_encode_baud_rate(termios, baud, baud); + uart_update_timeout(port, termios->c_cflag, baud); + } else { + dev_warn(port->dev, + "unable to set speed to %d baud or the default 115200\n", + baud); + } + } + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *esp32_uart_type(struct uart_port *port) +{ + return port_variant(port)->type; +} + +/* configure/auto-configure the port */ +static void esp32_uart_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) + port->type = PORT_GENERIC; +} + +#ifdef CONFIG_CONSOLE_POLL +static int esp32_uart_poll_init(struct uart_port *port) +{ + struct esp32_port *sport = container_of(port, struct esp32_port, port); + + return clk_prepare_enable(sport->clk); +} + +static void esp32_uart_poll_put_char(struct uart_port *port, unsigned char c) +{ + esp32_uart_put_char_sync(port, c); +} + +static int esp32_uart_poll_get_char(struct uart_port *port) +{ + if (esp32_uart_rx_fifo_cnt(port)) + return esp32_uart_read(port, UART_FIFO_REG); + else + return NO_POLL_CHAR; + +} +#endif + +static const struct uart_ops esp32_uart_pops = { + .tx_empty = esp32_uart_tx_empty, + .set_mctrl = esp32_uart_set_mctrl, + .get_mctrl = esp32_uart_get_mctrl, + .stop_tx = esp32_uart_stop_tx, + .start_tx = esp32_uart_start_tx, + .stop_rx = esp32_uart_stop_rx, + .startup = esp32_uart_startup, + .shutdown = esp32_uart_shutdown, + .set_termios = esp32_uart_set_termios, + .type = esp32_uart_type, + .config_port = esp32_uart_config_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_init = esp32_uart_poll_init, + .poll_put_char = esp32_uart_poll_put_char, + .poll_get_char = esp32_uart_poll_get_char, +#endif +}; + +static void esp32_uart_console_putchar(struct uart_port *port, u8 c) +{ + esp32_uart_put_char_sync(port, c); +} + +static void esp32_uart_string_write(struct uart_port *port, const char *s, + unsigned int count) +{ + uart_console_write(port, s, count, esp32_uart_console_putchar); +} + +static void +esp32_uart_console_write(struct console *co, const char *s, unsigned int count) +{ + struct esp32_port *sport = esp32_uart_ports[co->index]; + struct uart_port *port = &sport->port; + unsigned long flags; + bool locked = true; + + if (port->sysrq) + locked = false; + else if (oops_in_progress) + locked = spin_trylock_irqsave(&port->lock, flags); + else + spin_lock_irqsave(&port->lock, flags); + + esp32_uart_string_write(port, s, count); + + if (locked) + spin_unlock_irqrestore(&port->lock, flags); +} + +static int __init esp32_uart_console_setup(struct console *co, char *options) +{ + struct esp32_port *sport; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + int ret; + + /* + * check whether an invalid uart number has been specified, and + * if so, search for the first available port that does have + * console support. + */ + if (co->index == -1 || co->index >= ARRAY_SIZE(esp32_uart_ports)) + co->index = 0; + + sport = esp32_uart_ports[co->index]; + if (!sport) + return -ENODEV; + + ret = clk_prepare_enable(sport->clk); + if (ret) + return ret; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(&sport->port, co, baud, parity, bits, flow); +} + +static int esp32_uart_console_exit(struct console *co) +{ + struct esp32_port *sport = esp32_uart_ports[co->index]; + + clk_disable_unprepare(sport->clk); + return 0; +} + +static struct uart_driver esp32_uart_reg; +static struct console esp32_uart_console = { + .name = DEV_NAME, + .write = esp32_uart_console_write, + .device = uart_console_device, + .setup = esp32_uart_console_setup, + .exit = esp32_uart_console_exit, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &esp32_uart_reg, +}; + +static void esp32_uart_earlycon_putchar(struct uart_port *port, u8 c) +{ + esp32_uart_put_char_sync(port, c); +} + +static void esp32_uart_earlycon_write(struct console *con, const char *s, + unsigned int n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, esp32_uart_earlycon_putchar); +} + +#ifdef CONFIG_CONSOLE_POLL +static int esp32_uart_earlycon_read(struct console *con, char *s, unsigned int n) +{ + struct earlycon_device *dev = con->data; + unsigned int num_read = 0; + + while (num_read < n) { + int c = esp32_uart_poll_get_char(&dev->port); + + if (c == NO_POLL_CHAR) + break; + s[num_read++] = c; + } + return num_read; +} +#endif + +static int __init esp32xx_uart_early_console_setup(struct earlycon_device *device, + const char *options) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = esp32_uart_earlycon_write; +#ifdef CONFIG_CONSOLE_POLL + device->con->read = esp32_uart_earlycon_read; +#endif + if (device->port.uartclk != BASE_BAUD * 16) + esp32_uart_set_baud(&device->port, device->baud); + + return 0; +} + +static int __init esp32_uart_early_console_setup(struct earlycon_device *device, + const char *options) +{ + device->port.private_data = (void *)&esp32_variant; + + return esp32xx_uart_early_console_setup(device, options); +} + +OF_EARLYCON_DECLARE(esp32uart, "esp,esp32-uart", + esp32_uart_early_console_setup); + +static int __init esp32s3_uart_early_console_setup(struct earlycon_device *device, + const char *options) +{ + device->port.private_data = (void *)&esp32s3_variant; + + return esp32xx_uart_early_console_setup(device, options); +} + +OF_EARLYCON_DECLARE(esp32s3uart, "esp,esp32s3-uart", + esp32s3_uart_early_console_setup); + +static struct uart_driver esp32_uart_reg = { + .owner = THIS_MODULE, + .driver_name = DRIVER_NAME, + .dev_name = DEV_NAME, + .nr = ARRAY_SIZE(esp32_uart_ports), + .cons = &esp32_uart_console, +}; + +static int esp32_uart_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + static const struct of_device_id *match; + struct uart_port *port; + struct esp32_port *sport; + struct resource *res; + int ret; + + match = of_match_device(esp32_uart_dt_ids, &pdev->dev); + if (!match) + return -ENODEV; + + sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); + if (!sport) + return -ENOMEM; + + port = &sport->port; + + ret = of_alias_get_id(np, "serial"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); + return ret; + } + if (ret >= UART_NR) { + dev_err(&pdev->dev, "driver limited to %d serial ports\n", UART_NR); + return -ENOMEM; + } + + port->line = ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + port->mapbase = res->start; + port->membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(port->membase)) + return PTR_ERR(port->membase); + + sport->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(sport->clk)) + return PTR_ERR(sport->clk); + + port->uartclk = clk_get_rate(sport->clk); + port->dev = &pdev->dev; + port->type = PORT_GENERIC; + port->iotype = UPIO_MEM; + port->irq = platform_get_irq(pdev, 0); + port->ops = &esp32_uart_pops; + port->flags = UPF_BOOT_AUTOCONF; + port->has_sysrq = 1; + port->fifosize = ESP32_UART_TX_FIFO_SIZE; + port->private_data = (void *)match->data; + + esp32_uart_ports[port->line] = sport; + + platform_set_drvdata(pdev, port); + + return uart_add_one_port(&esp32_uart_reg, port); +} + +static int esp32_uart_remove(struct platform_device *pdev) +{ + struct uart_port *port = platform_get_drvdata(pdev); + + uart_remove_one_port(&esp32_uart_reg, port); + + return 0; +} + + +static struct platform_driver esp32_uart_driver = { + .probe = esp32_uart_probe, + .remove = esp32_uart_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = esp32_uart_dt_ids, + }, +}; + +static int __init esp32_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&esp32_uart_reg); + if (ret) + return ret; + + ret = platform_driver_register(&esp32_uart_driver); + if (ret) + uart_unregister_driver(&esp32_uart_reg); + + return ret; +} + +static void __exit esp32_uart_exit(void) +{ + platform_driver_unregister(&esp32_uart_driver); + uart_unregister_driver(&esp32_uart_reg); +} + +module_init(esp32_uart_init); +module_exit(esp32_uart_exit); + +MODULE_AUTHOR("Max Filippov <jcmvbkbc@gmail.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c index 249cb380c3c6..3bdaf1ddc309 100644 --- a/drivers/tty/serial/fsl_linflexuart.c +++ b/drivers/tty/serial/fsl_linflexuart.c @@ -203,7 +203,7 @@ static irqreturn_t linflex_txint(int irq, void *dev_id) struct circ_buf *xmit = &sport->state->xmit; unsigned long flags; - spin_lock_irqsave(&sport->lock, flags); + uart_port_lock_irqsave(sport, &flags); if (sport->x_char) { linflex_put_char(sport, sport->x_char); @@ -217,7 +217,7 @@ static irqreturn_t linflex_txint(int irq, void *dev_id) linflex_transmit_buffer(sport); out: - spin_unlock_irqrestore(&sport->lock, flags); + uart_port_unlock_irqrestore(sport, flags); return IRQ_HANDLED; } @@ -230,7 +230,7 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id) unsigned char rx; bool brk; - spin_lock_irqsave(&sport->lock, flags); + uart_port_lock_irqsave(sport, &flags); status = readl(sport->membase + UARTSR); while (status & LINFLEXD_UARTSR_RMB) { @@ -266,7 +266,7 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id) } } - spin_unlock_irqrestore(&sport->lock, flags); + uart_port_unlock_irqrestore(sport, flags); tty_flip_buffer_push(port); @@ -369,11 +369,11 @@ static int linflex_startup(struct uart_port *port) int ret = 0; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); linflex_setup_watermark(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = devm_request_irq(port->dev, port->irq, linflex_int, 0, DRIVER_NAME, port); @@ -386,14 +386,14 @@ static void linflex_shutdown(struct uart_port *port) unsigned long ier; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* disable interrupts */ ier = readl(port->membase + LINIER); ier &= ~(LINFLEXD_LINIER_DRIE | LINFLEXD_LINIER_DTIE); writel(ier, port->membase + LINIER); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); devm_free_irq(port->dev, port->irq, port); } @@ -474,7 +474,7 @@ linflex_set_termios(struct uart_port *port, struct ktermios *termios, cr &= ~LINFLEXD_UARTCR_PCE; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->read_status_mask = 0; @@ -507,7 +507,7 @@ linflex_set_termios(struct uart_port *port, struct ktermios *termios, writel(cr1, port->membase + LINCR1); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *linflex_type(struct uart_port *port) @@ -646,14 +646,14 @@ linflex_console_write(struct console *co, const char *s, unsigned int count) if (sport->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&sport->lock, flags); + locked = uart_port_trylock_irqsave(sport, &flags); else - spin_lock_irqsave(&sport->lock, flags); + uart_port_lock_irqsave(sport, &flags); linflex_string_write(sport, s, count); if (locked) - spin_unlock_irqrestore(&sport->lock, flags); + uart_port_unlock_irqrestore(sport, flags); } /* @@ -832,10 +832,14 @@ static int linflex_probe(struct platform_device *pdev) return PTR_ERR(sport->membase); sport->mapbase = res->start; + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; + sport->dev = &pdev->dev; sport->type = PORT_LINFLEXUART; sport->iotype = UPIO_MEM; - sport->irq = platform_get_irq(pdev, 0); + sport->irq = ret; sport->ops = &linflex_pops; sport->flags = UPF_BOOT_AUTOCONF; sport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE); diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index f72e1340b47d..6d0cfb2e86b4 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -532,9 +532,9 @@ static void lpuart_dma_tx_complete(void *arg) struct dma_chan *chan = sport->dma_tx_chan; unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (!sport->dma_tx_in_progress) { - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return; } @@ -543,7 +543,7 @@ static void lpuart_dma_tx_complete(void *arg) uart_xmit_advance(&sport->port, sport->dma_tx_bytes); sport->dma_tx_in_progress = false; - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); @@ -553,12 +553,12 @@ static void lpuart_dma_tx_complete(void *arg) return; } - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (!lpuart_stopped_or_empty(&sport->port)) lpuart_dma_tx(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static dma_addr_t lpuart_dma_datareg_addr(struct lpuart_port *sport) @@ -651,7 +651,7 @@ static int lpuart_poll_init(struct uart_port *port) sport->port.fifosize = 0; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* Disable Rx & Tx */ writeb(0, sport->port.membase + UARTCR2); @@ -675,7 +675,7 @@ static int lpuart_poll_init(struct uart_port *port) /* Enable Rx and Tx */ writeb(UARTCR2_RE | UARTCR2_TE, sport->port.membase + UARTCR2); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return 0; } @@ -703,7 +703,7 @@ static int lpuart32_poll_init(struct uart_port *port) sport->port.fifosize = 0; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* Disable Rx & Tx */ lpuart32_write(&sport->port, 0, UARTCTRL); @@ -724,7 +724,7 @@ static int lpuart32_poll_init(struct uart_port *port) /* Enable Rx and Tx */ lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return 0; } @@ -879,9 +879,9 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static void lpuart_txint(struct lpuart_port *sport) { - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); lpuart_transmit_buffer(sport); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); } static void lpuart_rxint(struct lpuart_port *sport) @@ -890,7 +890,7 @@ static void lpuart_rxint(struct lpuart_port *sport) struct tty_port *port = &sport->port.state->port; unsigned char rx, sr; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); while (!(readb(sport->port.membase + UARTSFIFO) & UARTSFIFO_RXEMPT)) { flg = TTY_NORMAL; @@ -956,9 +956,9 @@ out: static void lpuart32_txint(struct lpuart_port *sport) { - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); lpuart32_transmit_buffer(sport); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); } static void lpuart32_rxint(struct lpuart_port *sport) @@ -968,7 +968,7 @@ static void lpuart32_rxint(struct lpuart_port *sport) unsigned long rx, sr; bool is_break; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); while (!(lpuart32_read(&sport->port, UARTFIFO) & UARTFIFO_RXEMPT)) { flg = TTY_NORMAL; @@ -1170,12 +1170,12 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) async_tx_ack(sport->dma_rx_desc); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); dmastat = dmaengine_tx_status(chan, sport->dma_rx_cookie, &state); if (dmastat == DMA_ERROR) { dev_err(sport->port.dev, "Rx DMA transfer failed!\n"); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return; } @@ -1244,7 +1244,7 @@ exit: dma_sync_sg_for_device(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); tty_flip_buffer_push(port); if (!sport->dma_idle_int) @@ -1335,9 +1335,9 @@ static void lpuart_timer_func(struct timer_list *t) mod_timer(&sport->lpuart_timer, jiffies + sport->dma_rx_timeout); - if (spin_trylock_irqsave(&sport->port.lock, flags)) { + if (uart_port_trylock_irqsave(&sport->port, &flags)) { sport->last_residue = state.residue; - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } } @@ -1802,14 +1802,14 @@ static void lpuart_hw_setup(struct lpuart_port *sport) { unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); lpuart_setup_watermark_enable(sport); lpuart_rx_dma_startup(sport); lpuart_tx_dma_startup(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static int lpuart_startup(struct uart_port *port) @@ -1859,7 +1859,7 @@ static void lpuart32_hw_setup(struct lpuart_port *sport) { unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); lpuart32_hw_disable(sport); @@ -1869,7 +1869,7 @@ static void lpuart32_hw_setup(struct lpuart_port *sport) lpuart32_setup_watermark_enable(sport); lpuart32_configure(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static int lpuart32_startup(struct uart_port *port) @@ -1932,7 +1932,7 @@ static void lpuart_shutdown(struct uart_port *port) unsigned char temp; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* disable Rx/Tx and interrupts */ temp = readb(port->membase + UARTCR2); @@ -1940,7 +1940,7 @@ static void lpuart_shutdown(struct uart_port *port) UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE); writeb(temp, port->membase + UARTCR2); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); lpuart_dma_shutdown(sport); } @@ -1952,7 +1952,7 @@ static void lpuart32_shutdown(struct uart_port *port) unsigned long temp; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* clear status */ temp = lpuart32_read(&sport->port, UARTSTAT); @@ -1969,7 +1969,7 @@ static void lpuart32_shutdown(struct uart_port *port) UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE | UARTCTRL_SBK); lpuart32_write(port, temp, UARTCTRL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); lpuart_dma_shutdown(sport); } @@ -2069,7 +2069,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, if (old && sport->lpuart_dma_rx_use) lpuart_dma_rx_free(&sport->port); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) @@ -2124,7 +2124,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, sport->lpuart_dma_rx_use = false; } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static void __lpuart32_serial_setbrg(struct uart_port *port, @@ -2304,7 +2304,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, if (old && sport->lpuart_dma_rx_use) lpuart_dma_rx_free(&sport->port); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) @@ -2359,7 +2359,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, sport->lpuart_dma_rx_use = false; } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static const char *lpuart_type(struct uart_port *port) @@ -2477,9 +2477,9 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count) int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&sport->port.lock, flags); + locked = uart_port_trylock_irqsave(&sport->port, &flags); else - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* first save CR2 and then disable interrupts */ cr2 = old_cr2 = readb(sport->port.membase + UARTCR2); @@ -2495,7 +2495,7 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count) writeb(old_cr2, sport->port.membase + UARTCR2); if (locked) - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static void @@ -2507,9 +2507,9 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count) int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&sport->port.lock, flags); + locked = uart_port_trylock_irqsave(&sport->port, &flags); else - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* first save CR2 and then disable interrupts */ cr = old_cr = lpuart32_read(&sport->port, UARTCTRL); @@ -2525,7 +2525,7 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count) lpuart32_write(&sport->port, old_cr, UARTCTRL); if (locked) - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } /* @@ -3089,7 +3089,7 @@ static int lpuart_suspend(struct device *dev) uart_suspend_port(&lpuart_reg, &sport->port); if (lpuart_uport_is_active(sport)) { - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (lpuart_is_32(sport)) { /* disable Rx/Tx and interrupts */ temp = lpuart32_read(&sport->port, UARTCTRL); @@ -3101,7 +3101,7 @@ static int lpuart_suspend(struct device *dev) temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE); writeb(temp, sport->port.membase + UARTCR2); } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); if (sport->lpuart_dma_rx_use) { /* @@ -3114,7 +3114,7 @@ static int lpuart_suspend(struct device *dev) lpuart_dma_rx_free(&sport->port); /* Disable Rx DMA to use UART port as wakeup source */ - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (lpuart_is_32(sport)) { temp = lpuart32_read(&sport->port, UARTBAUD); lpuart32_write(&sport->port, temp & ~UARTBAUD_RDMAE, @@ -3123,11 +3123,11 @@ static int lpuart_suspend(struct device *dev) writeb(readb(sport->port.membase + UARTCR5) & ~UARTCR5_RDMAS, sport->port.membase + UARTCR5); } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } if (sport->lpuart_dma_tx_use) { - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (lpuart_is_32(sport)) { temp = lpuart32_read(&sport->port, UARTBAUD); temp &= ~UARTBAUD_TDMAE; @@ -3137,7 +3137,7 @@ static int lpuart_suspend(struct device *dev) temp &= ~UARTCR5_TDMAS; writeb(temp, sport->port.membase + UARTCR5); } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); sport->dma_tx_in_progress = false; dmaengine_terminate_sync(sport->dma_tx_chan); } diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 819f957b6b84..a75eafbcbea3 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -929,7 +929,7 @@ static inline void check_modem_status(struct icom_port *icom_port) char delta_status; unsigned char status; - spin_lock(&icom_port->uart_port.lock); + uart_port_lock(&icom_port->uart_port); /*modem input register */ status = readb(&icom_port->dram->isr); @@ -951,7 +951,7 @@ static inline void check_modem_status(struct icom_port *icom_port) port.delta_msr_wait); old_status = status; } - spin_unlock(&icom_port->uart_port.lock); + uart_port_unlock(&icom_port->uart_port); } static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port) @@ -1093,7 +1093,7 @@ static void process_interrupt(u16 port_int_reg, struct icom_port *icom_port) { - spin_lock(&icom_port->uart_port.lock); + uart_port_lock(&icom_port->uart_port); trace(icom_port, "INTERRUPT", port_int_reg); if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED)) @@ -1102,7 +1102,7 @@ static void process_interrupt(u16 port_int_reg, if (port_int_reg & INT_RCV_COMPLETED) recv_interrupt(port_int_reg, icom_port); - spin_unlock(&icom_port->uart_port.lock); + uart_port_unlock(&icom_port->uart_port); } static irqreturn_t icom_interrupt(int irq, void *dev_id) @@ -1186,14 +1186,14 @@ static unsigned int icom_tx_empty(struct uart_port *port) int ret; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (le16_to_cpu(icom_port->statStg->xmit[0].flags) & SA_FLAGS_READY_TO_XMIT) ret = TIOCSER_TEMT; else ret = 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return ret; } @@ -1276,7 +1276,7 @@ static void icom_send_xchar(struct uart_port *port, char ch) /* wait .1 sec to send char */ for (index = 0; index < 10; index++) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); xdata = readb(&icom_port->dram->xchar); if (xdata == 0x00) { trace(icom_port, "QUICK_WRITE", 0); @@ -1284,10 +1284,10 @@ static void icom_send_xchar(struct uart_port *port, char ch) /* flush write operation */ xdata = readb(&icom_port->dram->xchar); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); break; } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); msleep(10); } } @@ -1307,7 +1307,7 @@ static void icom_break(struct uart_port *port, int break_state) unsigned char cmdReg; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); trace(icom_port, "BREAK", 0); cmdReg = readb(&icom_port->dram->CmdReg); if (break_state == -1) { @@ -1315,7 +1315,7 @@ static void icom_break(struct uart_port *port, int break_state) } else { writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int icom_open(struct uart_port *port) @@ -1365,7 +1365,7 @@ static void icom_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long offset; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); trace(icom_port, "CHANGE_SPEED", 0); cflag = termios->c_cflag; @@ -1516,7 +1516,7 @@ static void icom_set_termios(struct uart_port *port, struct ktermios *termios, trace(icom_port, "XR_ENAB", 0); writeb(CMD_XMIT_RCV_ENABLE, &icom_port->dram->CmdReg); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *icom_type(struct uart_port *port) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 13cb78340709..708b9852a575 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -177,8 +177,6 @@ enum imx_uart_type { IMX1_UART, IMX21_UART, - IMX53_UART, - IMX6Q_UART, }; /* device type dependent stuff */ @@ -240,30 +238,26 @@ struct imx_port_ucrs { unsigned int ucr3; }; -static struct imx_uart_data imx_uart_devdata[] = { - [IMX1_UART] = { - .uts_reg = IMX1_UTS, - .devtype = IMX1_UART, - }, - [IMX21_UART] = { - .uts_reg = IMX21_UTS, - .devtype = IMX21_UART, - }, - [IMX53_UART] = { - .uts_reg = IMX21_UTS, - .devtype = IMX53_UART, - }, - [IMX6Q_UART] = { - .uts_reg = IMX21_UTS, - .devtype = IMX6Q_UART, - }, +static const struct imx_uart_data imx_uart_imx1_devdata = { + .uts_reg = IMX1_UTS, + .devtype = IMX1_UART, +}; + +static const struct imx_uart_data imx_uart_imx21_devdata = { + .uts_reg = IMX21_UTS, + .devtype = IMX21_UART, }; static const struct of_device_id imx_uart_dt_ids[] = { - { .compatible = "fsl,imx6q-uart", .data = &imx_uart_devdata[IMX6Q_UART], }, - { .compatible = "fsl,imx53-uart", .data = &imx_uart_devdata[IMX53_UART], }, - { .compatible = "fsl,imx1-uart", .data = &imx_uart_devdata[IMX1_UART], }, - { .compatible = "fsl,imx21-uart", .data = &imx_uart_devdata[IMX21_UART], }, + /* + * For reasons unknown to me, some UART devices (e.g. imx6ul's) are + * compatible to fsl,imx6q-uart, but not fsl,imx21-uart, while the + * original imx6q's UART is compatible to fsl,imx21-uart. This driver + * doesn't make any distinction between these two variants. + */ + { .compatible = "fsl,imx6q-uart", .data = &imx_uart_imx21_devdata, }, + { .compatible = "fsl,imx1-uart", .data = &imx_uart_imx1_devdata, }, + { .compatible = "fsl,imx21-uart", .data = &imx_uart_imx21_devdata, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, imx_uart_dt_ids); @@ -575,7 +569,7 @@ static void imx_uart_dma_tx_callback(void *data) unsigned long flags; u32 ucr1; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); @@ -600,7 +594,7 @@ static void imx_uart_dma_tx_callback(void *data) imx_uart_writel(sport, ucr4, UCR4); } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } /* called with port.lock taken and irqs off */ @@ -766,11 +760,11 @@ static irqreturn_t imx_uart_rtsint(int irq, void *dev_id) struct imx_port *sport = dev_id; irqreturn_t ret; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); ret = __imx_uart_rtsint(irq, dev_id); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return ret; } @@ -779,9 +773,9 @@ static irqreturn_t imx_uart_txint(int irq, void *dev_id) { struct imx_port *sport = dev_id; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); imx_uart_transmit_buffer(sport); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return IRQ_HANDLED; } @@ -895,11 +889,11 @@ static irqreturn_t imx_uart_rxint(int irq, void *dev_id) struct imx_port *sport = dev_id; irqreturn_t ret; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); ret = __imx_uart_rxint(irq, dev_id); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return ret; } @@ -962,7 +956,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id) unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4; irqreturn_t ret = IRQ_NONE; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); usr1 = imx_uart_readl(sport, USR1); usr2 = imx_uart_readl(sport, USR2); @@ -1032,7 +1026,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id) ret = IRQ_HANDLED; } - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return ret; } @@ -1115,7 +1109,7 @@ static void imx_uart_break_ctl(struct uart_port *port, int break_state) unsigned long flags; u32 ucr1; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); ucr1 = imx_uart_readl(sport, UCR1) & ~UCR1_SNDBRK; @@ -1124,7 +1118,7 @@ static void imx_uart_break_ctl(struct uart_port *port, int break_state) imx_uart_writel(sport, ucr1, UCR1); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } /* @@ -1137,9 +1131,9 @@ static void imx_uart_timeout(struct timer_list *t) unsigned long flags; if (sport->port.state) { - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); imx_uart_mctrl_check(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); } @@ -1169,9 +1163,9 @@ static void imx_uart_dma_rx_callback(void *data) status = dmaengine_tx_status(chan, sport->rx_cookie, &state); if (status == DMA_ERROR) { - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); imx_uart_clear_rx_errors(sport); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return; } @@ -1200,9 +1194,9 @@ static void imx_uart_dma_rx_callback(void *data) r_bytes = rx_ring->head - rx_ring->tail; /* If we received something, check for 0xff flood */ - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); imx_uart_check_flood(sport, imx_uart_readl(sport, USR2)); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); if (!(sport->port.ignore_status_mask & URXD_DUMMY_READ)) { @@ -1457,10 +1451,12 @@ static int imx_uart_startup(struct uart_port *port) imx_uart_writel(sport, ucr4 & ~UCR4_DREN, UCR4); /* Can we enable the DMA support? */ - if (!uart_console(port) && imx_uart_dma_init(sport) == 0) + if (!uart_console(port) && imx_uart_dma_init(sport) == 0) { + lockdep_set_subclass(&port->lock, 1); dma_is_inited = 1; + } - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* Reset fifo's and state machines */ imx_uart_soft_reset(sport); @@ -1533,7 +1529,7 @@ static int imx_uart_startup(struct uart_port *port) imx_uart_disable_loopback_rs485(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return 0; } @@ -1558,21 +1554,21 @@ static void imx_uart_shutdown(struct uart_port *port) sport->dma_is_rxing = 0; } - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); imx_uart_stop_tx(port); imx_uart_stop_rx(port); imx_uart_disable_dma(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); imx_uart_dma_exit(sport); } mctrl_gpio_disable_ms(sport->gpios); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); ucr2 = imx_uart_readl(sport, UCR2); ucr2 &= ~(UCR2_TXEN | UCR2_ATEN); imx_uart_writel(sport, ucr2, UCR2); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); /* * Stop our timer. @@ -1583,7 +1579,7 @@ static void imx_uart_shutdown(struct uart_port *port) * Disable all interrupts, port and break condition. */ - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); ucr1 = imx_uart_readl(sport, UCR1); ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_RXDMAEN | @@ -1605,7 +1601,7 @@ static void imx_uart_shutdown(struct uart_port *port) ucr4 &= ~UCR4_TCEN; imx_uart_writel(sport, ucr4, UCR4); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); clk_disable_unprepare(sport->clk_per); clk_disable_unprepare(sport->clk_ipg); @@ -1668,7 +1664,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); quot = uart_get_divisor(port, baud); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* * Read current UCR2 and save it for future use, then clear all the bits @@ -1796,7 +1792,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) imx_uart_enable_ms(&sport->port); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static const char *imx_uart_type(struct uart_port *port) @@ -1858,7 +1854,7 @@ static int imx_uart_poll_init(struct uart_port *port) imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* * Be careful about the order of enabling bits here. First enable the @@ -1886,7 +1882,7 @@ static int imx_uart_poll_init(struct uart_port *port) imx_uart_writel(sport, ucr1 | UCR1_RRDYEN, UCR1); imx_uart_writel(sport, ucr2 | UCR2_ATEN, UCR2); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return 0; } @@ -2005,9 +2001,9 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) if (sport->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&sport->port.lock, flags); + locked = uart_port_trylock_irqsave(&sport->port, &flags); else - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* * First, save UCR1/2/3 and then disable interrupts @@ -2035,7 +2031,7 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) imx_uart_ucrs_restore(sport, &old_ucr); if (locked) - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } /* @@ -2193,10 +2189,10 @@ static enum hrtimer_restart imx_trigger_start_tx(struct hrtimer *t) struct imx_port *sport = container_of(t, struct imx_port, trigger_start_tx); unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (sport->tx_state == WAIT_AFTER_RTS) imx_uart_start_tx(&sport->port); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return HRTIMER_NORESTART; } @@ -2206,10 +2202,10 @@ static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) struct imx_port *sport = container_of(t, struct imx_port, trigger_stop_tx); unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (sport->tx_state == WAIT_AFTER_SEND) imx_uart_stop_tx(&sport->port); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return HRTIMER_NORESTART; } @@ -2482,9 +2478,9 @@ static void imx_uart_restore_context(struct imx_port *sport) { unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (!sport->context_saved) { - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return; } @@ -2499,7 +2495,7 @@ static void imx_uart_restore_context(struct imx_port *sport) imx_uart_writel(sport, sport->saved_reg[2], UCR3); imx_uart_writel(sport, sport->saved_reg[3], UCR4); sport->context_saved = false; - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static void imx_uart_save_context(struct imx_port *sport) @@ -2507,7 +2503,7 @@ static void imx_uart_save_context(struct imx_port *sport) unsigned long flags; /* Save necessary regs */ - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sport->saved_reg[0] = imx_uart_readl(sport, UCR1); sport->saved_reg[1] = imx_uart_readl(sport, UCR2); sport->saved_reg[2] = imx_uart_readl(sport, UCR3); @@ -2519,7 +2515,7 @@ static void imx_uart_save_context(struct imx_port *sport) sport->saved_reg[8] = imx_uart_readl(sport, UBMR); sport->saved_reg[9] = imx_uart_readl(sport, IMX21_UTS); sport->context_saved = true; - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static void imx_uart_enable_wakeup(struct imx_port *sport, bool on) diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 845ff706bc59..320b29cd4683 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -432,7 +432,7 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) unsigned char r3; bool push = false; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); r3 = read_zsreg(channel, R3); /* Channel A */ @@ -448,7 +448,7 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) if (r3 & CHATxIP) ip22zilog_transmit_chars(up, channel); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); if (push) tty_flip_buffer_push(&up->port.state->port); @@ -458,7 +458,7 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) channel = ZILOG_CHANNEL_FROM_PORT(&up->port); push = false; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { writeb(RES_H_IUS, &channel->control); ZSDELAY(); @@ -471,7 +471,7 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) if (r3 & CHBTxIP) ip22zilog_transmit_chars(up, channel); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); if (push) tty_flip_buffer_push(&up->port.state->port); @@ -504,11 +504,11 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port) unsigned char status; unsigned int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = ip22zilog_read_channel_status(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; @@ -664,7 +664,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state) else clear_bits |= SND_BRK; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); new_reg = (up->curregs[R5] | set_bits) & ~clear_bits; if (new_reg != up->curregs[R5]) { @@ -674,7 +674,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state) write_zsreg(channel, R5, up->curregs[R5]); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void __ip22zilog_reset(struct uart_ip22zilog_port *up) @@ -735,9 +735,9 @@ static int ip22zilog_startup(struct uart_port *port) if (ZS_IS_CONS(up)) return 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); __ip22zilog_startup(up); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -775,7 +775,7 @@ static void ip22zilog_shutdown(struct uart_port *port) if (ZS_IS_CONS(up)) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); channel = ZILOG_CHANNEL_FROM_PORT(port); @@ -788,7 +788,7 @@ static void ip22zilog_shutdown(struct uart_port *port) up->curregs[R5] &= ~SND_BRK; ip22zilog_maybe_update_regs(up, channel); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Shared by TTY driver and serial console setup. The port lock is held @@ -880,7 +880,7 @@ ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 1200, 76800); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); @@ -894,7 +894,7 @@ ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios, ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port)); uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static const char *ip22zilog_type(struct uart_port *port) @@ -1016,10 +1016,10 @@ ip22zilog_console_write(struct console *con, const char *s, unsigned int count) struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index]; unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); uart_console_write(&up->port, s, count, ip22zilog_put_char); udelay(2); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int __init ip22zilog_console_setup(struct console *con, char *options) @@ -1034,13 +1034,13 @@ static int __init ip22zilog_console_setup(struct console *con, char *options) printk(KERN_INFO "Console: ttyS%d (IP22-Zilog)\n", con->index); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->curregs[R15] |= BRKIE; __ip22zilog_startup(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 0c78f66276cd..2bd640428970 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -816,9 +816,9 @@ static void neo_parse_isr(struct jsm_board *brd, u32 port) /* Parse any modem signal changes */ jsm_dbg(INTR, &ch->ch_bd->pci_dev, "MOD_STAT: sending to parse_modem_sigs\n"); - spin_lock_irqsave(&ch->uart_port.lock, lock_flags); + uart_port_lock_irqsave(&ch->uart_port, &lock_flags); neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); - spin_unlock_irqrestore(&ch->uart_port.lock, lock_flags); + uart_port_unlock_irqrestore(&ch->uart_port, lock_flags); } } diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 222afc270c88..ce0fef7e2c66 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -152,14 +152,14 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) container_of(port, struct jsm_channel, uart_port); struct ktermios *termios; - spin_lock_irqsave(&port->lock, lock_flags); + uart_port_lock_irqsave(port, &lock_flags); termios = &port->state->port.tty->termios; if (ch == termios->c_cc[VSTART]) channel->ch_bd->bd_ops->send_start_character(channel); if (ch == termios->c_cc[VSTOP]) channel->ch_bd->bd_ops->send_stop_character(channel); - spin_unlock_irqrestore(&port->lock, lock_flags); + uart_port_unlock_irqrestore(port, lock_flags); } static void jsm_tty_stop_rx(struct uart_port *port) @@ -176,13 +176,13 @@ static void jsm_tty_break(struct uart_port *port, int break_state) struct jsm_channel *channel = container_of(port, struct jsm_channel, uart_port); - spin_lock_irqsave(&port->lock, lock_flags); + uart_port_lock_irqsave(port, &lock_flags); if (break_state == -1) channel->ch_bd->bd_ops->send_break(channel); else channel->ch_bd->bd_ops->clear_break(channel); - spin_unlock_irqrestore(&port->lock, lock_flags); + uart_port_unlock_irqrestore(port, lock_flags); } static int jsm_tty_open(struct uart_port *port) @@ -241,7 +241,7 @@ static int jsm_tty_open(struct uart_port *port) channel->ch_cached_lsr = 0; channel->ch_stops_sent = 0; - spin_lock_irqsave(&port->lock, lock_flags); + uart_port_lock_irqsave(port, &lock_flags); termios = &port->state->port.tty->termios; channel->ch_c_cflag = termios->c_cflag; channel->ch_c_iflag = termios->c_iflag; @@ -261,7 +261,7 @@ static int jsm_tty_open(struct uart_port *port) jsm_carrier(channel); channel->ch_open_count++; - spin_unlock_irqrestore(&port->lock, lock_flags); + uart_port_unlock_irqrestore(port, lock_flags); jsm_dbg(OPEN, &channel->ch_bd->pci_dev, "finish\n"); return 0; @@ -307,7 +307,7 @@ static void jsm_tty_set_termios(struct uart_port *port, struct jsm_channel *channel = container_of(port, struct jsm_channel, uart_port); - spin_lock_irqsave(&port->lock, lock_flags); + uart_port_lock_irqsave(port, &lock_flags); channel->ch_c_cflag = termios->c_cflag; channel->ch_c_iflag = termios->c_iflag; channel->ch_c_oflag = termios->c_oflag; @@ -317,7 +317,7 @@ static void jsm_tty_set_termios(struct uart_port *port, channel->ch_bd->bd_ops->param(channel); jsm_carrier(channel); - spin_unlock_irqrestore(&port->lock, lock_flags); + uart_port_unlock_irqrestore(port, lock_flags); } static const char *jsm_tty_type(struct uart_port *port) diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c index d881cdd2a58f..a25ab1efe38f 100644 --- a/drivers/tty/serial/liteuart.c +++ b/drivers/tty/serial/liteuart.c @@ -139,13 +139,13 @@ static irqreturn_t liteuart_interrupt(int irq, void *data) * if polling, the context would be "in_serving_softirq", so use * irq[save|restore] spin_lock variants to cover all possibilities */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); isr = litex_read8(port->membase + OFF_EV_PENDING) & uart->irq_reg; if (isr & EV_RX) liteuart_rx_chars(port); if (isr & EV_TX) liteuart_tx_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_RETVAL(isr); } @@ -195,10 +195,10 @@ static int liteuart_startup(struct uart_port *port) } } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* only enabling rx irqs during startup */ liteuart_update_irq_reg(port, true, EV_RX); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (!port->irq) { timer_setup(&uart->timer, liteuart_timer, 0); @@ -213,9 +213,9 @@ static void liteuart_shutdown(struct uart_port *port) struct liteuart_port *uart = to_liteuart_port(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); liteuart_update_irq_reg(port, false, EV_RX | EV_TX); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (port->irq) free_irq(port->irq, port); @@ -229,13 +229,13 @@ static void liteuart_set_termios(struct uart_port *port, struct ktermios *new, unsigned int baud; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* update baudrate */ baud = uart_get_baud_rate(port, new, old, 0, 460800); uart_update_timeout(port, new->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *liteuart_type(struct uart_port *port) @@ -382,9 +382,9 @@ static void liteuart_console_write(struct console *co, const char *s, uart = (struct liteuart_port *)xa_load(&liteuart_array, co->index); port = &uart->port; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_console_write(port, s, count, liteuart_putchar); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int liteuart_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index b38fe4728c26..5149a947b7fe 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -140,15 +140,15 @@ static void lpc32xx_hsuart_console_write(struct console *co, const char *s, if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); + locked = uart_port_trylock(&up->port); else - spin_lock(&up->port.lock); + uart_port_lock(&up->port); uart_console_write(&up->port, s, count, lpc32xx_hsuart_console_putchar); wait_for_xmit_empty(&up->port); if (locked) - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); local_irq_restore(flags); } @@ -298,7 +298,7 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) struct tty_port *tport = &port->state->port; u32 status; - spin_lock(&port->lock); + uart_port_lock(port); /* Read UART status and clear latched interrupts */ status = readl(LPC32XX_HSUART_IIR(port->membase)); @@ -333,7 +333,7 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) __serial_lpc32xx_tx(port); } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -404,14 +404,14 @@ static void serial_lpc32xx_break_ctl(struct uart_port *port, unsigned long flags; u32 tmp; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); if (break_state != 0) tmp |= LPC32XX_HSU_BREAK; else tmp &= ~LPC32XX_HSU_BREAK; writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* port->lock is not held. */ @@ -421,7 +421,7 @@ static int serial_lpc32xx_startup(struct uart_port *port) unsigned long flags; u32 tmp; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); __serial_uart_flush(port); @@ -441,7 +441,7 @@ static int serial_lpc32xx_startup(struct uart_port *port) lpc32xx_loopback_set(port->mapbase, 0); /* get out of loopback mode */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); retval = request_irq(port->irq, serial_lpc32xx_interrupt, 0, MODNAME, port); @@ -458,7 +458,7 @@ static void serial_lpc32xx_shutdown(struct uart_port *port) u32 tmp; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B; @@ -466,7 +466,7 @@ static void serial_lpc32xx_shutdown(struct uart_port *port) lpc32xx_loopback_set(port->mapbase, 1); /* go to loopback mode */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -491,7 +491,7 @@ static void serial_lpc32xx_set_termios(struct uart_port *port, quot = __serial_get_clock_div(port->uartclk, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Ignore characters? */ tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); @@ -505,7 +505,7 @@ static void serial_lpc32xx_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) diff --git a/drivers/tty/serial/ma35d1_serial.c b/drivers/tty/serial/ma35d1_serial.c index 465b1def9e11..a6a7c405892e 100644 --- a/drivers/tty/serial/ma35d1_serial.c +++ b/drivers/tty/serial/ma35d1_serial.c @@ -269,16 +269,16 @@ static void receive_chars(struct uart_ma35d1_port *up) if (uart_handle_sysrq_char(&up->port, ch)) continue; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); uart_insert_char(&up->port, fsr, MA35_FSR_RX_OVER_IF, ch, flag); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); fsr = serial_in(up, MA35_FSR_REG); } while (!(fsr & MA35_FSR_RX_EMPTY) && (max_count-- > 0)); - spin_lock(&up->port.lock); + uart_port_lock(&up->port); tty_flip_buffer_push(&up->port.state->port); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); } static irqreturn_t ma35d1serial_interrupt(int irq, void *dev_id) @@ -364,14 +364,14 @@ static void ma35d1serial_break_ctl(struct uart_port *port, int break_state) unsigned long flags; u32 lcr; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); lcr = serial_in(up, MA35_LCR_REG); if (break_state != 0) lcr |= MA35_LCR_BREAK; else lcr &= ~MA35_LCR_BREAK; serial_out(up, MA35_LCR_REG, lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int ma35d1serial_startup(struct uart_port *port) @@ -441,7 +441,7 @@ static void ma35d1serial_set_termios(struct uart_port *port, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.read_status_mask = MA35_FSR_RX_OVER_IF; if (termios->c_iflag & INPCK) @@ -475,7 +475,7 @@ static void ma35d1serial_set_termios(struct uart_port *port, serial_out(up, MA35_LCR_REG, lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static const char *ma35d1serial_type(struct uart_port *port) @@ -560,9 +560,9 @@ static void ma35d1serial_console_write(struct console *co, const char *s, u32 co if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); + locked = uart_port_trylock_irqsave(&up->port, &flags); else - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * First save the IER then disable the interrupts @@ -576,7 +576,7 @@ static void ma35d1serial_console_write(struct console *co, const char *s, u32 co serial_out(up, MA35_IER_REG, ier); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int __init ma35d1serial_console_setup(struct console *co, char *options) @@ -695,6 +695,9 @@ static int ma35d1serial_probe(struct platform_device *pdev) up->port.iobase = res_mem->start; up->port.membase = ioremap(up->port.iobase, MA35_UART_REG_SIZE); + if (!up->port.membase) + return -ENOMEM; + up->port.ops = &ma35d1serial_ops; spin_lock_init(&up->port.lock); diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index db3204d2a305..97e4965b73d4 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -402,7 +402,7 @@ static int max14830_detect(struct device *dev) ret = s->if_cfg->extended_reg_enable(dev, true); if (ret) return ret; - + regmap_read(s->regmap, s->if_cfg->rev_id_reg, &val); s->if_cfg->extended_reg_enable(dev, false); if (((val & MAX310x_REV_MASK) != MAX14830_REV_ID)) { diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index 1666ce012e5e..91b15243f6c6 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -135,12 +135,12 @@ static void mcf_break_ctl(struct uart_port *port, int break_state) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (break_state == -1) writeb(MCFUART_UCR_CMDBREAKSTART, port->membase + MCFUART_UCR); else writeb(MCFUART_UCR_CMDBREAKSTOP, port->membase + MCFUART_UCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /****************************************************************************/ @@ -150,7 +150,7 @@ static int mcf_startup(struct uart_port *port) struct mcf_uart *pp = container_of(port, struct mcf_uart, port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Reset UART, get it into known state... */ writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); @@ -164,7 +164,7 @@ static int mcf_startup(struct uart_port *port) pp->imr = MCFUART_UIR_RXREADY; writeb(pp->imr, port->membase + MCFUART_UIMR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -176,7 +176,7 @@ static void mcf_shutdown(struct uart_port *port) struct mcf_uart *pp = container_of(port, struct mcf_uart, port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable all interrupts now */ pp->imr = 0; @@ -186,7 +186,7 @@ static void mcf_shutdown(struct uart_port *port) writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /****************************************************************************/ @@ -252,7 +252,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, mr2 |= MCFUART_MR2_TXCTS; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); mr2 |= MCFUART_MR2_TXRTS; @@ -273,7 +273,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, port->membase + MCFUART_UCSR); writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /****************************************************************************/ @@ -350,7 +350,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data) isr = readb(port->membase + MCFUART_UISR) & pp->imr; - spin_lock(&port->lock); + uart_port_lock(port); if (isr & MCFUART_UIR_RXREADY) { mcf_rx_chars(pp); ret = IRQ_HANDLED; @@ -359,7 +359,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data) mcf_tx_chars(pp); ret = IRQ_HANDLED; } - spin_unlock(&port->lock); + uart_port_unlock(port); return ret; } diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index d2502aaa3e8c..8048fa542fc4 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -392,7 +392,7 @@ static irqreturn_t men_z135_intr(int irq, void *data) if (!irq_id) goto out; - spin_lock(&port->lock); + uart_port_lock(port); /* It's save to write to IIR[7:6] RXC[9:8] */ iowrite8(irq_id, port->membase + MEN_Z135_STAT_REG); @@ -418,7 +418,7 @@ static irqreturn_t men_z135_intr(int irq, void *data) handled = true; } - spin_unlock(&port->lock); + uart_port_unlock(port); out: return IRQ_RETVAL(handled); } @@ -708,7 +708,7 @@ static void men_z135_set_termios(struct uart_port *port, baud = uart_get_baud_rate(port, termios, old, 0, uart_freq / 16); - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); @@ -716,7 +716,7 @@ static void men_z135_set_termios(struct uart_port *port, iowrite32(bd_reg, port->membase + MEN_Z135_BAUD_REG); uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } static const char *men_z135_type(struct uart_port *port) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 790d910dafa5..8dd84617e715 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -129,14 +129,14 @@ static void meson_uart_shutdown(struct uart_port *port) free_irq(port->irq, port); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = readl(port->membase + AML_UART_CONTROL); val &= ~AML_UART_RX_EN; val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN); writel(val, port->membase + AML_UART_CONTROL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void meson_uart_start_tx(struct uart_port *port) @@ -238,7 +238,7 @@ static irqreturn_t meson_uart_interrupt(int irq, void *dev_id) { struct uart_port *port = (struct uart_port *)dev_id; - spin_lock(&port->lock); + uart_port_lock(port); if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)) meson_receive_chars(port); @@ -248,7 +248,7 @@ static irqreturn_t meson_uart_interrupt(int irq, void *dev_id) meson_uart_start_tx(port); } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -284,7 +284,7 @@ static int meson_uart_startup(struct uart_port *port) u32 val; int ret = 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = readl(port->membase + AML_UART_CONTROL); val |= AML_UART_CLEAR_ERR; @@ -301,7 +301,7 @@ static int meson_uart_startup(struct uart_port *port) val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2)); writel(val, port->membase + AML_UART_MISC); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = request_irq(port->irq, meson_uart_interrupt, 0, port->name, port); @@ -341,7 +341,7 @@ static void meson_uart_set_termios(struct uart_port *port, unsigned long flags; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); cflags = termios->c_cflag; iflags = termios->c_iflag; @@ -380,10 +380,14 @@ static void meson_uart_set_termios(struct uart_port *port, else val |= AML_UART_STOP_BIT_1SB; - if (cflags & CRTSCTS) - val &= ~AML_UART_TWO_WIRE_EN; - else + if (cflags & CRTSCTS) { + if (port->flags & UPF_HARD_FLOW) + val &= ~AML_UART_TWO_WIRE_EN; + else + termios->c_cflag &= ~CRTSCTS; + } else { val |= AML_UART_TWO_WIRE_EN; + } writel(val, port->membase + AML_UART_CONTROL); @@ -401,7 +405,7 @@ static void meson_uart_set_termios(struct uart_port *port, AML_UART_FRAME_ERR; uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int meson_uart_verify_port(struct uart_port *port, @@ -460,14 +464,14 @@ static int meson_uart_poll_get_char(struct uart_port *port) u32 c; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY) c = NO_POLL_CHAR; else c = readl(port->membase + AML_UART_RFIFO); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return c; } @@ -478,7 +482,7 @@ static void meson_uart_poll_put_char(struct uart_port *port, unsigned char c) u32 reg; int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Wait until FIFO is empty or timeout */ ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg, @@ -502,7 +506,7 @@ static void meson_uart_poll_put_char(struct uart_port *port, unsigned char c) dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n"); out: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #endif /* CONFIG_CONSOLE_POLL */ @@ -559,9 +563,9 @@ static void meson_serial_port_write(struct uart_port *port, const char *s, if (port->sysrq) { locked = 0; } else if (oops_in_progress) { - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); } else { - spin_lock(&port->lock); + uart_port_lock(port); locked = 1; } @@ -573,7 +577,7 @@ static void meson_serial_port_write(struct uart_port *port, const char *s, writel(val, port->membase + AML_UART_CONTROL); if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } @@ -646,8 +650,8 @@ meson_serial_early_console_setup(struct earlycon_device *device, const char *opt return 0; } -OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", - meson_serial_early_console_setup); +OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", meson_serial_early_console_setup); +OF_EARLYCON_DECLARE(meson, "amlogic,meson-s4-uart", meson_serial_early_console_setup); #define MESON_SERIAL_CONSOLE_PTR(_devname) (&meson_serial_console_##_devname) #else @@ -705,6 +709,7 @@ static int meson_uart_probe(struct platform_device *pdev) u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */ int ret = 0; int irq; + bool has_rtscts; if (pdev->dev.of_node) pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); @@ -732,6 +737,7 @@ static int meson_uart_probe(struct platform_device *pdev) return irq; of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize); + has_rtscts = of_property_read_bool(pdev->dev.of_node, "uart-has-rtscts"); if (meson_ports[pdev->id]) { return dev_err_probe(&pdev->dev, -EBUSY, @@ -762,6 +768,8 @@ static int meson_uart_probe(struct platform_device *pdev) port->mapsize = resource_size(res_mem); port->irq = irq; port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY; + if (has_rtscts) + port->flags |= UPF_HARD_FLOW; port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE); port->dev = &pdev->dev; port->line = pdev->id; diff --git a/drivers/tty/serial/milbeaut_usio.c b/drivers/tty/serial/milbeaut_usio.c index 70a910085e93..db3b81f2aa57 100644 --- a/drivers/tty/serial/milbeaut_usio.c +++ b/drivers/tty/serial/milbeaut_usio.c @@ -207,9 +207,9 @@ static irqreturn_t mlb_usio_rx_irq(int irq, void *dev_id) { struct uart_port *port = dev_id; - spin_lock(&port->lock); + uart_port_lock(port); mlb_usio_rx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -218,10 +218,10 @@ static irqreturn_t mlb_usio_tx_irq(int irq, void *dev_id) { struct uart_port *port = dev_id; - spin_lock(&port->lock); + uart_port_lock(port); if (readb(port->membase + MLB_USIO_REG_SSR) & MLB_USIO_SSR_TBI) mlb_usio_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -267,7 +267,7 @@ static int mlb_usio_startup(struct uart_port *port) escr = readb(port->membase + MLB_USIO_REG_ESCR); if (of_property_read_bool(port->dev->of_node, "auto-flow-control")) escr |= MLB_USIO_ESCR_FLWEN; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); writeb(0, port->membase + MLB_USIO_REG_SCR); writeb(escr, port->membase + MLB_USIO_REG_ESCR); writeb(MLB_USIO_SCR_UPCL, port->membase + MLB_USIO_REG_SCR); @@ -282,7 +282,7 @@ static int mlb_usio_startup(struct uart_port *port) writeb(MLB_USIO_SCR_TXE | MLB_USIO_SCR_RIE | MLB_USIO_SCR_TBIE | MLB_USIO_SCR_RXE, port->membase + MLB_USIO_REG_SCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -337,7 +337,7 @@ static void mlb_usio_set_termios(struct uart_port *port, else quot = 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = MLB_USIO_SSR_ORE | MLB_USIO_SSR_RDRF | MLB_USIO_SSR_TDRE; @@ -367,7 +367,7 @@ static void mlb_usio_set_termios(struct uart_port *port, writew(BIT(12), port->membase + MLB_USIO_REG_FBYTE); writeb(MLB_USIO_SCR_RIE | MLB_USIO_SCR_RXE | MLB_USIO_SCR_TBIE | MLB_USIO_SCR_TXE, port->membase + MLB_USIO_REG_SCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *mlb_usio_type(struct uart_port *port) diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 916507b8f31d..a252465e745f 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1096,14 +1096,14 @@ static void mpc52xx_uart_break_ctl(struct uart_port *port, int ctl) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (ctl == -1) psc_ops->command(port, MPC52xx_PSC_START_BRK); else psc_ops->command(port, MPC52xx_PSC_STOP_BRK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int @@ -1214,7 +1214,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, } /* Get the lock */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Do our best to flush TX & RX, so we don't lose anything */ /* But we don't wait indefinitely ! */ @@ -1250,7 +1250,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, psc_ops->command(port, MPC52xx_PSC_RX_ENABLE); /* We're all set, release the lock */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char * @@ -1477,11 +1477,11 @@ mpc52xx_uart_int(int irq, void *dev_id) struct uart_port *port = dev_id; irqreturn_t ret; - spin_lock(&port->lock); + uart_port_lock(port); ret = psc_ops->handle_irq(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return ret; } diff --git a/drivers/tty/serial/mps2-uart.c b/drivers/tty/serial/mps2-uart.c index ea5a7911cb15..2a4c09f3a834 100644 --- a/drivers/tty/serial/mps2-uart.c +++ b/drivers/tty/serial/mps2-uart.c @@ -188,12 +188,12 @@ static irqreturn_t mps2_uart_rxirq(int irq, void *data) if (unlikely(!(irqflag & UARTn_INT_RX))) return IRQ_NONE; - spin_lock(&port->lock); + uart_port_lock(port); mps2_uart_write8(port, UARTn_INT_RX, UARTn_INT); mps2_uart_rx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -206,12 +206,12 @@ static irqreturn_t mps2_uart_txirq(int irq, void *data) if (unlikely(!(irqflag & UARTn_INT_TX))) return IRQ_NONE; - spin_lock(&port->lock); + uart_port_lock(port); mps2_uart_write8(port, UARTn_INT_TX, UARTn_INT); mps2_uart_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -222,7 +222,7 @@ static irqreturn_t mps2_uart_oerrirq(int irq, void *data) struct uart_port *port = data; u8 irqflag = mps2_uart_read8(port, UARTn_INT); - spin_lock(&port->lock); + uart_port_lock(port); if (irqflag & UARTn_INT_RX_OVERRUN) { struct tty_port *tport = &port->state->port; @@ -244,7 +244,7 @@ static irqreturn_t mps2_uart_oerrirq(int irq, void *data) handled = IRQ_HANDLED; } - spin_unlock(&port->lock); + uart_port_unlock(port); return handled; } @@ -356,12 +356,12 @@ mps2_uart_set_termios(struct uart_port *port, struct ktermios *termios, bauddiv = DIV_ROUND_CLOSEST(port->uartclk, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); mps2_uart_write32(port, bauddiv, UARTn_BAUDDIV); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 90953e679e38..597264b546fd 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -444,7 +444,7 @@ static void msm_complete_tx_dma(void *args) unsigned int count; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Already stopped */ if (!dma->count) @@ -476,7 +476,7 @@ static void msm_complete_tx_dma(void *args) msm_handle_tx(port); done: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int msm_handle_tx_dma(struct msm_port *msm_port, unsigned int count) @@ -549,7 +549,7 @@ static void msm_complete_rx_dma(void *args) unsigned long flags; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Already stopped */ if (!dma->count) @@ -587,16 +587,16 @@ static void msm_complete_rx_dma(void *args) if (!(port->read_status_mask & MSM_UART_SR_RX_BREAK)) flag = TTY_NORMAL; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); sysrq = uart_handle_sysrq_char(port, dma->virt[i]); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (!sysrq) tty_insert_flip_char(tport, dma->virt[i], flag); } msm_start_rx_dma(msm_port); done: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (count) tty_flip_buffer_push(tport); @@ -762,9 +762,9 @@ static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr) if (!(port->read_status_mask & MSM_UART_SR_RX_BREAK)) flag = TTY_NORMAL; - spin_unlock(&port->lock); + uart_port_unlock(port); sysrq = uart_handle_sysrq_char(port, buf[i]); - spin_lock(&port->lock); + uart_port_lock(port); if (!sysrq) tty_insert_flip_char(tport, buf[i], flag); } @@ -824,9 +824,9 @@ static void msm_handle_rx(struct uart_port *port) else if (sr & MSM_UART_SR_PAR_FRAME_ERR) flag = TTY_FRAME; - spin_unlock(&port->lock); + uart_port_unlock(port); sysrq = uart_handle_sysrq_char(port, c); - spin_lock(&port->lock); + uart_port_lock(port); if (!sysrq) tty_insert_flip_char(tport, c, flag); } @@ -951,7 +951,7 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id) unsigned int misr; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); misr = msm_read(port, MSM_UART_MISR); msm_write(port, 0, MSM_UART_IMR); /* disable interrupt */ @@ -983,7 +983,7 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id) msm_handle_delta_cts(port); msm_write(port, msm_port->imr, MSM_UART_IMR); /* restore interrupt */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -1128,13 +1128,13 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud, unsigned long flags, rate; flags = *saved_flags; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); entry = msm_find_best_baud(port, baud, &rate); clk_set_rate(msm_port->clk, rate); baud = rate / 16 / entry->divisor; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); *saved_flags = flags; port->uartclk = rate; @@ -1266,7 +1266,7 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long flags; unsigned int baud, mr; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (dma->chan) /* Terminate if any */ msm_stop_dma(port, dma); @@ -1338,7 +1338,7 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios, /* Try to use DMA */ msm_start_rx_dma(msm_port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *msm_type(struct uart_port *port) @@ -1620,9 +1620,9 @@ static void __msm_console_write(struct uart_port *port, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); else - spin_lock(&port->lock); + uart_port_lock(port); if (is_uartdm) msm_reset_dm_count(port, count); @@ -1661,7 +1661,7 @@ static void __msm_console_write(struct uart_port *port, const char *s, } if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index ea924e9b913b..0255646bc175 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -187,9 +187,9 @@ static unsigned int mvebu_uart_tx_empty(struct uart_port *port) unsigned long flags; unsigned int st; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); st = readl(port->membase + UART_STAT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return (st & STAT_TX_EMP) ? TIOCSER_TEMT : 0; } @@ -249,14 +249,14 @@ static void mvebu_uart_break_ctl(struct uart_port *port, int brk) unsigned int ctl; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ctl = readl(port->membase + UART_CTRL(port)); if (brk == -1) ctl |= CTRL_SND_BRK_SEQ; else ctl &= ~CTRL_SND_BRK_SEQ; writel(ctl, port->membase + UART_CTRL(port)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void mvebu_uart_rx_chars(struct uart_port *port, unsigned int status) @@ -540,7 +540,7 @@ static void mvebu_uart_set_termios(struct uart_port *port, unsigned long flags; unsigned int baud, min_baud, max_baud; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->read_status_mask = STAT_RX_RDY(port) | STAT_OVR_ERR | STAT_TX_RDY(port) | STAT_TX_FIFO_FUL; @@ -589,7 +589,7 @@ static void mvebu_uart_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *mvebu_uart_type(struct uart_port *port) @@ -735,9 +735,9 @@ static void mvebu_uart_console_write(struct console *co, const char *s, int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ier = readl(port->membase + UART_CTRL(port)) & CTRL_BRK_INT; intr = readl(port->membase + UART_INTR(port)) & @@ -758,7 +758,7 @@ static void mvebu_uart_console_write(struct console *co, const char *s, } if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int mvebu_uart_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 0ead88c5a19a..ad4c1c5d0a7f 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -390,10 +390,10 @@ static void serial_omap_throttle(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void serial_omap_unthrottle(struct uart_port *port) @@ -401,10 +401,10 @@ static void serial_omap_unthrottle(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->ier |= UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static unsigned int check_modem_status(struct uart_omap_port *up) @@ -527,7 +527,7 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) irqreturn_t ret = IRQ_NONE; int max_count = 256; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); do { iir = serial_in(up, UART_IIR); @@ -563,7 +563,7 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) } } while (max_count--); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); tty_flip_buffer_push(&up->port.state->port); @@ -579,9 +579,9 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port) unsigned int ret = 0; dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->port.line); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return ret; } @@ -647,13 +647,13 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state) unsigned long flags; dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int serial_omap_startup(struct uart_port *port) @@ -701,13 +701,13 @@ static int serial_omap_startup(struct uart_port *port) * Now, initialize the UART */ serial_out(up, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Most PC uarts need OUT2 raised to enable interrupts. */ up->port.mctrl |= TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); up->msr_saved_flags = 0; /* @@ -742,10 +742,10 @@ static void serial_omap_shutdown(struct uart_port *port) up->ier = 0; serial_out(up, UART_IER, 0); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Disable break condition and FIFOs @@ -815,7 +815,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Update the per-port timeout. @@ -1013,7 +1013,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_omap_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); } @@ -1216,9 +1216,9 @@ serial_omap_console_write(struct console *co, const char *s, if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); + locked = uart_port_trylock(&up->port); else - spin_lock(&up->port.lock); + uart_port_lock(&up->port); /* * First save the IER then disable the interrupts @@ -1245,7 +1245,7 @@ serial_omap_console_write(struct console *co, const char *s, check_modem_status(up); if (locked) - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c index e99970a9437f..919f5e5aa0f1 100644 --- a/drivers/tty/serial/owl-uart.c +++ b/drivers/tty/serial/owl-uart.c @@ -125,12 +125,12 @@ static unsigned int owl_uart_tx_empty(struct uart_port *port) u32 val; unsigned int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = owl_uart_read(port, OWL_UART_STAT); ret = (val & OWL_UART_STAT_TFES) ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return ret; } @@ -232,7 +232,7 @@ static irqreturn_t owl_uart_irq(int irq, void *dev_id) unsigned long flags; u32 stat; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stat = owl_uart_read(port, OWL_UART_STAT); @@ -246,7 +246,7 @@ static irqreturn_t owl_uart_irq(int irq, void *dev_id) stat |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP; owl_uart_write(port, stat, OWL_UART_STAT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -256,14 +256,14 @@ static void owl_uart_shutdown(struct uart_port *port) u32 val; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = owl_uart_read(port, OWL_UART_CTL); val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_RXIE | OWL_UART_CTL_TXDE | OWL_UART_CTL_RXDE | OWL_UART_CTL_EN); owl_uart_write(port, val, OWL_UART_CTL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -279,7 +279,7 @@ static int owl_uart_startup(struct uart_port *port) if (ret) return ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = owl_uart_read(port, OWL_UART_STAT); val |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP @@ -291,7 +291,7 @@ static int owl_uart_startup(struct uart_port *port) val |= OWL_UART_CTL_EN; owl_uart_write(port, val, OWL_UART_CTL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -311,7 +311,7 @@ static void owl_uart_set_termios(struct uart_port *port, u32 ctl; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ctl = owl_uart_read(port, OWL_UART_CTL); @@ -371,7 +371,7 @@ static void owl_uart_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void owl_uart_release_port(struct uart_port *port) @@ -515,9 +515,9 @@ static void owl_uart_port_write(struct uart_port *port, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); else { - spin_lock(&port->lock); + uart_port_lock(port); locked = 1; } @@ -541,7 +541,7 @@ static void owl_uart_port_write(struct uart_port *port, const char *s, owl_uart_write(port, old_ctl, OWL_UART_CTL); if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index cc83b772b7ca..436cc6d52a11 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1347,7 +1347,7 @@ static void pch_uart_set_termios(struct uart_port *port, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); spin_lock_irqsave(&priv->lock, flags); - spin_lock(&port->lock); + uart_port_lock(port); uart_update_timeout(port, termios->c_cflag, baud); rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb); @@ -1360,7 +1360,7 @@ static void pch_uart_set_termios(struct uart_port *port, tty_termios_encode_baud_rate(termios, baud, baud); out: - spin_unlock(&port->lock); + uart_port_unlock(port); spin_unlock_irqrestore(&priv->lock, flags); } @@ -1581,10 +1581,10 @@ pch_console_write(struct console *co, const char *s, unsigned int count) port_locked = 0; } else if (oops_in_progress) { priv_locked = spin_trylock(&priv->lock); - port_locked = spin_trylock(&priv->port.lock); + port_locked = uart_port_trylock(&priv->port); } else { spin_lock(&priv->lock); - spin_lock(&priv->port.lock); + uart_port_lock(&priv->port); } /* @@ -1604,7 +1604,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count) iowrite8(ier, priv->membase + UART_IER); if (port_locked) - spin_unlock(&priv->port.lock); + uart_port_unlock(&priv->port); if (priv_locked) spin_unlock(&priv->lock); local_irq_restore(flags); diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index e308d5022b3f..3a95bf5d55d3 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c @@ -243,7 +243,7 @@ static void pic32_uart_break_ctl(struct uart_port *port, int ctl) struct pic32_sport *sport = to_pic32_sport(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (ctl) pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA), @@ -252,7 +252,7 @@ static void pic32_uart_break_ctl(struct uart_port *port, int ctl) pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), PIC32_UART_STA_UTXBRK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* get port type in string format */ @@ -274,7 +274,7 @@ static void pic32_uart_do_rx(struct uart_port *port) */ max_count = PIC32_UART_RX_FIFO_DEPTH; - spin_lock(&port->lock); + uart_port_lock(port); tty = &port->state->port; @@ -331,7 +331,7 @@ static void pic32_uart_do_rx(struct uart_port *port) } while (--max_count); - spin_unlock(&port->lock); + uart_port_unlock(port); tty_flip_buffer_push(tty); } @@ -410,9 +410,9 @@ static irqreturn_t pic32_uart_tx_interrupt(int irq, void *dev_id) struct uart_port *port = dev_id; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pic32_uart_do_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -580,9 +580,9 @@ static void pic32_uart_shutdown(struct uart_port *port) unsigned long flags; /* disable uart */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pic32_uart_dsbl_and_mask(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); clk_disable_unprepare(sport->clk); /* free all 3 interrupts for this UART */ @@ -604,7 +604,7 @@ static void pic32_uart_set_termios(struct uart_port *port, unsigned int quot; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* disable uart and mask all interrupts while changing speed */ pic32_uart_dsbl_and_mask(port); @@ -672,7 +672,7 @@ static void pic32_uart_set_termios(struct uart_port *port, /* enable uart */ pic32_uart_en_and_unmask(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* serial core request to claim uart iomem */ diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 13668ffdb1e7..c8bf08c19c64 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -246,9 +246,9 @@ static bool pmz_receive_chars(struct uart_pmac_port *uap) #endif /* USE_CTRL_O_SYSRQ */ if (uap->port.sysrq) { int swallow; - spin_unlock(&uap->port.lock); + uart_port_unlock(&uap->port); swallow = uart_handle_sysrq_char(&uap->port, ch); - spin_lock(&uap->port.lock); + uart_port_lock(&uap->port); if (swallow) goto next_char; } @@ -435,7 +435,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) uap_a = pmz_get_port_A(uap); uap_b = uap_a->mate; - spin_lock(&uap_a->port.lock); + uart_port_lock(&uap_a->port); r3 = read_zsreg(uap_a, R3); /* Channel A */ @@ -456,14 +456,14 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) rc = IRQ_HANDLED; } skip_a: - spin_unlock(&uap_a->port.lock); + uart_port_unlock(&uap_a->port); if (push) tty_flip_buffer_push(&uap->port.state->port); if (!uap_b) goto out; - spin_lock(&uap_b->port.lock); + uart_port_lock(&uap_b->port); push = false; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { if (!ZS_IS_OPEN(uap_b)) { @@ -481,7 +481,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) rc = IRQ_HANDLED; } skip_b: - spin_unlock(&uap_b->port.lock); + uart_port_unlock(&uap_b->port); if (push) tty_flip_buffer_push(&uap->port.state->port); @@ -497,9 +497,9 @@ static inline u8 pmz_peek_status(struct uart_pmac_port *uap) unsigned long flags; u8 status; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); status = read_zsreg(uap, R0); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); return status; } @@ -685,7 +685,7 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) else clear_bits |= SND_BRK; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); new_reg = (uap->curregs[R5] | set_bits) & ~clear_bits; if (new_reg != uap->curregs[R5]) { @@ -693,7 +693,7 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) write_zsreg(uap, R5, uap->curregs[R5]); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #ifdef CONFIG_PPC_PMAC @@ -865,18 +865,18 @@ static void pmz_irda_reset(struct uart_pmac_port *uap) { unsigned long flags; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); uap->curregs[R5] |= DTR; write_zsreg(uap, R5, uap->curregs[R5]); zssync(uap); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); msleep(110); - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); uap->curregs[R5] &= ~DTR; write_zsreg(uap, R5, uap->curregs[R5]); zssync(uap); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); msleep(10); } @@ -896,9 +896,9 @@ static int pmz_startup(struct uart_port *port) * initialize the chip */ if (!ZS_IS_CONS(uap)) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pwr_delay = __pmz_startup(uap); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } sprintf(uap->irq_name, PMACZILOG_NAME"%d", uap->port.line); if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, @@ -921,9 +921,9 @@ static int pmz_startup(struct uart_port *port) pmz_irda_reset(uap); /* Enable interrupt requests for the channel */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pmz_interrupt_control(uap, 1); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -933,7 +933,7 @@ static void pmz_shutdown(struct uart_port *port) struct uart_pmac_port *uap = to_pmz(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable interrupt requests for the channel */ pmz_interrupt_control(uap, 0); @@ -948,19 +948,19 @@ static void pmz_shutdown(struct uart_port *port) pmz_maybe_update_regs(uap); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Release interrupt handler */ free_irq(uap->port.irq, uap); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uap->flags &= ~PMACZILOG_FLAG_IS_OPEN; if (!ZS_IS_CONS(uap)) pmz_set_scc_power(uap, 0); /* Shut the chip down */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Shared by TTY driver and serial console setup. The port lock is held @@ -1247,7 +1247,7 @@ static void pmz_set_termios(struct uart_port *port, struct ktermios *termios, struct uart_pmac_port *uap = to_pmz(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable IRQs on the port */ pmz_interrupt_control(uap, 0); @@ -1259,7 +1259,7 @@ static void pmz_set_termios(struct uart_port *port, struct ktermios *termios, if (ZS_IS_OPEN(uap)) pmz_interrupt_control(uap, 1); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *pmz_type(struct uart_port *port) @@ -1896,7 +1896,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c struct uart_pmac_port *uap = &pmz_ports[con->index]; unsigned long flags; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); /* Turn of interrupts and enable the transmitter. */ write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB); @@ -1908,7 +1908,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c write_zsreg(uap, R1, uap->curregs[1]); /* Don't disable the transmitter. */ - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } /* diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 73c60f5ea027..46e70e155aab 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -225,14 +225,14 @@ static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) iir = serial_in(up, UART_IIR); if (iir & UART_IIR_NO_INT) return IRQ_NONE; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); lsr = serial_in(up, UART_LSR); if (lsr & UART_LSR_DR) receive_chars(up, &lsr); check_modem_status(up); if (lsr & UART_LSR_THRE) transmit_chars(up); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); return IRQ_HANDLED; } @@ -242,9 +242,9 @@ static unsigned int serial_pxa_tx_empty(struct uart_port *port) unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return ret; } @@ -295,13 +295,13 @@ static void serial_pxa_break_ctl(struct uart_port *port, int break_state) struct uart_pxa_port *up = (struct uart_pxa_port *)port; unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int serial_pxa_startup(struct uart_port *port) @@ -346,10 +346,10 @@ static int serial_pxa_startup(struct uart_port *port) */ serial_out(up, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.mctrl |= TIOCM_OUT2; serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Finally, enable interrupts. Note: Modem status interrupts @@ -383,10 +383,10 @@ static void serial_pxa_shutdown(struct uart_port *port) up->ier = 0; serial_out(up, UART_IER, 0); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.mctrl &= ~TIOCM_OUT2; serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Disable break condition and FIFOs @@ -434,7 +434,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Ensure the port will be enabled. @@ -504,7 +504,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, up->lcr = cval; /* Save LCR */ serial_pxa_set_mctrl(&up->port, up->port.mctrl); serial_out(up, UART_FCR, fcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void @@ -608,9 +608,9 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); + locked = uart_port_trylock(&up->port); else - spin_lock(&up->port.lock); + uart_port_lock(&up->port); /* * First save the IER then disable the interrupts @@ -628,7 +628,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) serial_out(up, UART_IER, ier); if (locked) - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); local_irq_restore(flags); clk_disable(up->clk); diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index b8aa4c1293ba..7e78f97e8f43 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -482,9 +482,9 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s, uport = &port->uport; if (oops_in_progress) - locked = spin_trylock_irqsave(&uport->lock, flags); + locked = uart_port_trylock_irqsave(uport, &flags); else - spin_lock_irqsave(&uport->lock, flags); + uart_port_lock_irqsave(uport, &flags); geni_status = readl(uport->membase + SE_GENI_STATUS); @@ -520,7 +520,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s, qcom_geni_serial_setup_tx(uport, port->tx_remaining); if (locked) - spin_unlock_irqrestore(&uport->lock, flags); + uart_port_unlock_irqrestore(uport, flags); } static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop) @@ -970,7 +970,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev) if (uport->suspended) return IRQ_NONE; - spin_lock(&uport->lock); + uart_port_lock(uport); m_irq_status = readl(uport->membase + SE_GENI_M_IRQ_STATUS); s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); diff --git a/drivers/tty/serial/rda-uart.c b/drivers/tty/serial/rda-uart.c index be5c842b5ba9..d824c8318f33 100644 --- a/drivers/tty/serial/rda-uart.c +++ b/drivers/tty/serial/rda-uart.c @@ -139,12 +139,12 @@ static unsigned int rda_uart_tx_empty(struct uart_port *port) unsigned int ret; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = rda_uart_read(port, RDA_UART_STATUS); ret = (val & RDA_UART_TX_FIFO_MASK) ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return ret; } @@ -246,7 +246,7 @@ static void rda_uart_set_termios(struct uart_port *port, unsigned int baud; u32 irq_mask; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); baud = uart_get_baud_rate(port, termios, old, 9600, port->uartclk / 4); rda_uart_change_baudrate(rda_port, baud); @@ -325,7 +325,7 @@ static void rda_uart_set_termios(struct uart_port *port, /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void rda_uart_send_chars(struct uart_port *port) @@ -408,7 +408,7 @@ static irqreturn_t rda_interrupt(int irq, void *dev_id) unsigned long flags; u32 val, irq_mask; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Clear IRQ cause */ val = rda_uart_read(port, RDA_UART_IRQ_CAUSE); @@ -425,7 +425,7 @@ static irqreturn_t rda_interrupt(int irq, void *dev_id) rda_uart_send_chars(port); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -436,16 +436,16 @@ static int rda_uart_startup(struct uart_port *port) int ret; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); rda_uart_write(port, 0, RDA_UART_IRQ_MASK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = request_irq(port->irq, rda_interrupt, IRQF_NO_SUSPEND, "rda-uart", port); if (ret) return ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = rda_uart_read(port, RDA_UART_CTRL); val |= RDA_UART_ENABLE; @@ -456,7 +456,7 @@ static int rda_uart_startup(struct uart_port *port) val |= (RDA_UART_RX_DATA_AVAILABLE | RDA_UART_RX_TIMEOUT); rda_uart_write(port, val, RDA_UART_IRQ_MASK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -466,7 +466,7 @@ static void rda_uart_shutdown(struct uart_port *port) unsigned long flags; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); rda_uart_stop_tx(port); rda_uart_stop_rx(port); @@ -475,7 +475,7 @@ static void rda_uart_shutdown(struct uart_port *port) val &= ~RDA_UART_ENABLE; rda_uart_write(port, val, RDA_UART_CTRL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *rda_uart_type(struct uart_port *port) @@ -515,7 +515,7 @@ static void rda_uart_config_port(struct uart_port *port, int flags) rda_uart_request_port(port); } - spin_lock_irqsave(&port->lock, irq_flags); + uart_port_lock_irqsave(port, &irq_flags); /* Clear mask, so no surprise interrupts. */ rda_uart_write(port, 0, RDA_UART_IRQ_MASK); @@ -523,7 +523,7 @@ static void rda_uart_config_port(struct uart_port *port, int flags) /* Clear status register */ rda_uart_write(port, 0, RDA_UART_STATUS); - spin_unlock_irqrestore(&port->lock, irq_flags); + uart_port_unlock_irqrestore(port, irq_flags); } static void rda_uart_release_port(struct uart_port *port) @@ -597,9 +597,9 @@ static void rda_uart_port_write(struct uart_port *port, const char *s, if (port->sysrq) { locked = 0; } else if (oops_in_progress) { - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); } else { - spin_lock(&port->lock); + uart_port_lock(port); locked = 1; } @@ -615,7 +615,7 @@ static void rda_uart_port_write(struct uart_port *port, const char *s, rda_uart_write(port, old_irq_mask, RDA_UART_IRQ_MASK); if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c index de220ac8ca54..d46a81cddfcd 100644 --- a/drivers/tty/serial/rp2.c +++ b/drivers/tty/serial/rp2.c @@ -276,9 +276,9 @@ static unsigned int rp2_uart_tx_empty(struct uart_port *port) * But the TXEMPTY bit doesn't seem to work unless the TX IRQ is * enabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); tx_fifo_bytes = readw(up->base + RP2_TX_FIFO_COUNT); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return tx_fifo_bytes ? 0 : TIOCSER_TEMT; } @@ -323,10 +323,10 @@ static void rp2_uart_break_ctl(struct uart_port *port, int break_state) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); rp2_rmw(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_BREAK_m, break_state ? RP2_TXRX_CTL_BREAK_m : 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void rp2_uart_enable_ms(struct uart_port *port) @@ -383,7 +383,7 @@ static void rp2_uart_set_termios(struct uart_port *port, struct ktermios *new, if (tty_termios_baud_rate(new)) tty_termios_encode_baud_rate(new, baud, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* ignore all characters if CREAD is not set */ port->ignore_status_mask = (new->c_cflag & CREAD) ? 0 : RP2_DUMMY_READ; @@ -391,7 +391,7 @@ static void rp2_uart_set_termios(struct uart_port *port, struct ktermios *new, __rp2_uart_set_termios(up, new->c_cflag, new->c_iflag, baud_div); uart_update_timeout(port, new->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void rp2_rx_chars(struct rp2_uart_port *up) @@ -440,7 +440,7 @@ static void rp2_ch_interrupt(struct rp2_uart_port *up) { u32 status; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); /* * The IRQ status bits are clear-on-write. Other status bits in @@ -456,7 +456,7 @@ static void rp2_ch_interrupt(struct rp2_uart_port *up) if (status & RP2_CHAN_STAT_MS_CHANGED_MASK) wake_up_interruptible(&up->port.state->port.delta_msr_wait); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); } static int rp2_asic_interrupt(struct rp2_card *card, unsigned int asic_id) @@ -516,10 +516,10 @@ static void rp2_uart_shutdown(struct uart_port *port) rp2_uart_break_ctl(port, 0); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); rp2_mask_ch_irq(up, up->idx, 0); rp2_rmw(up, RP2_CHAN_STAT, 0, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *rp2_uart_type(struct uart_port *port) diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index ad011f1e2f4d..be7bcd75d9f4 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -115,9 +115,9 @@ static void sa1100_timeout(struct timer_list *t) unsigned long flags; if (sport->port.state) { - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sa1100_mctrl_check(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); } @@ -247,7 +247,7 @@ static irqreturn_t sa1100_int(int irq, void *dev_id) struct sa1100_port *sport = dev_id; unsigned int status, pass_counter = 0; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); status = UART_GET_UTSR0(sport); status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS; do { @@ -276,7 +276,7 @@ static irqreturn_t sa1100_int(int irq, void *dev_id) status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS; } while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID)); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return IRQ_HANDLED; } @@ -321,14 +321,14 @@ static void sa1100_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int utcr3; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); utcr3 = UART_GET_UTCR3(sport); if (break_state == -1) utcr3 |= UTCR3_BRK; else utcr3 &= ~UTCR3_BRK; UART_PUT_UTCR3(sport, utcr3); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static int sa1100_startup(struct uart_port *port) @@ -354,9 +354,9 @@ static int sa1100_startup(struct uart_port *port) /* * Enable modem status interrupts */ - spin_lock_irq(&sport->port.lock); + uart_port_lock_irq(&sport->port); sa1100_enable_ms(&sport->port); - spin_unlock_irq(&sport->port.lock); + uart_port_unlock_irq(&sport->port); return 0; } @@ -423,7 +423,7 @@ sa1100_set_termios(struct uart_port *port, struct ktermios *termios, del_timer_sync(&sport->timer); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); @@ -485,7 +485,7 @@ sa1100_set_termios(struct uart_port *port, struct ktermios *termios, if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) sa1100_enable_ms(&sport->port); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static const char *sa1100_type(struct uart_port *port) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 07fb8a9dac63..3bd552841cd2 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -64,7 +64,6 @@ #define RXSTAT_DUMMY_READ (0x10000000) enum s3c24xx_port_type { - TYPE_S3C24XX, TYPE_S3C6400, TYPE_APPLE_S5L, }; @@ -128,8 +127,6 @@ struct s3c24xx_uart_dma { }; struct s3c24xx_uart_port { - unsigned char rx_claimed; - unsigned char tx_claimed; unsigned char rx_enabled; unsigned char tx_enabled; unsigned int pm_level; @@ -248,7 +245,7 @@ static void s3c24xx_serial_rx_enable(struct uart_port *port) unsigned int ucon, ufcon; int count = 10000; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (--count && !s3c24xx_serial_txempty_nofifo(port)) udelay(100); @@ -262,7 +259,7 @@ static void s3c24xx_serial_rx_enable(struct uart_port *port) wr_regl(port, S3C2410_UCON, ucon); ourport->rx_enabled = 1; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void s3c24xx_serial_rx_disable(struct uart_port *port) @@ -271,14 +268,14 @@ static void s3c24xx_serial_rx_disable(struct uart_port *port) unsigned long flags; unsigned int ucon; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ucon = rd_regl(port, S3C2410_UCON); ucon &= ~S3C2410_UCON_RXIRQMODE; wr_regl(port, S3C2410_UCON, ucon); ourport->rx_enabled = 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void s3c24xx_serial_stop_tx(struct uart_port *port) @@ -344,7 +341,7 @@ static void s3c24xx_serial_tx_dma_complete(void *args) dma->tx_transfer_addr, dma->tx_size, DMA_TO_DEVICE); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_xmit_advance(port, count); ourport->tx_in_progress = 0; @@ -353,7 +350,7 @@ static void s3c24xx_serial_tx_dma_complete(void *args) uart_write_wakeup(port); s3c24xx_serial_start_next_tx(ourport); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void enable_tx_dma(struct s3c24xx_uart_port *ourport) @@ -619,7 +616,7 @@ static void s3c24xx_serial_rx_dma_complete(void *args) received = dma->rx_bytes_requested - state.residue; async_tx_ack(dma->rx_desc); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (received) s3c24xx_uart_copy_rx_to_tty(ourport, t, received); @@ -631,7 +628,7 @@ static void s3c24xx_serial_rx_dma_complete(void *args) s3c64xx_start_rx_dma(ourport); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport) @@ -722,7 +719,7 @@ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id) utrstat = rd_regl(port, S3C2410_UTRSTAT); rd_regl(port, S3C2410_UFSTAT); - spin_lock(&port->lock); + uart_port_lock(port); if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) { s3c64xx_start_rx_dma(ourport); @@ -751,7 +748,7 @@ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id) wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT); finish: - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -849,9 +846,9 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id) struct s3c24xx_uart_port *ourport = dev_id; struct uart_port *port = &ourport->port; - spin_lock(&port->lock); + uart_port_lock(port); s3c24xx_serial_rx_drain_fifo(ourport); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -932,11 +929,11 @@ static irqreturn_t s3c24xx_serial_tx_irq(int irq, void *id) struct s3c24xx_uart_port *ourport = id; struct uart_port *port = &ourport->port; - spin_lock(&port->lock); + uart_port_lock(port); s3c24xx_serial_tx_chars(ourport); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -1033,7 +1030,7 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int ucon; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ucon = rd_regl(port, S3C2410_UCON); @@ -1044,7 +1041,7 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) wr_regl(port, S3C2410_UCON, ucon); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) @@ -1166,29 +1163,6 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) } } -static void s3c24xx_serial_shutdown(struct uart_port *port) -{ - struct s3c24xx_uart_port *ourport = to_ourport(port); - - if (ourport->tx_claimed) { - free_irq(ourport->tx_irq, ourport); - ourport->tx_enabled = 0; - ourport->tx_claimed = 0; - ourport->tx_mode = 0; - } - - if (ourport->rx_claimed) { - free_irq(ourport->rx_irq, ourport); - ourport->rx_claimed = 0; - ourport->rx_enabled = 0; - } - - if (ourport->dma) - s3c24xx_serial_release_dma(ourport); - - ourport->tx_in_progress = 0; -} - static void s3c64xx_serial_shutdown(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); @@ -1234,48 +1208,6 @@ static void apple_s5l_serial_shutdown(struct uart_port *port) ourport->tx_in_progress = 0; } -static int s3c24xx_serial_startup(struct uart_port *port) -{ - struct s3c24xx_uart_port *ourport = to_ourport(port); - int ret; - - ourport->rx_enabled = 1; - - ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_irq, 0, - s3c24xx_serial_portname(port), ourport); - - if (ret != 0) { - dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq); - return ret; - } - - ourport->rx_claimed = 1; - - dev_dbg(port->dev, "requesting tx irq...\n"); - - ourport->tx_enabled = 1; - - ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_irq, 0, - s3c24xx_serial_portname(port), ourport); - - if (ret) { - dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq); - goto err; - } - - ourport->tx_claimed = 1; - - /* the port reset code should have done the correct - * register setup for the port controls - */ - - return ret; - -err: - s3c24xx_serial_shutdown(port); - return ret; -} - static int s3c64xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); @@ -1303,7 +1235,7 @@ static int s3c64xx_serial_startup(struct uart_port *port) ourport->rx_enabled = 1; ourport->tx_enabled = 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ufcon = rd_regl(port, S3C2410_UFCON); ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8; @@ -1313,7 +1245,7 @@ static int s3c64xx_serial_startup(struct uart_port *port) enable_rx_pio(ourport); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Enable Rx Interrupt */ s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM); @@ -1341,7 +1273,7 @@ static int apple_s5l_serial_startup(struct uart_port *port) ourport->rx_enabled = 1; ourport->tx_enabled = 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ufcon = rd_regl(port, S3C2410_UFCON); ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8; @@ -1351,7 +1283,7 @@ static int apple_s5l_serial_startup(struct uart_port *port) enable_rx_pio(ourport); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Enable Rx Interrupt */ s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON); @@ -1626,7 +1558,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ulcon |= S3C2410_LCON_PNONE; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); dev_dbg(port->dev, "setting ulcon to %08x, brddiv to %d, udivslot %08x\n", @@ -1684,7 +1616,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= RXSTAT_DUMMY_READ; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *s3c24xx_serial_type(struct uart_port *port) @@ -1692,8 +1624,6 @@ static const char *s3c24xx_serial_type(struct uart_port *port) const struct s3c24xx_uart_port *ourport = to_ourport(port); switch (ourport->info->type) { - case TYPE_S3C24XX: - return "S3C24XX"; case TYPE_S3C6400: return "S3C6400/10"; case TYPE_APPLE_S5L: @@ -1753,27 +1683,6 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port, unsigned char c); #endif -static const struct uart_ops s3c24xx_serial_ops = { - .pm = s3c24xx_serial_pm, - .tx_empty = s3c24xx_serial_tx_empty, - .get_mctrl = s3c24xx_serial_get_mctrl, - .set_mctrl = s3c24xx_serial_set_mctrl, - .stop_tx = s3c24xx_serial_stop_tx, - .start_tx = s3c24xx_serial_start_tx, - .stop_rx = s3c24xx_serial_stop_rx, - .break_ctl = s3c24xx_serial_break_ctl, - .startup = s3c24xx_serial_startup, - .shutdown = s3c24xx_serial_shutdown, - .set_termios = s3c24xx_serial_set_termios, - .type = s3c24xx_serial_type, - .config_port = s3c24xx_serial_config_port, - .verify_port = s3c24xx_serial_verify_port, -#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) - .poll_get_char = s3c24xx_serial_get_poll_char, - .poll_put_char = s3c24xx_serial_put_poll_char, -#endif -}; - static const struct uart_ops s3c64xx_serial_ops = { .pm = s3c24xx_serial_pm, .tx_empty = s3c24xx_serial_tx_empty, @@ -1836,7 +1745,6 @@ static void s3c24xx_serial_init_port_default(int index) { port->iotype = UPIO_MEM; port->uartclk = 0; port->fifosize = 16; - port->ops = &s3c24xx_serial_ops; port->flags = UPF_BOOT_AUTOCONF; port->line = index; } @@ -1954,16 +1862,6 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ourport->tx_irq = ret + 1; } - switch (ourport->info->type) { - case TYPE_S3C24XX: - ret = platform_get_irq(platdev, 1); - if (ret > 0) - ourport->tx_irq = ret; - break; - default: - break; - } - /* * DMA is currently supported only on DT platforms, if DMA properties * are specified. @@ -2083,9 +1981,6 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) &ourport->drv_data->def_cfg; switch (ourport->info->type) { - case TYPE_S3C24XX: - ourport->port.ops = &s3c24xx_serial_ops; - break; case TYPE_S3C6400: ourport->port.ops = &s3c64xx_serial_ops; break; @@ -2376,14 +2271,14 @@ s3c24xx_serial_console_write(struct console *co, const char *s, if (cons_uart->sysrq) locked = false; else if (oops_in_progress) - locked = spin_trylock_irqsave(&cons_uart->lock, flags); + locked = uart_port_trylock_irqsave(cons_uart, &flags); else - spin_lock_irqsave(&cons_uart->lock, flags); + uart_port_lock_irqsave(cons_uart, &flags); uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); if (locked) - spin_unlock_irqrestore(&cons_uart->lock, flags); + uart_port_unlock_irqrestore(cons_uart, flags); } /* Shouldn't be __init, as it can be instantiated from other module */ @@ -2840,17 +2735,7 @@ static struct samsung_early_console_data s3c2410_early_console_data = { .rxfifo_mask = S3C2410_UFSTAT_RXFULL | S3C2410_UFSTAT_RXMASK, }; -static int __init s3c2410_early_console_setup(struct earlycon_device *device, - const char *opt) -{ - device->port.private_data = &s3c2410_early_console_data; - return samsung_early_console_setup(device, opt); -} - -OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", - s3c2410_early_console_setup); - -/* S3C2412, S3C2440, S3C64xx */ +/* S3C64xx */ static struct samsung_early_console_data s3c2440_early_console_data = { .txfull_mask = S3C2440_UFSTAT_TXFULL, .rxfifo_mask = S3C2440_UFSTAT_RXFULL | S3C2440_UFSTAT_RXMASK, @@ -2863,10 +2748,6 @@ static int __init s3c2440_early_console_setup(struct earlycon_device *device, return samsung_early_console_setup(device, opt); } -OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart", - s3c2440_early_console_setup); -OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart", - s3c2440_early_console_setup); OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart", s3c2440_early_console_setup); diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index f3cd69346482..dbec29d9a6c3 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c @@ -610,7 +610,7 @@ static void sbd_set_termios(struct uart_port *uport, struct ktermios *termios, else aux &= ~M_DUART_CTS_CHNG_ENA; - spin_lock(&uport->lock); + uart_port_lock(uport); if (sport->tx_stopped) command |= M_DUART_TX_DIS; @@ -632,7 +632,7 @@ static void sbd_set_termios(struct uart_port *uport, struct ktermios *termios, write_sbdchn(sport, R_DUART_CMD, command); - spin_unlock(&uport->lock); + uart_port_unlock(uport); } @@ -839,22 +839,22 @@ static void sbd_console_write(struct console *co, const char *s, unsigned int mask; /* Disable transmit interrupts and enable the transmitter. */ - spin_lock_irqsave(&uport->lock, flags); + uart_port_lock_irqsave(uport, &flags); mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2)); write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask & ~M_DUART_IMR_TX); write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN); - spin_unlock_irqrestore(&uport->lock, flags); + uart_port_unlock_irqrestore(uport, flags); uart_console_write(&sport->port, s, count, sbd_console_putchar); /* Restore transmit interrupts and the transmitter enable. */ - spin_lock_irqsave(&uport->lock, flags); + uart_port_lock_irqsave(uport, &flags); sbd_line_drain(sport); if (sport->tx_stopped) write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS); write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask); - spin_unlock_irqrestore(&uport->lock, flags); + uart_port_unlock_irqrestore(uport, flags); } static int __init sbd_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index f61d98e09dc3..db2bb1c0d36c 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -223,7 +223,7 @@ * trigger levels. Trigger levels from 4 characters to 60 characters are * available with a granularity of four. * - * When the trigger level setting in TLR is zero, the SC16IS740/750/760 uses the + * When the trigger level setting in TLR is zero, the SC16IS74x/75x/76x uses the * trigger level setting defined in FCR. If TLR has non-zero trigger level value * the trigger level defined in FCR is discarded. This applies to both transmit * FIFO and receive FIFO trigger level setting. @@ -234,7 +234,7 @@ #define SC16IS7XX_TLR_TX_TRIGGER(words) ((((words) / 4) & 0x0f) << 0) #define SC16IS7XX_TLR_RX_TRIGGER(words) ((((words) / 4) & 0x0f) << 4) -/* IOControl register bits (Only 750/760) */ +/* IOControl register bits (Only 75x/76x) */ #define SC16IS7XX_IOCONTROL_LATCH_BIT (1 << 0) /* Enable input latching */ #define SC16IS7XX_IOCONTROL_MODEM_A_BIT (1 << 1) /* Enable GPIO[7:4] as modem A pins */ #define SC16IS7XX_IOCONTROL_MODEM_B_BIT (1 << 2) /* Enable GPIO[3:0] as modem B pins */ @@ -249,9 +249,9 @@ #define SC16IS7XX_EFCR_RTS_INVERT_BIT (1 << 5) /* RTS output inversion */ #define SC16IS7XX_EFCR_IRDA_MODE_BIT (1 << 7) /* IrDA mode * 0 = rate upto 115.2 kbit/s - * - Only 750/760 + * - Only 75x/76x * 1 = rate upto 1.152 Mbit/s - * - Only 760 + * - Only 76x */ /* EFR register bits */ @@ -358,7 +358,6 @@ static struct uart_driver sc16is7xx_uart = { static void sc16is7xx_ier_set(struct uart_port *port, u8 bit); static void sc16is7xx_stop_tx(struct uart_port *port); -#define to_sc16is7xx_port(p,e) ((container_of((p), struct sc16is7xx_port, e))) #define to_sc16is7xx_one(p,e) ((container_of((p), struct sc16is7xx_one, e))) static int sc16is7xx_line(struct uart_port *port) @@ -667,9 +666,9 @@ static void sc16is7xx_handle_tx(struct uart_port *port) } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_stop_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } @@ -695,13 +694,13 @@ static void sc16is7xx_handle_tx(struct uart_port *port) sc16is7xx_fifo_write(port, to_send); } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) sc16is7xx_stop_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static unsigned int sc16is7xx_get_hwmctrl(struct uart_port *port) @@ -733,7 +732,7 @@ static void sc16is7xx_update_mlines(struct sc16is7xx_one *one) one->old_mctrl = status; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if ((changed & TIOCM_RNG) && (status & TIOCM_RNG)) port->icount.rng++; if (changed & TIOCM_DSR) @@ -744,7 +743,7 @@ static void sc16is7xx_update_mlines(struct sc16is7xx_one *one) uart_handle_cts_change(port, status & TIOCM_CTS); wake_up_interruptible(&port->state->port.delta_msr_wait); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) @@ -823,9 +822,9 @@ static void sc16is7xx_tx_proc(struct kthread_work *ws) sc16is7xx_handle_tx(port); mutex_unlock(&s->efr_lock); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sc16is7xx_reconf_rs485(struct uart_port *port) @@ -836,14 +835,14 @@ static void sc16is7xx_reconf_rs485(struct uart_port *port) struct serial_rs485 *rs485 = &port->rs485; unsigned long irqflags; - spin_lock_irqsave(&port->lock, irqflags); + uart_port_lock_irqsave(port, &irqflags); if (rs485->flags & SER_RS485_ENABLED) { efcr |= SC16IS7XX_EFCR_AUTO_RS485_BIT; if (rs485->flags & SER_RS485_RTS_AFTER_SEND) efcr |= SC16IS7XX_EFCR_RTS_INVERT_BIT; } - spin_unlock_irqrestore(&port->lock, irqflags); + uart_port_unlock_irqrestore(port, irqflags); sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, mask, efcr); } @@ -854,10 +853,10 @@ static void sc16is7xx_reg_proc(struct kthread_work *ws) struct sc16is7xx_one_config config; unsigned long irqflags; - spin_lock_irqsave(&one->port.lock, irqflags); + uart_port_lock_irqsave(&one->port, &irqflags); config = one->config; memset(&one->config, 0, sizeof(one->config)); - spin_unlock_irqrestore(&one->port.lock, irqflags); + uart_port_unlock_irqrestore(&one->port, irqflags); if (config.flags & SC16IS7XX_RECONF_MD) { u8 mcr = 0; @@ -963,18 +962,18 @@ static void sc16is7xx_throttle(struct uart_port *port) * value set in MCR register. Stop reading data from RX FIFO so the * AutoRTS feature will de-activate RTS output. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_ier_clear(port, SC16IS7XX_IER_RDI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sc16is7xx_unthrottle(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_ier_set(port, SC16IS7XX_IER_RDI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static unsigned int sc16is7xx_tx_empty(struct uart_port *port) @@ -1113,7 +1112,7 @@ static void sc16is7xx_set_termios(struct uart_port *port, /* Setup baudrate generator */ baud = sc16is7xx_set_baud(port, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Update timeout according to new baud rate */ uart_update_timeout(port, termios->c_cflag, baud); @@ -1121,7 +1120,7 @@ static void sc16is7xx_set_termios(struct uart_port *port, if (UART_ENABLE_MS(port, termios->c_cflag)) sc16is7xx_enable_ms(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sc16is7xx_config_rs485(struct uart_port *port, struct ktermios *termios, @@ -1208,9 +1207,9 @@ static int sc16is7xx_startup(struct uart_port *port) sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); /* Enable modem status polling */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_enable_ms(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -1409,6 +1408,29 @@ static int sc16is7xx_setup_gpio_chip(struct sc16is7xx_port *s) } #endif +static void sc16is7xx_setup_irda_ports(struct sc16is7xx_port *s) +{ + int i; + int ret; + int count; + u32 irda_port[2]; + struct device *dev = s->p[0].port.dev; + + count = device_property_count_u32(dev, "irda-mode-ports"); + if (count < 0 || count > ARRAY_SIZE(irda_port)) + return; + + ret = device_property_read_u32_array(dev, "irda-mode-ports", + irda_port, count); + if (ret) + return; + + for (i = 0; i < count; i++) { + if (irda_port[i] < s->devtype->nr_uart) + s->p[irda_port[i]].irda_mode = true; + } +} + /* * Configure ports designated to operate as modem control lines. */ @@ -1591,16 +1613,7 @@ static int sc16is7xx_probe(struct device *dev, sc16is7xx_power(&s->p[i].port, 0); } - if (dev->of_node) { - struct property *prop; - const __be32 *p; - u32 u; - - of_property_for_each_u32(dev->of_node, "irda-mode-ports", - prop, p, u) - if (u < devtype->nr_uart) - s->p[u].irda_mode = true; - } + sc16is7xx_setup_irda_ports(s); ret = sc16is7xx_setup_mctrl_ports(s); if (ret) diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index d4ec943cb8e9..6d4006b41975 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -411,7 +411,7 @@ static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) divisor = DIV_ROUND_CLOSEST(rate, baud * 16); } - spin_lock_irqsave(&tup->uport.lock, flags); + uart_port_lock_irqsave(&tup->uport, &flags); lcr = tup->lcr_shadow; lcr |= UART_LCR_DLAB; tegra_uart_write(tup, lcr, UART_LCR); @@ -424,7 +424,7 @@ static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) /* Dummy read to ensure the write is posted */ tegra_uart_read(tup, UART_SCR); - spin_unlock_irqrestore(&tup->uport.lock, flags); + uart_port_unlock_irqrestore(&tup->uport, flags); tup->current_baud = baud; @@ -522,13 +522,13 @@ static void tegra_uart_tx_dma_complete(void *args) dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); count = tup->tx_bytes_requested - state.residue; async_tx_ack(tup->tx_dma_desc); - spin_lock_irqsave(&tup->uport.lock, flags); + uart_port_lock_irqsave(&tup->uport, &flags); uart_xmit_advance(&tup->uport, count); tup->tx_in_progress = 0; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&tup->uport); tegra_uart_start_next_tx(tup); - spin_unlock_irqrestore(&tup->uport.lock, flags); + uart_port_unlock_irqrestore(&tup->uport, flags); } static int tegra_uart_start_tx_dma(struct tegra_uart_port *tup, @@ -598,13 +598,13 @@ static unsigned int tegra_uart_tx_empty(struct uart_port *u) unsigned int ret = 0; unsigned long flags; - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); if (!tup->tx_in_progress) { unsigned long lsr = tegra_uart_read(tup, UART_LSR); if ((lsr & TX_EMPTY_STATUS) == TX_EMPTY_STATUS) ret = TIOCSER_TEMT; } - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); return ret; } @@ -727,7 +727,7 @@ static void tegra_uart_rx_dma_complete(void *args) struct dma_tx_state state; enum dma_status status; - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); status = dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); @@ -749,7 +749,7 @@ static void tegra_uart_rx_dma_complete(void *args) set_rts(tup, true); done: - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); } static void tegra_uart_terminate_rx_dma(struct tegra_uart_port *tup) @@ -836,7 +836,7 @@ static irqreturn_t tegra_uart_isr(int irq, void *data) bool is_rx_int = false; unsigned long flags; - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); while (1) { iir = tegra_uart_read(tup, UART_IIR); if (iir & UART_IIR_NO_INT) { @@ -852,7 +852,7 @@ static irqreturn_t tegra_uart_isr(int irq, void *data) } else if (is_rx_start) { tegra_uart_start_rx_dma(tup); } - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); return IRQ_HANDLED; } @@ -969,11 +969,11 @@ static void tegra_uart_hw_deinit(struct tegra_uart_port *tup) } } - spin_lock_irqsave(&tup->uport.lock, flags); + uart_port_lock_irqsave(&tup->uport, &flags); /* Reset the Rx and Tx FIFOs */ tegra_uart_fifo_reset(tup, UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); tup->current_baud = 0; - spin_unlock_irqrestore(&tup->uport.lock, flags); + uart_port_unlock_irqrestore(&tup->uport, flags); tup->rx_in_progress = 0; tup->tx_in_progress = 0; @@ -1292,7 +1292,7 @@ static void tegra_uart_set_termios(struct uart_port *u, int ret; max_divider *= 16; - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); /* Changing configuration, it is safe to stop any rx now */ if (tup->rts_active) @@ -1341,7 +1341,7 @@ static void tegra_uart_set_termios(struct uart_port *u, baud = uart_get_baud_rate(u, termios, oldtermios, parent_clk_rate/max_divider, parent_clk_rate/16); - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); ret = tegra_set_baudrate(tup, baud); if (ret < 0) { dev_err(tup->uport.dev, "Failed to set baud rate\n"); @@ -1349,7 +1349,7 @@ static void tegra_uart_set_termios(struct uart_port *u, } if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); /* Flow control */ if (termios->c_cflag & CRTSCTS) { @@ -1382,7 +1382,7 @@ static void tegra_uart_set_termios(struct uart_port *u, if (termios->c_iflag & IGNBRK) tup->uport.ignore_status_mask |= UART_LSR_BI; - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); } static const char *tegra_uart_type(struct uart_port *u) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index d5ba6e90bd95..f1348a509552 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -79,7 +79,7 @@ static inline void uart_port_deref(struct uart_port *uport) ({ \ struct uart_port *__uport = uart_port_ref(state); \ if (__uport) \ - spin_lock_irqsave(&__uport->lock, flags); \ + uart_port_lock_irqsave(__uport, &flags); \ __uport; \ }) @@ -87,7 +87,7 @@ static inline void uart_port_deref(struct uart_port *uport) ({ \ struct uart_port *__uport = uport; \ if (__uport) { \ - spin_unlock_irqrestore(&__uport->lock, flags); \ + uart_port_unlock_irqrestore(__uport, flags); \ uart_port_deref(__uport); \ } \ }) @@ -146,7 +146,7 @@ static void __uart_start(struct uart_state *state) /* Increment the runtime PM usage count for the active check below */ err = pm_runtime_get(&port_dev->dev); - if (err < 0) { + if (err < 0 && err != -EINPROGRESS) { pm_runtime_put_noidle(&port_dev->dev); return; } @@ -179,12 +179,12 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) unsigned long flags; unsigned int old; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); old = port->mctrl; port->mctrl = (old & ~clear) | set; if (old != port->mctrl && !(port->rs485.flags & SER_RS485_ENABLED)) port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0) @@ -219,7 +219,7 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state /* * Set modem status enables based on termios cflag */ - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); if (termios->c_cflag & CRTSCTS) uport->status |= UPSTAT_CTS_ENABLE; else @@ -240,7 +240,7 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state else __uart_start(state); } - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); } /* @@ -431,7 +431,7 @@ EXPORT_SYMBOL(uart_update_timeout); * baud. * * If the new baud rate is invalid, try the @old termios setting. If it's still - * invalid, we try 9600 baud. + * invalid, we try 9600 baud. If that is also invalid 0 is returned. * * The @termios structure is updated to reflect the baud rate we're actually * going to be using. Don't do this for the case where B0 is requested ("hang @@ -515,8 +515,6 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, max - 1, max - 1); } } - /* Should never happen */ - WARN_ON(1); return 0; } EXPORT_SYMBOL(uart_get_baud_rate); @@ -702,11 +700,11 @@ static void uart_send_xchar(struct tty_struct *tty, char ch) if (port->ops->send_xchar) port->ops->send_xchar(port, ch); else { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->x_char = ch; if (ch) port->ops->start_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } uart_port_deref(port); } @@ -775,6 +773,9 @@ static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo) struct uart_port *uport; int ret = -ENODEV; + /* Initialize structure in case we error out later to prevent any stack info leakage. */ + *retinfo = (struct serial_struct){}; + /* * Ensure the state we copy is consistent and no hardware changes * occur as we go @@ -1085,9 +1086,9 @@ static int uart_tiocmget(struct tty_struct *tty) if (!tty_io_error(tty)) { result = uport->mctrl; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); result |= uport->ops->get_mctrl(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); } out: mutex_unlock(&port->mutex); @@ -1223,16 +1224,16 @@ static int uart_wait_modem_status(struct uart_state *state, unsigned long arg) uport = uart_port_ref(state); if (!uport) return -EIO; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); memcpy(&cprev, &uport->icount, sizeof(struct uart_icount)); uart_enable_ms(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); add_wait_queue(&port->delta_msr_wait, &wait); for (;;) { - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); set_current_state(TASK_INTERRUPTIBLE); @@ -1277,9 +1278,9 @@ static int uart_get_icount(struct tty_struct *tty, uport = uart_port_ref(state); if (!uport) return -EIO; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); uart_port_deref(uport); icount->cts = cnow.cts; @@ -1413,9 +1414,9 @@ static int uart_rs485_config(struct uart_port *port) uart_sanitize_serial_rs485(port, rs485); uart_set_rs485_termination(port, rs485); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = port->rs485_config(port, NULL, rs485); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (ret) memset(rs485, 0, sizeof(*rs485)); @@ -1428,9 +1429,9 @@ static int uart_get_rs485_config(struct uart_port *port, unsigned long flags; struct serial_rs485 aux; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); aux = port->rs485; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (copy_to_user(rs485, &aux, sizeof(aux))) return -EFAULT; @@ -1457,7 +1458,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, uart_sanitize_serial_rs485(port, &rs485); uart_set_rs485_termination(port, &rs485); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = port->rs485_config(port, &tty->termios, &rs485); if (!ret) { port->rs485 = rs485; @@ -1466,7 +1467,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, if (!(rs485.flags & SER_RS485_ENABLED)) port->ops->set_mctrl(port, port->mctrl); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (ret) return ret; @@ -1485,9 +1486,9 @@ static int uart_get_iso7816_config(struct uart_port *port, if (!port->iso7816_config) return -ENOTTY; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); aux = port->iso7816; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (copy_to_user(iso7816, &aux, sizeof(aux))) return -EFAULT; @@ -1516,9 +1517,9 @@ static int uart_set_iso7816_config(struct uart_port *port, if (iso7816.reserved[i]) return -EINVAL; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = port->iso7816_config(port, &iso7816); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (ret) return ret; @@ -1735,9 +1736,9 @@ static void uart_tty_port_shutdown(struct tty_port *port) if (WARN(!uport, "detached port still initialized!\n")) return; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); uport->ops->stop_rx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); uart_port_shutdown(port); @@ -1751,10 +1752,10 @@ static void uart_tty_port_shutdown(struct tty_port *port) /* * Free the transmit buffer. */ - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); buf = state->xmit.buf; state->xmit.buf = NULL; - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); free_page((unsigned long)buf); @@ -1897,10 +1898,10 @@ static bool uart_carrier_raised(struct tty_port *port) */ if (WARN_ON(!uport)) return true; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); uart_enable_ms(uport); mctrl = uport->ops->get_mctrl(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); uart_port_deref(uport); return mctrl & TIOCM_CAR; @@ -2017,9 +2018,9 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) pm_state = state->pm_state; if (pm_state != UART_PM_STATE_ON) uart_change_pm(state, UART_PM_STATE_ON); - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); status = uport->ops->get_mctrl(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); if (pm_state != UART_PM_STATE_ON) uart_change_pm(state, pm_state); @@ -2358,9 +2359,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) */ if (!console_suspend_enabled && uart_console(uport)) { if (uport->ops->start_rx) { - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); uport->ops->stop_rx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); } goto unlock; } @@ -2375,7 +2376,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) tty_port_set_suspended(port, true); tty_port_set_initialized(port, false); - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); ops->stop_tx(uport); if (!(uport->rs485.flags & SER_RS485_ENABLED)) ops->set_mctrl(uport, 0); @@ -2383,7 +2384,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) mctrl = uport->mctrl; uport->mctrl = 0; ops->stop_rx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); /* * Wait for the transmitter to empty. @@ -2455,9 +2456,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) uart_change_pm(state, UART_PM_STATE_ON); uport->ops->set_termios(uport, &termios, NULL); if (!console_suspend_enabled && uport->ops->start_rx) { - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); uport->ops->start_rx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); } if (console_suspend_enabled) console_start(uport->cons); @@ -2468,10 +2469,10 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) int ret; uart_change_pm(state, UART_PM_STATE_ON); - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); if (!(uport->rs485.flags & SER_RS485_ENABLED)) ops->set_mctrl(uport, 0); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); if (console_suspend_enabled || !uart_console(uport)) { /* Protected by port mutex for now */ struct tty_struct *tty = port->tty; @@ -2481,11 +2482,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) if (tty) uart_change_line_settings(tty, state, NULL); uart_rs485_config(uport); - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); if (!(uport->rs485.flags & SER_RS485_ENABLED)) ops->set_mctrl(uport, uport->mctrl); ops->start_tx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); tty_port_set_initialized(port, true); } else { /* @@ -2588,11 +2589,11 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, * keep the DTR setting that is set in uart_set_options() * We probably don't need a spinlock around this, but */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->mctrl &= TIOCM_DTR; if (!(port->rs485.flags & SER_RS485_ENABLED)) port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); uart_rs485_config(port); @@ -3564,9 +3565,10 @@ int uart_get_rs485_mode(struct uart_port *port) { struct serial_rs485 *rs485conf = &port->rs485; struct device *dev = port->dev; + enum gpiod_flags dflags; + struct gpio_desc *desc; u32 rs485_delay[2]; int ret; - int rx_during_tx_gpio_flag; ret = device_property_read_u32_array(dev, "rs485-rts-delay", rs485_delay, 2); @@ -3605,26 +3607,19 @@ int uart_get_rs485_mode(struct uart_port *port) * bus participants enable it, no communication is possible at all. * Works fine for short cables and users may enable for longer cables. */ - port->rs485_term_gpio = devm_gpiod_get_optional(dev, "rs485-term", - GPIOD_OUT_LOW); - if (IS_ERR(port->rs485_term_gpio)) { - ret = PTR_ERR(port->rs485_term_gpio); - port->rs485_term_gpio = NULL; - return dev_err_probe(dev, ret, "Cannot get rs485-term-gpios\n"); - } + desc = devm_gpiod_get_optional(dev, "rs485-term", GPIOD_OUT_LOW); + if (IS_ERR(desc)) + return dev_err_probe(dev, PTR_ERR(desc), "Cannot get rs485-term-gpios\n"); + port->rs485_term_gpio = desc; if (port->rs485_term_gpio) port->rs485_supported.flags |= SER_RS485_TERMINATE_BUS; - rx_during_tx_gpio_flag = (rs485conf->flags & SER_RS485_RX_DURING_TX) ? - GPIOD_OUT_HIGH : GPIOD_OUT_LOW; - port->rs485_rx_during_tx_gpio = devm_gpiod_get_optional(dev, - "rs485-rx-during-tx", - rx_during_tx_gpio_flag); - if (IS_ERR(port->rs485_rx_during_tx_gpio)) { - ret = PTR_ERR(port->rs485_rx_during_tx_gpio); - port->rs485_rx_during_tx_gpio = NULL; - return dev_err_probe(dev, ret, "Cannot get rs485-rx-during-tx-gpios\n"); - } + dflags = (rs485conf->flags & SER_RS485_RX_DURING_TX) ? + GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + desc = devm_gpiod_get_optional(dev, "rs485-rx-during-tx", dflags); + if (IS_ERR(desc)) + return dev_err_probe(dev, PTR_ERR(desc), "Cannot get rs485-rx-during-tx-gpios\n"); + port->rs485_rx_during_tx_gpio = desc; return 0; } diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index 7d5aaa8d422b..e51ca593ab86 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c @@ -184,7 +184,7 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context) mctrl_gpio_get(gpios, &mctrl); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); mctrl_diff = mctrl ^ gpios->mctrl_prev; gpios->mctrl_prev = mctrl; @@ -205,7 +205,7 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context) wake_up_interruptible(&port->state->port.delta_msr_wait); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c index 862423237007..88975a4df306 100644 --- a/drivers/tty/serial/serial_port.c +++ b/drivers/tty/serial/serial_port.c @@ -35,10 +35,10 @@ static int serial_port_runtime_resume(struct device *dev) goto out; /* Flush any pending TX for the port */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (__serial_port_busy(port)) port->ops->start_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); out: pm_runtime_mark_last_busy(dev); diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index be08fb6f749c..eaa980722455 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -335,13 +335,13 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) unsigned int status; while (1) { - spin_lock(&up->lock); + uart_port_lock(up); status = sio_in(up, TXX9_SIDISR); if (!(sio_in(up, TXX9_SIDICR) & TXX9_SIDICR_TIE)) status &= ~TXX9_SIDISR_TDIS; if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | TXX9_SIDISR_TOUT))) { - spin_unlock(&up->lock); + uart_port_unlock(up); break; } @@ -353,7 +353,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) sio_mask(up, TXX9_SIDISR, TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | TXX9_SIDISR_TOUT); - spin_unlock(&up->lock); + uart_port_unlock(up); if (pass_counter++ > PASS_LIMIT) break; @@ -367,9 +367,9 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *up) unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); ret = (sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS) ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); return ret; } @@ -399,12 +399,12 @@ static void serial_txx9_break_ctl(struct uart_port *up, int break_state) { unsigned long flags; - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); if (break_state == -1) sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); else sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); } #if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL) @@ -517,9 +517,9 @@ static int serial_txx9_startup(struct uart_port *up) /* * Now, initialize the UART */ - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); serial_txx9_set_mctrl(up, up->mctrl); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); /* Enable RX/TX */ sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); @@ -541,9 +541,9 @@ static void serial_txx9_shutdown(struct uart_port *up) */ sio_out(up, TXX9_SIDICR, 0); /* disable all intrs */ - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); serial_txx9_set_mctrl(up, up->mctrl); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); /* * Disable break condition @@ -625,7 +625,7 @@ serial_txx9_set_termios(struct uart_port *up, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); /* * Update the per-port timeout. @@ -676,7 +676,7 @@ serial_txx9_set_termios(struct uart_port *up, struct ktermios *termios, sio_out(up, TXX9_SIFCR, fcr); serial_txx9_set_mctrl(up, up->mctrl); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); } static void diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a560b729fa3b..84ab434c94ba 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1205,7 +1205,7 @@ static void sci_dma_tx_complete(void *arg) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_xmit_advance(port, s->tx_dma_len); @@ -1229,7 +1229,7 @@ static void sci_dma_tx_complete(void *arg) } } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Locking: called with port lock held */ @@ -1320,7 +1320,7 @@ static void sci_dma_rx_complete(void *arg) dev_dbg(port->dev, "%s(%d) active cookie %d\n", __func__, port->line, s->active_rx); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); active = sci_dma_rx_find_active(s); if (active >= 0) @@ -1347,20 +1347,20 @@ static void sci_dma_rx_complete(void *arg) dma_async_issue_pending(chan); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n", __func__, s->cookie_rx[active], active, s->active_rx); return; fail: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n"); /* Switch to PIO */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); dmaengine_terminate_async(chan); sci_dma_rx_chan_invalidate(s); sci_dma_rx_reenable_irq(s); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sci_dma_tx_release(struct sci_port *s) @@ -1409,13 +1409,13 @@ static int sci_dma_rx_submit(struct sci_port *s, bool port_lock_held) fail: /* Switch to PIO */ if (!port_lock_held) - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (i) dmaengine_terminate_async(chan); sci_dma_rx_chan_invalidate(s); sci_start_rx(port); if (!port_lock_held) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return -EAGAIN; } @@ -1437,14 +1437,14 @@ static void sci_dma_tx_work_fn(struct work_struct *work) * transmit till the end, and then the rest. Take the port lock to get a * consistent xmit buffer state. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); head = xmit->head; tail = xmit->tail; buf = s->tx_dma_addr + tail; s->tx_dma_len = CIRC_CNT_TO_END(head, tail, UART_XMIT_SIZE); if (!s->tx_dma_len) { /* Transmit buffer has been flushed */ - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); return; } @@ -1452,7 +1452,7 @@ static void sci_dma_tx_work_fn(struct work_struct *work) DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n"); goto switch_to_pio; } @@ -1464,12 +1464,12 @@ static void sci_dma_tx_work_fn(struct work_struct *work) desc->callback_param = s; s->cookie_tx = dmaengine_submit(desc); if (dma_submit_error(s->cookie_tx)) { - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); goto switch_to_pio; } - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__, xmit->buf, tail, head, s->cookie_tx); @@ -1477,10 +1477,10 @@ static void sci_dma_tx_work_fn(struct work_struct *work) return; switch_to_pio: - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); s->chan_tx = NULL; sci_start_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } @@ -1497,17 +1497,17 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t) dev_dbg(port->dev, "DMA Rx timed out\n"); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); active = sci_dma_rx_find_active(s); if (active < 0) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return HRTIMER_NORESTART; } status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state); if (status == DMA_COMPLETE) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); dev_dbg(port->dev, "Cookie %d #%d has already completed\n", s->active_rx, active); @@ -1525,7 +1525,7 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t) */ status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state); if (status == DMA_COMPLETE) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); dev_dbg(port->dev, "Transaction complete after DMA engine was stopped"); return HRTIMER_NORESTART; } @@ -1546,7 +1546,7 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t) sci_dma_rx_reenable_irq(s); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return HRTIMER_NORESTART; } @@ -1770,9 +1770,9 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr) struct uart_port *port = ptr; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sci_transmit_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -1786,11 +1786,11 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr) if (port->type != PORT_SCI) return sci_tx_interrupt(irq, ptr); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ctrl = serial_port_in(port, SCSCR); ctrl &= ~(SCSCR_TE | SCSCR_TEIE); serial_port_out(port, SCSCR, ctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -2187,7 +2187,7 @@ static void sci_break_ctl(struct uart_port *port, int break_state) return; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); scsptr = serial_port_in(port, SCSPTR); scscr = serial_port_in(port, SCSCR); @@ -2201,7 +2201,7 @@ static void sci_break_ctl(struct uart_port *port, int break_state) serial_port_out(port, SCSPTR, scsptr); serial_port_out(port, SCSCR, scscr); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sci_startup(struct uart_port *port) @@ -2233,7 +2233,7 @@ static void sci_shutdown(struct uart_port *port) s->autorts = false; mctrl_gpio_disable_ms(to_sci_port(port)->gpios); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sci_stop_rx(port); sci_stop_tx(port); /* @@ -2243,7 +2243,7 @@ static void sci_shutdown(struct uart_port *port) scr = serial_port_in(port, SCSCR); serial_port_out(port, SCSCR, scr & (SCSCR_CKE1 | SCSCR_CKE0 | s->hscif_tot)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); #ifdef CONFIG_SERIAL_SH_SCI_DMA if (s->chan_rx_saved) { @@ -2545,7 +2545,7 @@ done: serial_port_out(port, SCCKS, sccks); } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sci_reset(port); @@ -2667,7 +2667,7 @@ done: if ((termios->c_cflag & CREAD) != 0) sci_start_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); sci_port_disable(s); @@ -3052,9 +3052,9 @@ static void serial_console_write(struct console *co, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* first save SCSCR then disable interrupts, keep clock source */ ctrl = serial_port_in(port, SCSCR); @@ -3074,7 +3074,7 @@ static void serial_console_write(struct console *co, const char *s, serial_port_out(port, SCSCR, ctrl); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int serial_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index d195c5de52e7..b296e57a9dee 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -521,11 +521,11 @@ static irqreturn_t sifive_serial_irq(int irq, void *dev_id) struct sifive_serial_port *ssp = dev_id; u32 ip; - spin_lock(&ssp->port.lock); + uart_port_lock(&ssp->port); ip = __ssp_readl(ssp, SIFIVE_SERIAL_IP_OFFS); if (!ip) { - spin_unlock(&ssp->port.lock); + uart_port_unlock(&ssp->port); return IRQ_NONE; } @@ -534,7 +534,7 @@ static irqreturn_t sifive_serial_irq(int irq, void *dev_id) if (ip & SIFIVE_SERIAL_IP_TXWM_MASK) __ssp_transmit_chars(ssp); - spin_unlock(&ssp->port.lock); + uart_port_unlock(&ssp->port); return IRQ_HANDLED; } @@ -653,7 +653,7 @@ static void sifive_serial_set_termios(struct uart_port *port, ssp->port.uartclk / 16); __ssp_update_baud_rate(ssp, rate); - spin_lock_irqsave(&ssp->port.lock, flags); + uart_port_lock_irqsave(&ssp->port, &flags); /* Update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, rate); @@ -670,7 +670,7 @@ static void sifive_serial_set_termios(struct uart_port *port, if (v != old_v) __ssp_writel(v, SIFIVE_SERIAL_RXCTRL_OFFS, ssp); - spin_unlock_irqrestore(&ssp->port.lock, flags); + uart_port_unlock_irqrestore(&ssp->port, flags); } static void sifive_serial_release_port(struct uart_port *port) @@ -795,9 +795,9 @@ static void sifive_serial_console_write(struct console *co, const char *s, if (ssp->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&ssp->port.lock); + locked = uart_port_trylock(&ssp->port); else - spin_lock(&ssp->port.lock); + uart_port_lock(&ssp->port); ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS); __ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp); @@ -807,7 +807,7 @@ static void sifive_serial_console_write(struct console *co, const char *s, __ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp); if (locked) - spin_unlock(&ssp->port.lock); + uart_port_unlock(&ssp->port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index f328fa57231f..f257525f9299 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -247,7 +247,7 @@ static void sprd_complete_tx_dma(void *data) struct circ_buf *xmit = &port->state->xmit; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); dma_unmap_single(port->dev, sp->tx_dma.phys_addr, sp->tx_dma.trans_len, DMA_TO_DEVICE); @@ -260,7 +260,7 @@ static void sprd_complete_tx_dma(void *data) sprd_tx_dma_config(port)) sp->tx_dma.trans_len = 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sprd_uart_dma_submit(struct uart_port *port, @@ -429,13 +429,13 @@ static void sprd_complete_rx_dma(void *data) enum dma_status status; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = dmaengine_tx_status(sp->rx_dma.chn, sp->rx_dma.cookie, &state); if (status != DMA_COMPLETE) { sprd_stop_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } @@ -449,7 +449,7 @@ static void sprd_complete_rx_dma(void *data) if (sprd_start_dma_rx(port)) sprd_stop_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sprd_start_dma_rx(struct uart_port *port) @@ -638,12 +638,12 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) struct uart_port *port = dev_id; unsigned int ims; - spin_lock(&port->lock); + uart_port_lock(port); ims = serial_in(port, SPRD_IMSR); if (!ims) { - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_NONE; } @@ -660,7 +660,7 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) if (ims & SPRD_IMSR_TX_FIFO_EMPTY) sprd_tx(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -727,13 +727,13 @@ static int sprd_startup(struct uart_port *port) serial_out(port, SPRD_CTL1, fc); /* enable interrupt */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ien = serial_in(port, SPRD_IEN); ien |= SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT; if (!sp->rx_dma.enable) ien |= SPRD_IEN_RX_FULL; serial_out(port, SPRD_IEN, ien); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -793,7 +793,7 @@ static void sprd_set_termios(struct uart_port *port, struct ktermios *termios, lcr |= SPRD_LCR_EVEN_PAR; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); @@ -837,7 +837,7 @@ static void sprd_set_termios(struct uart_port *port, struct ktermios *termios, fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; serial_out(port, SPRD_CTL1, fc); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) @@ -974,9 +974,9 @@ static void sprd_console_write(struct console *co, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_console_write(port, s, count, sprd_console_putchar); @@ -984,7 +984,7 @@ static void sprd_console_write(struct console *co, const char *s, wait_for_xmitr(port); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sprd_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 92b9f6894006..a821f5d76a26 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -319,7 +319,7 @@ static irqreturn_t asc_interrupt(int irq, void *ptr) struct uart_port *port = ptr; u32 status; - spin_lock(&port->lock); + uart_port_lock(port); status = asc_in(port, ASC_STA); @@ -334,7 +334,7 @@ static irqreturn_t asc_interrupt(int irq, void *ptr) asc_transmit_chars(port); } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -452,10 +452,10 @@ static void asc_pm(struct uart_port *port, unsigned int state, * we can come to turning it off. Note this is not called with * the port spinlock held. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ctl = asc_in(port, ASC_CTL) & ~ASC_CTL_RUN; asc_out(port, ASC_CTL, ctl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); clk_disable_unprepare(ascport->clk); break; } @@ -480,7 +480,7 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); cflag = termios->c_cflag; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* read control register */ ctrl_val = asc_in(port, ASC_CTL); @@ -594,7 +594,7 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios, /* write final value and enable port */ asc_out(port, ASC_CTL, (ctrl_val | ASC_CTL_RUN)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *asc_type(struct uart_port *port) @@ -849,9 +849,9 @@ static void asc_console_write(struct console *co, const char *s, unsigned count) if (port->sysrq) locked = 0; /* asc_interrupt has already claimed the lock */ else if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Disable interrupts so we don't get the IRQ line bouncing @@ -869,7 +869,7 @@ static void asc_console_write(struct console *co, const char *s, unsigned count) asc_out(port, ASC_INTEN, intenable); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int asc_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 5e9cf0c48813..3048620315d6 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -537,7 +537,7 @@ static void stm32_usart_rx_dma_complete(void *arg) unsigned int size; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq_irqrestore(port, flags); if (size) @@ -643,9 +643,9 @@ static void stm32_usart_tx_dma_complete(void *arg) stm32_usart_tx_dma_terminate(stm32port); /* Let's see if we have pending data to send */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stm32_usart_transmit_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void stm32_usart_tx_interrupt_enable(struct uart_port *port) @@ -889,7 +889,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) if (!stm32_port->throttled) { if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_started(stm32_port)) || ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_started(stm32_port))) { - spin_lock(&port->lock); + uart_port_lock(port); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq(port); if (size) @@ -898,14 +898,14 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) } if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) { - spin_lock(&port->lock); + uart_port_lock(port); stm32_usart_transmit_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); } /* Receiver timeout irq for DMA RX */ if (stm32_usart_rx_dma_started(stm32_port) && !stm32_port->throttled) { - spin_lock(&port->lock); + uart_port_lock(port); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq(port); if (size) @@ -993,7 +993,7 @@ static void stm32_usart_throttle(struct uart_port *port) const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Pause DMA transfer, so the RX data gets queued into the FIFO. @@ -1006,7 +1006,7 @@ static void stm32_usart_throttle(struct uart_port *port) stm32_usart_clr_bits(port, ofs->cr3, stm32_port->cr3_irq); stm32_port->throttled = true; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Unthrottle the remote, the input buffer can now accept data. */ @@ -1016,7 +1016,7 @@ static void stm32_usart_unthrottle(struct uart_port *port) const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stm32_usart_set_bits(port, ofs->cr1, stm32_port->cr1_irq); if (stm32_port->cr3_irq) stm32_usart_set_bits(port, ofs->cr3, stm32_port->cr3_irq); @@ -1030,7 +1030,7 @@ static void stm32_usart_unthrottle(struct uart_port *port) if (stm32_port->rx_ch) stm32_usart_rx_dma_start_or_resume(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Receive stop */ @@ -1047,9 +1047,20 @@ static void stm32_usart_stop_rx(struct uart_port *port) stm32_usart_clr_bits(port, ofs->cr3, stm32_port->cr3_irq); } -/* Handle breaks - ignored by us */ static void stm32_usart_break_ctl(struct uart_port *port, int break_state) { + struct stm32_port *stm32_port = to_stm32_port(port); + const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + if (break_state) + stm32_usart_set_bits(port, ofs->rqr, USART_RQR_SBKRQ); + else + stm32_usart_clr_bits(port, ofs->rqr, USART_RQR_SBKRQ); + + spin_unlock_irqrestore(&port->lock, flags); } static int stm32_usart_startup(struct uart_port *port) @@ -1158,7 +1169,7 @@ static void stm32_usart_set_termios(struct uart_port *port, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 8); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, isr, @@ -1349,7 +1360,7 @@ static void stm32_usart_set_termios(struct uart_port *port, writel_relaxed(cr1, port->membase + ofs->cr1); stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Handle modem control interrupts */ if (UART_ENABLE_MS(port, termios->c_cflag)) @@ -1399,9 +1410,9 @@ static void stm32_usart_pm(struct uart_port *port, unsigned int state, pm_runtime_get_sync(port->dev); break; case UART_PM_STATE_OFF: - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stm32_usart_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); pm_runtime_put_sync(port->dev); break; } @@ -1884,9 +1895,9 @@ static void stm32_usart_console_write(struct console *co, const char *s, int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Save and disable interrupts, enable the transmitter */ old_cr1 = readl_relaxed(port->membase + ofs->cr1); @@ -1900,7 +1911,7 @@ static void stm32_usart_console_write(struct console *co, const char *s, writel_relaxed(old_cr1, port->membase + ofs->cr1); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int stm32_usart_console_setup(struct console *co, char *options) @@ -2035,7 +2046,7 @@ static int __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port, * low-power mode. */ if (stm32_port->rx_ch) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Poll data from DMA RX buffer if any */ if (!stm32_usart_rx_dma_pause(stm32_port)) size += stm32_usart_receive_chars(port, true); diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index c671d674bce4..5bfc0040f17b 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -217,10 +217,10 @@ static irqreturn_t sunhv_interrupt(int irq, void *dev_id) struct tty_port *tport; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); tport = receive_chars(port); transmit_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (tport) tty_flip_buffer_push(tport); @@ -271,7 +271,7 @@ static void sunhv_send_xchar(struct uart_port *port, char ch) if (ch == __DISABLED_CHAR) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (limit-- > 0) { long status = sun4v_con_putchar(ch); @@ -280,7 +280,7 @@ static void sunhv_send_xchar(struct uart_port *port, char ch) udelay(1); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* port->lock held by caller. */ @@ -295,7 +295,7 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state) unsigned long flags; int limit = 10000; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (limit-- > 0) { long status = sun4v_con_putchar(CON_BREAK); @@ -304,7 +304,7 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state) udelay(1); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } } @@ -328,7 +328,7 @@ static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios, unsigned int iflag, cflag; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); iflag = termios->c_iflag; cflag = termios->c_cflag; @@ -343,7 +343,7 @@ static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, cflag, (port->uartclk / (16 * quot))); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *sunhv_type(struct uart_port *port) @@ -437,9 +437,9 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign int locked = 1; if (port->sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (n > 0) { unsigned long ra = __pa(con_write_page); @@ -470,7 +470,7 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign } if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static inline void sunhv_console_putchar(struct uart_port *port, char c) @@ -492,9 +492,9 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig int i, locked = 1; if (port->sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); for (i = 0; i < n; i++) { if (*s == '\n') @@ -503,7 +503,7 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig } if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static struct console sunhv_console = { diff --git a/drivers/tty/serial/sunplus-uart.c b/drivers/tty/serial/sunplus-uart.c index 3aacd5eb414c..4251f4e1ba99 100644 --- a/drivers/tty/serial/sunplus-uart.c +++ b/drivers/tty/serial/sunplus-uart.c @@ -184,7 +184,7 @@ static void sunplus_break_ctl(struct uart_port *port, int ctl) unsigned long flags; unsigned int lcr; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); lcr = readl(port->membase + SUP_UART_LCR); @@ -195,7 +195,7 @@ static void sunplus_break_ctl(struct uart_port *port, int ctl) writel(lcr, port->membase + SUP_UART_LCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void transmit_chars(struct uart_port *port) @@ -277,7 +277,7 @@ static irqreturn_t sunplus_uart_irq(int irq, void *args) struct uart_port *port = args; unsigned int isc; - spin_lock(&port->lock); + uart_port_lock(port); isc = readl(port->membase + SUP_UART_ISC); @@ -287,7 +287,7 @@ static irqreturn_t sunplus_uart_irq(int irq, void *args) if (isc & SUP_UART_ISC_TX) transmit_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -302,14 +302,14 @@ static int sunplus_startup(struct uart_port *port) if (ret) return ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* isc define Bit[7:4] int setting, Bit[3:0] int status * isc register will clean Bit[3:0] int status after read * only do a write to Bit[7:4] int setting */ isc |= SUP_UART_ISC_RXM; writel(isc, port->membase + SUP_UART_ISC); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -318,13 +318,13 @@ static void sunplus_shutdown(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* isc define Bit[7:4] int setting, Bit[3:0] int status * isc register will clean Bit[3:0] int status after read * only do a write to Bit[7:4] int setting */ writel(0, port->membase + SUP_UART_ISC); /* disable all interrupt */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -372,7 +372,7 @@ static void sunplus_set_termios(struct uart_port *port, lcr |= UART_LCR_EPAR; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); @@ -407,7 +407,7 @@ static void sunplus_set_termios(struct uart_port *port, writel(div_l, port->membase + SUP_UART_DIV_L); writel(lcr, port->membase + SUP_UART_LCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sunplus_set_ldisc(struct uart_port *port, struct ktermios *termios) @@ -517,15 +517,15 @@ static void sunplus_console_write(struct console *co, if (sunplus_console_ports[co->index]->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&sunplus_console_ports[co->index]->port.lock); + locked = uart_port_trylock(&sunplus_console_ports[co->index]->port); else - spin_lock(&sunplus_console_ports[co->index]->port.lock); + uart_port_lock(&sunplus_console_ports[co->index]->port); uart_console_write(&sunplus_console_ports[co->index]->port, s, count, sunplus_uart_console_putchar); if (locked) - spin_unlock(&sunplus_console_ports[co->index]->port.lock); + uart_port_unlock(&sunplus_console_ports[co->index]->port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 40eeaf835bba..6aa51a6f8063 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -310,7 +310,7 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) unsigned long flags; unsigned char gis; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); status.stat = 0; gis = readb(&up->regs->r.gis) >> up->gis_shift; @@ -331,7 +331,7 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) transmit_chars(up, &status); } - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); if (port) tty_flip_buffer_push(port); @@ -473,12 +473,12 @@ static void sunsab_send_xchar(struct uart_port *port, char ch) if (ch == __DISABLED_CHAR) return; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); sunsab_tec_wait(up); writeb(ch, &up->regs->w.tic); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } /* port->lock held by caller. */ @@ -499,7 +499,7 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned char val; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); val = up->cached_dafo; if (break_state) @@ -512,7 +512,7 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state) if (test_bit(SAB82532_XPR, &up->irqflags)) sunsab_tx_idle(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } /* port->lock is not held. */ @@ -527,7 +527,7 @@ static int sunsab_startup(struct uart_port *port) if (err) return err; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Wait for any commands or immediate characters @@ -582,7 +582,7 @@ static int sunsab_startup(struct uart_port *port) set_bit(SAB82532_ALLS, &up->irqflags); set_bit(SAB82532_XPR, &up->irqflags); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } @@ -594,7 +594,7 @@ static void sunsab_shutdown(struct uart_port *port) container_of(port, struct uart_sunsab_port, port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* Disable Interrupts */ up->interrupt_mask0 = 0xff; @@ -628,7 +628,7 @@ static void sunsab_shutdown(struct uart_port *port) writeb(tmp, &up->regs->rw.ccr0); #endif - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); free_irq(up->port.irq, up); } @@ -779,9 +779,9 @@ static void sunsab_set_termios(struct uart_port *port, struct ktermios *termios, unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); unsigned int quot = uart_get_divisor(port, baud); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); sunsab_convert_to_sab(up, termios->c_cflag, termios->c_iflag, baud, quot); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static const char *sunsab_type(struct uart_port *port) @@ -857,15 +857,15 @@ static void sunsab_console_write(struct console *con, const char *s, unsigned n) int locked = 1; if (up->port.sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); + locked = uart_port_trylock_irqsave(&up->port, &flags); else - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); uart_console_write(&up->port, s, n, sunsab_console_putchar); sunsab_tec_wait(up); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int sunsab_console_setup(struct console *con, char *options) @@ -914,7 +914,7 @@ static int sunsab_console_setup(struct console *con, char *options) */ sunsab_startup(&up->port); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Finally, enable interrupts @@ -932,7 +932,7 @@ static int sunsab_console_setup(struct console *con, char *options) sunsab_convert_to_sab(up, con->cflag, 0, baud, quot); sunsab_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 58a4342ad0f9..1e051cc2591c 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -212,9 +212,9 @@ static void enable_rsa(struct uart_sunsu_port *up) { if (up->port.type == PORT_RSA) { if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); __enable_rsa(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) serial_outp(up, UART_RSA_FRR, 0); @@ -234,7 +234,7 @@ static void disable_rsa(struct uart_sunsu_port *up) if (up->port.type == PORT_RSA && up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); mode = serial_inp(up, UART_RSA_MSR); result = !(mode & UART_RSA_MSR_FIFO); @@ -247,7 +247,7 @@ static void disable_rsa(struct uart_sunsu_port *up) if (result) up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } } #endif /* CONFIG_SERIAL_8250_RSA */ @@ -311,10 +311,10 @@ static void sunsu_enable_ms(struct uart_port *port) container_of(port, struct uart_sunsu_port, port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void @@ -456,7 +456,7 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) unsigned long flags; unsigned char status; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); do { status = serial_inp(up, UART_LSR); @@ -470,7 +470,7 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) } while (!(serial_in(up, UART_IIR) & UART_IIR_NO_INT)); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return IRQ_HANDLED; } @@ -545,9 +545,9 @@ static unsigned int sunsu_tx_empty(struct uart_port *port) unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return ret; } @@ -599,13 +599,13 @@ static void sunsu_break_ctl(struct uart_port *port, int break_state) container_of(port, struct uart_sunsu_port, port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int sunsu_startup(struct uart_port *port) @@ -683,12 +683,12 @@ static int sunsu_startup(struct uart_port *port) */ serial_outp(up, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.mctrl |= TIOCM_OUT2; sunsu_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Finally, enable interrupts. Note: Modem status interrupts @@ -731,7 +731,7 @@ static void sunsu_shutdown(struct uart_port *port) up->ier = 0; serial_outp(up, UART_IER, 0); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (up->port.flags & UPF_FOURPORT) { /* reset interrupts on the AST Fourport board */ inb((up->port.iobase & 0xfe0) | 0x1f); @@ -740,7 +740,7 @@ static void sunsu_shutdown(struct uart_port *port) up->port.mctrl &= ~TIOCM_OUT2; sunsu_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Disable break condition and FIFOs @@ -826,7 +826,7 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Update the per-port timeout. @@ -891,7 +891,7 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag, up->cflag = cflag; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void @@ -1038,7 +1038,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) up->type_probed = PORT_UNKNOWN; up->port.iotype = UPIO_MEM; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (!(up->port.flags & UPF_BUGGY_UART)) { /* @@ -1173,7 +1173,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) serial_outp(up, UART_IER, 0); out: - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static struct uart_driver sunsu_reg = { @@ -1298,9 +1298,9 @@ static void sunsu_console_write(struct console *co, const char *s, int locked = 1; if (up->port.sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); + locked = uart_port_trylock_irqsave(&up->port, &flags); else - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * First save the UER then disable the interrupts @@ -1318,7 +1318,7 @@ static void sunsu_console_write(struct console *co, const char *s, serial_out(up, UART_IER, ier); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } /* diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index c8c71c56264c..d3b5e864b727 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -531,7 +531,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) struct tty_port *port; unsigned char r3; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); r3 = read_zsreg(channel, R3); /* Channel A */ @@ -548,7 +548,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) if (r3 & CHATxIP) sunzilog_transmit_chars(up, channel); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); if (port) tty_flip_buffer_push(port); @@ -557,7 +557,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) up = up->next; channel = ZILOG_CHANNEL_FROM_PORT(&up->port); - spin_lock(&up->port.lock); + uart_port_lock(&up->port); port = NULL; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { writeb(RES_H_IUS, &channel->control); @@ -571,7 +571,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) if (r3 & CHBTxIP) sunzilog_transmit_chars(up, channel); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); if (port) tty_flip_buffer_push(port); @@ -604,11 +604,11 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port) unsigned char status; unsigned int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = sunzilog_read_channel_status(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; @@ -764,7 +764,7 @@ static void sunzilog_break_ctl(struct uart_port *port, int break_state) else clear_bits |= SND_BRK; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); new_reg = (up->curregs[R5] | set_bits) & ~clear_bits; if (new_reg != up->curregs[R5]) { @@ -774,7 +774,7 @@ static void sunzilog_break_ctl(struct uart_port *port, int break_state) write_zsreg(channel, R5, up->curregs[R5]); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void __sunzilog_startup(struct uart_sunzilog_port *up) @@ -800,9 +800,9 @@ static int sunzilog_startup(struct uart_port *port) if (ZS_IS_CONS(up)) return 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); __sunzilog_startup(up); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -840,7 +840,7 @@ static void sunzilog_shutdown(struct uart_port *port) if (ZS_IS_CONS(up)) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); channel = ZILOG_CHANNEL_FROM_PORT(port); @@ -853,7 +853,7 @@ static void sunzilog_shutdown(struct uart_port *port) up->curregs[R5] &= ~SND_BRK; sunzilog_maybe_update_regs(up, channel); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Shared by TTY driver and serial console setup. The port lock is held @@ -945,7 +945,7 @@ sunzilog_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 1200, 76800); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); @@ -962,7 +962,7 @@ sunzilog_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static const char *sunzilog_type(struct uart_port *port) @@ -1201,15 +1201,15 @@ sunzilog_console_write(struct console *con, const char *s, unsigned int count) int locked = 1; if (up->port.sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); + locked = uart_port_trylock_irqsave(&up->port, &flags); else - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); uart_console_write(&up->port, s, count, sunzilog_putchar); udelay(2); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int __init sunzilog_console_setup(struct console *con, char *options) @@ -1244,7 +1244,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->curregs[R15] |= BRKIE; sunzilog_convert_to_zs(up, con->cflag, 0, brg); @@ -1252,7 +1252,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); __sunzilog_startup(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } @@ -1333,7 +1333,7 @@ static void sunzilog_init_hw(struct uart_sunzilog_port *up) channel = ZILOG_CHANNEL_FROM_PORT(&up->port); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (ZS_IS_CHANNEL_A(up)) { write_zsreg(channel, R9, FHWRES); ZSDELAY_LONG(); @@ -1383,7 +1383,7 @@ static void sunzilog_init_hw(struct uart_sunzilog_port *up) write_zsreg(channel, R9, up->curregs[R9]); } - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); #ifdef CONFIG_SERIO if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 0859394a78cd..0cc6524f5e8b 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c @@ -174,7 +174,7 @@ static void timbuart_tasklet(struct tasklet_struct *t) struct timbuart_port *uart = from_tasklet(uart, t, tasklet); u32 isr, ier = 0; - spin_lock(&uart->port.lock); + uart_port_lock(&uart->port); isr = ioread32(uart->port.membase + TIMBUART_ISR); dev_dbg(uart->port.dev, "%s ISR: %x\n", __func__, isr); @@ -189,7 +189,7 @@ static void timbuart_tasklet(struct tasklet_struct *t) iowrite32(ier, uart->port.membase + TIMBUART_IER); - spin_unlock(&uart->port.lock); + uart_port_unlock(&uart->port); dev_dbg(uart->port.dev, "%s leaving\n", __func__); } @@ -295,10 +295,10 @@ static void timbuart_set_termios(struct uart_port *port, tty_termios_copy_hw(termios, old); tty_termios_encode_baud_rate(termios, baud, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); iowrite8((u8)bindex, port->membase + TIMBUART_BAUDRATE); uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *timbuart_type(struct uart_port *port) diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index b225a78f6175..404c14acafa5 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -216,11 +216,11 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) unsigned long flags; do { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stat = uart_in32(ULITE_STATUS, port); busy = ulite_receive(port, stat); busy |= ulite_transmit(port, stat); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); n++; } while (busy); @@ -238,9 +238,9 @@ static unsigned int ulite_tx_empty(struct uart_port *port) unsigned long flags; unsigned int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = uart_in32(ULITE_STATUS, port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; } @@ -323,7 +323,7 @@ static void ulite_set_termios(struct uart_port *port, termios->c_cflag |= pdata->cflags & (PARENB | PARODD | CSIZE); tty_termios_encode_baud_rate(termios, pdata->baud, pdata->baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN | ULITE_STATUS_TXFULL; @@ -346,7 +346,7 @@ static void ulite_set_termios(struct uart_port *port, /* update timeout */ uart_update_timeout(port, termios->c_cflag, pdata->baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *ulite_type(struct uart_port *port) @@ -495,9 +495,9 @@ static void ulite_console_write(struct console *co, const char *s, int locked = 1; if (oops_in_progress) { - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); } else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* save and disable interrupt */ ier = uart_in32(ULITE_STATUS, port) & ULITE_STATUS_IE; @@ -512,7 +512,7 @@ static void ulite_console_write(struct console *co, const char *s, uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int ulite_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index b06661b80f41..ed7a6bb5596a 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -931,7 +931,7 @@ static void qe_uart_set_termios(struct uart_port *port, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); /* Do we really need a spinlock here? */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); @@ -949,7 +949,7 @@ static void qe_uart_set_termios(struct uart_port *port, qe_setbrg(qe_port->us_info.tx_clock, baud, 16); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index c5d5c2765119..78a1c1eea11b 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -227,7 +227,7 @@ static irqreturn_t vt8500_irq(int irq, void *dev_id) struct uart_port *port = dev_id; unsigned long isr; - spin_lock(&port->lock); + uart_port_lock(port); isr = vt8500_read(port, VT8500_URISR); /* Acknowledge active status bits */ @@ -240,7 +240,7 @@ static irqreturn_t vt8500_irq(int irq, void *dev_id) if (isr & TCTS) handle_delta_cts(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -342,7 +342,7 @@ static void vt8500_set_termios(struct uart_port *port, unsigned int baud, lcr; unsigned int loops = 1000; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* calculate and set baud rate */ baud = uart_get_baud_rate(port, termios, old, 900, 921600); @@ -410,7 +410,7 @@ static void vt8500_set_termios(struct uart_port *port, vt8500_write(&vt8500_port->uart, 0x881, VT8500_URFCR); vt8500_write(&vt8500_port->uart, vt8500_port->ier, VT8500_URIER); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *vt8500_type(struct uart_port *port) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 2e5e86a00a77..66a45a634158 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -346,7 +346,7 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) struct uart_port *port = (struct uart_port *)dev_id; unsigned int isrstatus; - spin_lock(&port->lock); + uart_port_lock(port); /* Read the interrupt status register to determine which * interrupt(s) is/are active and clear them. @@ -369,7 +369,7 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) !(readl(port->membase + CDNS_UART_CR) & CDNS_UART_CR_RX_DIS)) cdns_uart_handle_rx(dev_id, isrstatus); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -506,14 +506,14 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, return NOTIFY_BAD; } - spin_lock_irqsave(&cdns_uart->port->lock, flags); + uart_port_lock_irqsave(cdns_uart->port, &flags); /* Disable the TX and RX to set baud rate */ ctrl_reg = readl(port->membase + CDNS_UART_CR); ctrl_reg |= CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS; writel(ctrl_reg, port->membase + CDNS_UART_CR); - spin_unlock_irqrestore(&cdns_uart->port->lock, flags); + uart_port_unlock_irqrestore(cdns_uart->port, flags); return NOTIFY_OK; } @@ -523,7 +523,7 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, * frequency. */ - spin_lock_irqsave(&cdns_uart->port->lock, flags); + uart_port_lock_irqsave(cdns_uart->port, &flags); locked = 1; port->uartclk = ndata->new_rate; @@ -533,7 +533,7 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, fallthrough; case ABORT_RATE_CHANGE: if (!locked) - spin_lock_irqsave(&cdns_uart->port->lock, flags); + uart_port_lock_irqsave(cdns_uart->port, &flags); /* Set TX/RX Reset */ ctrl_reg = readl(port->membase + CDNS_UART_CR); @@ -555,7 +555,7 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN; writel(ctrl_reg, port->membase + CDNS_UART_CR); - spin_unlock_irqrestore(&cdns_uart->port->lock, flags); + uart_port_unlock_irqrestore(cdns_uart->port, flags); return NOTIFY_OK; default: @@ -652,19 +652,19 @@ static void cdns_uart_break_ctl(struct uart_port *port, int ctl) unsigned int status; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = readl(port->membase + CDNS_UART_CR); if (ctl == -1) - writel(CDNS_UART_CR_STARTBRK | status, + writel(CDNS_UART_CR_STARTBRK | (~CDNS_UART_CR_STOPBRK & status), port->membase + CDNS_UART_CR); else { if ((status & CDNS_UART_CR_STOPBRK) == 0) writel(CDNS_UART_CR_STOPBRK | status, port->membase + CDNS_UART_CR); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /** @@ -683,7 +683,7 @@ static void cdns_uart_set_termios(struct uart_port *port, unsigned long flags; unsigned int ctrl_reg, mode_reg; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable the TX and RX to set baud rate */ ctrl_reg = readl(port->membase + CDNS_UART_CR); @@ -794,7 +794,7 @@ static void cdns_uart_set_termios(struct uart_port *port, cval &= ~CDNS_UART_MODEMCR_FCM; writel(cval, port->membase + CDNS_UART_MODEMCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /** @@ -813,7 +813,7 @@ static int cdns_uart_startup(struct uart_port *port) is_brk_support = cdns_uart->quirks & CDNS_UART_RXBS_SUPPORT; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable the TX and RX */ writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS, @@ -861,7 +861,7 @@ static int cdns_uart_startup(struct uart_port *port) writel(readl(port->membase + CDNS_UART_ISR), port->membase + CDNS_UART_ISR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = request_irq(port->irq, cdns_uart_isr, 0, CDNS_UART_NAME, port); if (ret) { @@ -889,7 +889,7 @@ static void cdns_uart_shutdown(struct uart_port *port) int status; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable interrupts */ status = readl(port->membase + CDNS_UART_IMR); @@ -900,7 +900,7 @@ static void cdns_uart_shutdown(struct uart_port *port) writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS, port->membase + CDNS_UART_CR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -1050,7 +1050,7 @@ static int cdns_uart_poll_get_char(struct uart_port *port) int c; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Check if FIFO is empty */ if (readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_RXEMPTY) @@ -1058,7 +1058,7 @@ static int cdns_uart_poll_get_char(struct uart_port *port) else /* Read a character */ c = (unsigned char) readl(port->membase + CDNS_UART_FIFO); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return c; } @@ -1067,7 +1067,7 @@ static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Wait until FIFO is empty */ while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY)) @@ -1080,7 +1080,7 @@ static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c) while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY)) cpu_relax(); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #endif @@ -1232,9 +1232,9 @@ static void cdns_uart_console_write(struct console *co, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* save and disable interrupt */ imr = readl(port->membase + CDNS_UART_IMR); @@ -1257,7 +1257,7 @@ static void cdns_uart_console_write(struct console *co, const char *s, writel(imr, port->membase + CDNS_UART_IER); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /** @@ -1325,7 +1325,7 @@ static int cdns_uart_suspend(struct device *device) if (console_suspend_enabled && uart_console(port) && may_wake) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Empty the receive FIFO 1st before making changes */ while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_RXEMPTY)) @@ -1334,7 +1334,7 @@ static int cdns_uart_suspend(struct device *device) writel(1, port->membase + CDNS_UART_RXWM); /* disable RX timeout interrups */ writel(CDNS_UART_IXR_TOUT, port->membase + CDNS_UART_IDR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* @@ -1372,7 +1372,7 @@ static int cdns_uart_resume(struct device *device) return ret; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Set TX/RX Reset */ ctrl_reg = readl(port->membase + CDNS_UART_CR); @@ -1392,14 +1392,14 @@ static int cdns_uart_resume(struct device *device) clk_disable(cdns_uart->uartclk); clk_disable(cdns_uart->pclk); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } else { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* restore original rx trigger level */ writel(rx_trigger_level, port->membase + CDNS_UART_RXWM); /* enable RX timeout interrupt */ writel(CDNS_UART_IXR_TOUT, port->membase + CDNS_UART_IER); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } return uart_resume_port(cdns_uart->cdns_uart_driver, port); diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 23198e3f1461..6b4a28bcf2f5 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -262,13 +262,14 @@ static void sysrq_handle_showallcpus(u8 key) if (in_hardirq()) regs = get_irq_regs(); - pr_info("CPU%d:\n", smp_processor_id()); + pr_info("CPU%d:\n", get_cpu()); if (regs) show_regs(regs); else show_stack(NULL, NULL, KERN_INFO); schedule_work(&sysrq_showallcpus); + put_cpu(); } } diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 50862f98273e..93cf5ef1e857 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -41,15 +41,20 @@ enum { }; /* Values for tty->flow_change */ -#define TTY_THROTTLE_SAFE 1 -#define TTY_UNTHROTTLE_SAFE 2 +enum tty_flow_change { + TTY_FLOW_NO_CHANGE, + TTY_THROTTLE_SAFE, + TTY_UNTHROTTLE_SAFE, +}; -static inline void __tty_set_flow_change(struct tty_struct *tty, int val) +static inline void __tty_set_flow_change(struct tty_struct *tty, + enum tty_flow_change val) { tty->flow_change = val; } -static inline void tty_set_flow_change(struct tty_struct *tty, int val) +static inline void tty_set_flow_change(struct tty_struct *tty, + enum tty_flow_change val) { tty->flow_change = val; smp_mb(); diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 5f6d0cf67571..f8883afbeeba 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -69,12 +69,11 @@ EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive); void tty_buffer_unlock_exclusive(struct tty_port *port) { struct tty_bufhead *buf = &port->buf; - int restart; - - restart = buf->head->commit != buf->head->read; + bool restart = buf->head->commit != buf->head->read; atomic_dec(&buf->priority); mutex_unlock(&buf->lock); + if (restart) queue_work(system_unbound_wq, &buf->work); } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 0216a468b438..06414e43e0b5 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -159,7 +159,7 @@ static int tty_fasync(int fd, struct file *filp, int on); static void release_tty(struct tty_struct *tty, int idx); /** - * free_tty_struct - free a disused tty + * free_tty_struct - free a disused tty * @tty: tty struct to free * * Free the write buffers, tty queue and tty memory itself. @@ -233,7 +233,7 @@ static void tty_del_file(struct file *file) } /** - * tty_name - return tty naming + * tty_name - return tty naming * @tty: tty structure * * Convert a tty structure into a name. The name reflects the kernel naming @@ -295,7 +295,7 @@ static void check_tty_count(struct tty_struct *tty, const char *routine) } /** - * get_tty_driver - find device of a tty + * get_tty_driver - find device of a tty * @device: device identifier * @index: returns the index of the tty * @@ -320,7 +320,7 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) } /** - * tty_dev_name_to_number - return dev_t for device name + * tty_dev_name_to_number - return dev_t for device name * @name: user space name of device under /dev * @number: pointer to dev_t that this function will populate * @@ -372,7 +372,7 @@ EXPORT_SYMBOL_GPL(tty_dev_name_to_number); #ifdef CONFIG_CONSOLE_POLL /** - * tty_find_polling_driver - find device of a polled tty + * tty_find_polling_driver - find device of a polled tty * @name: name string to match * @line: pointer to resulting tty line nr * @@ -505,7 +505,7 @@ static DEFINE_SPINLOCK(redirect_lock); static struct file *redirect; /** - * tty_wakeup - request more data + * tty_wakeup - request more data * @tty: terminal * * Internal and external helper for wakeups of tty. This function informs the @@ -529,7 +529,7 @@ void tty_wakeup(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_wakeup); /** - * tty_release_redirect - Release a redirect on a pty if present + * tty_release_redirect - Release a redirect on a pty if present * @tty: tty device * * This is available to the pty code so if the master closes, if the slave is a @@ -550,7 +550,7 @@ static struct file *tty_release_redirect(struct tty_struct *tty) } /** - * __tty_hangup - actual handler for hangup events + * __tty_hangup - actual handler for hangup events * @tty: tty device * @exit_session: if non-zero, signal all foreground group processes * @@ -673,7 +673,7 @@ static void do_tty_hangup(struct work_struct *work) } /** - * tty_hangup - trigger a hangup event + * tty_hangup - trigger a hangup event * @tty: tty to hangup * * A carrier loss (virtual or otherwise) has occurred on @tty. Schedule a @@ -687,7 +687,7 @@ void tty_hangup(struct tty_struct *tty) EXPORT_SYMBOL(tty_hangup); /** - * tty_vhangup - process vhangup + * tty_vhangup - process vhangup * @tty: tty to hangup * * The user has asked via system call for the terminal to be hung up. We do @@ -703,7 +703,7 @@ EXPORT_SYMBOL(tty_vhangup); /** - * tty_vhangup_self - process vhangup for own ctty + * tty_vhangup_self - process vhangup for own ctty * * Perform a vhangup on the current controlling tty */ @@ -719,7 +719,7 @@ void tty_vhangup_self(void) } /** - * tty_vhangup_session - hangup session leader exit + * tty_vhangup_session - hangup session leader exit * @tty: tty to hangup * * The session leader is exiting and hanging up its controlling terminal. @@ -735,7 +735,7 @@ void tty_vhangup_session(struct tty_struct *tty) } /** - * tty_hung_up_p - was tty hung up + * tty_hung_up_p - was tty hung up * @filp: file pointer of tty * * Return: true if the tty has been subject to a vhangup or a carrier loss @@ -756,7 +756,7 @@ void __stop_tty(struct tty_struct *tty) } /** - * stop_tty - propagate flow control + * stop_tty - propagate flow control * @tty: tty to stop * * Perform flow control to the driver. May be called on an already stopped @@ -790,7 +790,7 @@ void __start_tty(struct tty_struct *tty) } /** - * start_tty - propagate flow control + * start_tty - propagate flow control * @tty: tty to start * * Start a tty that has been stopped if at all possible. If @tty was previously @@ -902,7 +902,7 @@ static ssize_t iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, /** - * tty_read - read method for tty device files + * tty_read - read method for tty device files * @iocb: kernel I/O control block * @to: destination for the data read * @@ -1095,7 +1095,7 @@ static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_ } /** - * tty_write - write method for tty device file + * tty_write - write method for tty device file * @iocb: kernel I/O control block * @from: iov_iter with data to write * @@ -1137,7 +1137,7 @@ ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) } /** - * tty_send_xchar - send priority character + * tty_send_xchar - send priority character * @tty: the tty to send to * @ch: xchar to send * @@ -1171,7 +1171,7 @@ int tty_send_xchar(struct tty_struct *tty, char ch) } /** - * pty_line_name - generate name for a pty + * pty_line_name - generate name for a pty * @driver: the tty driver in use * @index: the minor number * @p: output buffer of at least 6 bytes @@ -1192,7 +1192,7 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) } /** - * tty_line_name - generate name for a tty + * tty_line_name - generate name for a tty * @driver: the tty driver in use * @index: the minor number * @p: output buffer of at least 7 bytes @@ -1243,7 +1243,7 @@ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, } /** - * tty_init_termios - helper for termios setup + * tty_init_termios - helper for termios setup * @tty: the tty to set up * * Initialise the termios structure for this tty. This runs under the @@ -1326,7 +1326,7 @@ static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct * } /** - * tty_reopen() - fast re-open of an open tty + * tty_reopen() - fast re-open of an open tty * @tty: the tty to open * * Re-opens on master ptys are not allowed and return -%EIO. @@ -1370,7 +1370,7 @@ static int tty_reopen(struct tty_struct *tty) } /** - * tty_init_dev - initialise a tty device + * tty_init_dev - initialise a tty device * @driver: tty driver we are opening a device on * @idx: device index * @@ -1492,7 +1492,7 @@ void tty_save_termios(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_save_termios); /** - * tty_flush_works - flush all works of a tty/pty pair + * tty_flush_works - flush all works of a tty/pty pair * @tty: tty device to flush works for (or either end of a pty pair) * * Sync flush all works belonging to @tty (and the 'other' tty). @@ -1508,7 +1508,7 @@ static void tty_flush_works(struct tty_struct *tty) } /** - * release_one_tty - release tty structure memory + * release_one_tty - release tty structure memory * @work: work of tty we are obliterating * * Releases memory associated with a tty structure, and clears out the @@ -1556,7 +1556,7 @@ static void queue_release_one_tty(struct kref *kref) } /** - * tty_kref_put - release a tty kref + * tty_kref_put - release a tty kref * @tty: tty device * * Release a reference to the @tty device and if need be let the kref layer @@ -1570,7 +1570,7 @@ void tty_kref_put(struct tty_struct *tty) EXPORT_SYMBOL(tty_kref_put); /** - * release_tty - release tty structure memory + * release_tty - release tty structure memory * @tty: tty device release * @idx: index of the tty device release * @@ -1647,7 +1647,7 @@ static int tty_release_checks(struct tty_struct *tty, int idx) } /** - * tty_kclose - closes tty opened by tty_kopen + * tty_kclose - closes tty opened by tty_kopen * @tty: tty device * * Performs the final steps to release and free a tty device. It is the same as @@ -1677,7 +1677,7 @@ void tty_kclose(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_kclose); /** - * tty_release_struct - release a tty struct + * tty_release_struct - release a tty struct * @tty: tty device * @idx: index of the tty * @@ -1706,7 +1706,7 @@ void tty_release_struct(struct tty_struct *tty, int idx) EXPORT_SYMBOL_GPL(tty_release_struct); /** - * tty_release - vfs callback for close + * tty_release - vfs callback for close * @inode: inode of tty * @filp: file pointer for handle to tty * @@ -1987,7 +1987,7 @@ out: } /** - * tty_kopen_exclusive - open a tty device for kernel + * tty_kopen_exclusive - open a tty device for kernel * @device: dev_t of device to open * * Opens tty exclusively for kernel. Performs the driver lookup, makes sure @@ -2007,7 +2007,7 @@ struct tty_struct *tty_kopen_exclusive(dev_t device) EXPORT_SYMBOL_GPL(tty_kopen_exclusive); /** - * tty_kopen_shared - open a tty device for shared in-kernel use + * tty_kopen_shared - open a tty device for shared in-kernel use * @device: dev_t of device to open * * Opens an already existing tty for in-kernel use. Compared to @@ -2022,7 +2022,7 @@ struct tty_struct *tty_kopen_shared(dev_t device) EXPORT_SYMBOL_GPL(tty_kopen_shared); /** - * tty_open_by_driver - open a tty device + * tty_open_by_driver - open a tty device * @device: dev_t of device to open * @filp: file pointer to tty * @@ -2090,7 +2090,7 @@ out: } /** - * tty_open - open a tty device + * tty_open - open a tty device * @inode: inode of device file * @filp: file pointer to tty * @@ -2184,7 +2184,7 @@ retry_open: /** - * tty_poll - check tty status + * tty_poll - check tty status * @filp: file being polled * @wait: poll wait structures to update * @@ -2262,7 +2262,7 @@ static int tty_fasync(int fd, struct file *filp, int on) static bool tty_legacy_tiocsti __read_mostly = IS_ENABLED(CONFIG_LEGACY_TIOCSTI); /** - * tiocsti - fake input character + * tiocsti - fake input character * @tty: tty to fake input into * @p: pointer to character * @@ -2299,7 +2299,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p) } /** - * tiocgwinsz - implement window query ioctl + * tiocgwinsz - implement window query ioctl * @tty: tty * @arg: user buffer for result * @@ -2320,7 +2320,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) } /** - * tty_do_resize - resize event + * tty_do_resize - resize event * @tty: tty being resized * @ws: new dimensions * @@ -2350,7 +2350,7 @@ done: EXPORT_SYMBOL(tty_do_resize); /** - * tiocswinsz - implement window size set ioctl + * tiocswinsz - implement window size set ioctl * @tty: tty side of tty * @arg: user buffer for result * @@ -2377,7 +2377,7 @@ static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) } /** - * tioccons - allow admin to move logical console + * tioccons - allow admin to move logical console * @file: the file to become console * * Allow the administrator to move the redirected console device. @@ -2416,7 +2416,7 @@ static int tioccons(struct file *file) } /** - * tiocsetd - set line discipline + * tiocsetd - set line discipline * @tty: tty device * @p: pointer to user data * @@ -2438,7 +2438,7 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) } /** - * tiocgetd - get line discipline + * tiocgetd - get line discipline * @tty: tty device * @p: pointer to user data * @@ -2461,7 +2461,7 @@ static int tiocgetd(struct tty_struct *tty, int __user *p) } /** - * send_break - performed time break + * send_break - performed time break * @tty: device to break on * @duration: timeout in mS * @@ -2479,27 +2479,27 @@ static int send_break(struct tty_struct *tty, unsigned int duration) return 0; if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) - retval = tty->ops->break_ctl(tty, duration); - else { - /* Do the work ourselves */ - if (tty_write_lock(tty, false) < 0) - return -EINTR; - retval = tty->ops->break_ctl(tty, -1); - if (retval) - goto out; - if (!signal_pending(current)) - msleep_interruptible(duration); + return tty->ops->break_ctl(tty, duration); + + /* Do the work ourselves */ + if (tty_write_lock(tty, false) < 0) + return -EINTR; + + retval = tty->ops->break_ctl(tty, -1); + if (!retval) { + msleep_interruptible(duration); retval = tty->ops->break_ctl(tty, 0); -out: - tty_write_unlock(tty); - if (signal_pending(current)) - retval = -EINTR; } + tty_write_unlock(tty); + + if (signal_pending(current)) + retval = -EINTR; + return retval; } /** - * tty_tiocmget - get modem status + * tty_tiocmget - get modem status * @tty: tty device * @p: pointer to result * @@ -2522,7 +2522,7 @@ static int tty_tiocmget(struct tty_struct *tty, int __user *p) } /** - * tty_tiocmset - set modem status + * tty_tiocmset - set modem status * @tty: tty device * @cmd: command - clear bits, set bits or set all * @p: pointer to desired bits @@ -2563,7 +2563,7 @@ static int tty_tiocmset(struct tty_struct *tty, unsigned int cmd, } /** - * tty_get_icount - get tty statistics + * tty_get_icount - get tty statistics * @tty: tty device * @icount: output parameter * @@ -3126,7 +3126,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) } /** - * tty_put_char - write one character to a tty + * tty_put_char - write one character to a tty * @tty: tty * @ch: character to write * @@ -3304,7 +3304,7 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) EXPORT_SYMBOL(tty_unregister_device); /** - * __tty_alloc_driver -- allocate tty driver + * __tty_alloc_driver - allocate tty driver * @lines: count of lines this driver can handle at most * @owner: module which is responsible for this driver * @flags: some of %TTY_DRIVER_ flags, will be set in driver->flags @@ -3397,7 +3397,7 @@ static void destruct_tty_driver(struct kref *kref) } /** - * tty_driver_kref_put -- drop a reference to a tty driver + * tty_driver_kref_put - drop a reference to a tty driver * @driver: driver of which to drop the reference * * The final put will destroy and free up the driver. @@ -3409,7 +3409,7 @@ void tty_driver_kref_put(struct tty_driver *driver) EXPORT_SYMBOL(tty_driver_kref_put); /** - * tty_register_driver -- register a tty driver + * tty_register_driver - register a tty driver * @driver: driver to register * * Called by a tty driver to register itself. @@ -3474,7 +3474,7 @@ err: EXPORT_SYMBOL(tty_register_driver); /** - * tty_unregister_driver -- unregister a tty driver + * tty_unregister_driver - unregister a tty driver * @driver: driver to unregister * * Called by a tty driver to unregister itself. diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 7958bf6d27c4..4b499301a3db 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -38,16 +38,13 @@ #define TERMIOS_TERMIO BIT(2) #define TERMIOS_OLD BIT(3) - /** - * tty_chars_in_buffer - characters pending - * @tty: terminal + * tty_chars_in_buffer - characters pending + * @tty: terminal * - * Return the number of bytes of data in the device private - * output queue. If no private method is supplied there is assumed - * to be no queue on the device. + * Returns: the number of bytes of data in the device private output queue. If + * no private method is supplied there is assumed to be no queue on the device. */ - unsigned int tty_chars_in_buffer(struct tty_struct *tty) { if (tty->ops->chars_in_buffer) @@ -57,16 +54,15 @@ unsigned int tty_chars_in_buffer(struct tty_struct *tty) EXPORT_SYMBOL(tty_chars_in_buffer); /** - * tty_write_room - write queue space - * @tty: terminal + * tty_write_room - write queue space + * @tty: terminal * - * Return the number of bytes that can be queued to this device - * at the present time. The result should be treated as a guarantee - * and the driver cannot offer a value it later shrinks by more than - * the number of bytes written. If no method is provided 2K is always - * returned and data may be lost as there will be no flow control. + * Returns: the number of bytes that can be queued to this device at the present + * time. The result should be treated as a guarantee and the driver cannot + * offer a value it later shrinks by more than the number of bytes written. If + * no method is provided, 2K is always returned and data may be lost as there + * will be no flow control. */ - unsigned int tty_write_room(struct tty_struct *tty) { if (tty->ops->write_room) @@ -76,12 +72,12 @@ unsigned int tty_write_room(struct tty_struct *tty) EXPORT_SYMBOL(tty_write_room); /** - * tty_driver_flush_buffer - discard internal buffer - * @tty: terminal + * tty_driver_flush_buffer - discard internal buffer + * @tty: terminal * - * Discard the internal output buffer for this device. If no method - * is provided then either the buffer cannot be hardware flushed or - * there is no buffer driver side. + * Discard the internal output buffer for this device. If no method is provided, + * then either the buffer cannot be hardware flushed or there is no buffer + * driver side. */ void tty_driver_flush_buffer(struct tty_struct *tty) { @@ -91,50 +87,47 @@ void tty_driver_flush_buffer(struct tty_struct *tty) EXPORT_SYMBOL(tty_driver_flush_buffer); /** - * tty_unthrottle - flow control - * @tty: terminal + * tty_unthrottle - flow control + * @tty: terminal * - * Indicate that a tty may continue transmitting data down the stack. - * Takes the termios rwsem to protect against parallel throttle/unthrottle - * and also to ensure the driver can consistently reference its own - * termios data at this point when implementing software flow control. + * Indicate that a @tty may continue transmitting data down the stack. Takes + * the &tty_struct->termios_rwsem to protect against parallel + * throttle/unthrottle and also to ensure the driver can consistently reference + * its own termios data at this point when implementing software flow control. * - * Drivers should however remember that the stack can issue a throttle, - * then change flow control method, then unthrottle. + * Drivers should however remember that the stack can issue a throttle, then + * change flow control method, then unthrottle. */ - void tty_unthrottle(struct tty_struct *tty) { down_write(&tty->termios_rwsem); if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && tty->ops->unthrottle) tty->ops->unthrottle(tty); - tty->flow_change = 0; + tty->flow_change = TTY_FLOW_NO_CHANGE; up_write(&tty->termios_rwsem); } EXPORT_SYMBOL(tty_unthrottle); /** - * tty_throttle_safe - flow control - * @tty: terminal + * tty_throttle_safe - flow control + * @tty: terminal * - * Indicate that a tty should stop transmitting data down the stack. - * tty_throttle_safe will only attempt throttle if tty->flow_change is - * TTY_THROTTLE_SAFE. Prevents an accidental throttle due to race - * conditions when throttling is conditional on factors evaluated prior to - * throttling. + * Indicate that a @tty should stop transmitting data down the stack. + * tty_throttle_safe() will only attempt throttle if @tty->flow_change is + * %TTY_THROTTLE_SAFE. Prevents an accidental throttle due to race conditions + * when throttling is conditional on factors evaluated prior to throttling. * - * Returns 0 if tty is throttled (or was already throttled) + * Returns: %true if @tty is throttled (or was already throttled) */ - -int tty_throttle_safe(struct tty_struct *tty) +bool tty_throttle_safe(struct tty_struct *tty) { - int ret = 0; + bool ret = true; mutex_lock(&tty->throttle_mutex); if (!tty_throttled(tty)) { if (tty->flow_change != TTY_THROTTLE_SAFE) - ret = 1; + ret = false; else { set_bit(TTY_THROTTLED, &tty->flags); if (tty->ops->throttle) @@ -147,25 +140,24 @@ int tty_throttle_safe(struct tty_struct *tty) } /** - * tty_unthrottle_safe - flow control - * @tty: terminal + * tty_unthrottle_safe - flow control + * @tty: terminal * - * Similar to tty_unthrottle() but will only attempt unthrottle - * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental - * unthrottle due to race conditions when unthrottling is conditional - * on factors evaluated prior to unthrottling. + * Similar to tty_unthrottle() but will only attempt unthrottle if + * @tty->flow_change is %TTY_UNTHROTTLE_SAFE. Prevents an accidental unthrottle + * due to race conditions when unthrottling is conditional on factors evaluated + * prior to unthrottling. * - * Returns 0 if tty is unthrottled (or was already unthrottled) + * Returns: %true if @tty is unthrottled (or was already unthrottled) */ - -int tty_unthrottle_safe(struct tty_struct *tty) +bool tty_unthrottle_safe(struct tty_struct *tty) { - int ret = 0; + bool ret = true; mutex_lock(&tty->throttle_mutex); if (tty_throttled(tty)) { if (tty->flow_change != TTY_UNTHROTTLE_SAFE) - ret = 1; + ret = false; else { clear_bit(TTY_THROTTLED, &tty->flags); if (tty->ops->unthrottle) @@ -178,14 +170,14 @@ int tty_unthrottle_safe(struct tty_struct *tty) } /** - * tty_wait_until_sent - wait for I/O to finish - * @tty: tty we are waiting for - * @timeout: how long we will wait + * tty_wait_until_sent - wait for I/O to finish + * @tty: tty we are waiting for + * @timeout: how long we will wait * - * Wait for characters pending in a tty driver to hit the wire, or - * for a timeout to occur (eg due to flow control) + * Wait for characters pending in a tty driver to hit the wire, or for a + * timeout to occur (eg due to flow control). * - * Locking: none + * Locking: none */ void tty_wait_until_sent(struct tty_struct *tty, long timeout) @@ -231,16 +223,15 @@ static void unset_locked_termios(struct tty_struct *tty, const struct ktermios * } /** - * tty_termios_copy_hw - copy hardware settings - * @new: New termios - * @old: Old termios + * tty_termios_copy_hw - copy hardware settings + * @new: new termios + * @old: old termios * - * Propagate the hardware specific terminal setting bits from - * the old termios structure to the new one. This is used in cases - * where the hardware does not support reconfiguration or as a helper - * in some cases where only minimal reconfiguration is supported + * Propagate the hardware specific terminal setting bits from the @old termios + * structure to the @new one. This is used in cases where the hardware does not + * support reconfiguration or as a helper in some cases where only minimal + * reconfiguration is supported. */ - void tty_termios_copy_hw(struct ktermios *new, const struct ktermios *old) { /* The bits a dumb device handles in software. Smart devices need @@ -253,14 +244,15 @@ void tty_termios_copy_hw(struct ktermios *new, const struct ktermios *old) EXPORT_SYMBOL(tty_termios_copy_hw); /** - * tty_termios_hw_change - check for setting change - * @a: termios - * @b: termios to compare + * tty_termios_hw_change - check for setting change + * @a: termios + * @b: termios to compare * - * Check if any of the bits that affect a dumb device have changed - * between the two termios structures, or a speed change is needed. + * Check if any of the bits that affect a dumb device have changed between the + * two termios structures, or a speed change is needed. + * + * Returns: %true if change is needed */ - bool tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b) { if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) @@ -272,11 +264,10 @@ bool tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b) EXPORT_SYMBOL(tty_termios_hw_change); /** - * tty_get_char_size - get size of a character - * @cflag: termios cflag value + * tty_get_char_size - get size of a character + * @cflag: termios cflag value * - * Get the size (in bits) of a character depending on @cflag's %CSIZE - * setting. + * Returns: size (in bits) of a character depending on @cflag's %CSIZE setting */ unsigned char tty_get_char_size(unsigned int cflag) { @@ -295,13 +286,14 @@ unsigned char tty_get_char_size(unsigned int cflag) EXPORT_SYMBOL_GPL(tty_get_char_size); /** - * tty_get_frame_size - get size of a frame - * @cflag: termios cflag value + * tty_get_frame_size - get size of a frame + * @cflag: termios cflag value * - * Get the size (in bits) of a frame depending on @cflag's %CSIZE, %CSTOPB, - * and %PARENB setting. The result is a sum of character size, start and - * stop bits -- one bit each -- second stop bit (if set), and parity bit - * (if set). + * Get the size (in bits) of a frame depending on @cflag's %CSIZE, %CSTOPB, and + * %PARENB setting. The result is a sum of character size, start and stop bits + * -- one bit each -- second stop bit (if set), and parity bit (if set). + * + * Returns: size (in bits) of a frame depending on @cflag's setting. */ unsigned char tty_get_frame_size(unsigned int cflag) { @@ -319,16 +311,15 @@ unsigned char tty_get_frame_size(unsigned int cflag) EXPORT_SYMBOL_GPL(tty_get_frame_size); /** - * tty_set_termios - update termios values - * @tty: tty to update - * @new_termios: desired new value + * tty_set_termios - update termios values + * @tty: tty to update + * @new_termios: desired new value * - * Perform updates to the termios values set on this terminal. - * A master pty's termios should never be set. + * Perform updates to the termios values set on this @tty. A master pty's + * termios should never be set. * - * Locking: termios_rwsem + * Locking: &tty_struct->termios_rwsem */ - int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) { struct ktermios old_termios; @@ -441,18 +432,19 @@ __weak int kernel_termios_to_user_termios(struct termios __user *u, #endif /* TCGETS2 */ /** - * set_termios - set termios values for a tty - * @tty: terminal device - * @arg: user data - * @opt: option information + * set_termios - set termios values for a tty + * @tty: terminal device + * @arg: user data + * @opt: option information + * + * Helper function to prepare termios data and run necessary other functions + * before using tty_set_termios() to do the actual changes. * - * Helper function to prepare termios data and run necessary other - * functions before using tty_set_termios to do the actual changes. + * Locking: called functions take &tty_struct->ldisc_sem and + * &tty_struct->termios_rwsem locks * - * Locking: - * Called functions take ldisc and termios_rwsem locks + * Returns: 0 on success, an error otherwise */ - static int set_termios(struct tty_struct *tty, void __user *arg, int opt) { struct ktermios tmp_termios; @@ -624,16 +616,16 @@ static void set_sgflags(struct ktermios *termios, int flags) } /** - * set_sgttyb - set legacy terminal values - * @tty: tty structure - * @sgttyb: pointer to old style terminal structure + * set_sgttyb - set legacy terminal values + * @tty: tty structure + * @sgttyb: pointer to old style terminal structure + * + * Updates a terminal from the legacy BSD style terminal information structure. * - * Updates a terminal from the legacy BSD style terminal information - * structure. + * Locking: &tty_struct->termios_rwsem * - * Locking: termios_rwsem + * Returns: 0 on success, an error otherwise */ - static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) { int retval; @@ -735,14 +727,17 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) #endif /** - * tty_change_softcar - carrier change ioctl helper - * @tty: tty to update - * @enable: enable/disable CLOCAL + * tty_change_softcar - carrier change ioctl helper + * @tty: tty to update + * @enable: enable/disable %CLOCAL + * + * Perform a change to the %CLOCAL state and call into the driver layer to make + * it visible. + * + * Locking: &tty_struct->termios_rwsem. * - * Perform a change to the CLOCAL state and call into the driver - * layer to make it visible. All done with the termios rwsem + * Returns: 0 on success, an error otherwise */ - static int tty_change_softcar(struct tty_struct *tty, bool enable) { int ret = 0; @@ -762,16 +757,15 @@ static int tty_change_softcar(struct tty_struct *tty, bool enable) } /** - * tty_mode_ioctl - mode related ioctls - * @tty: tty for the ioctl - * @cmd: command - * @arg: ioctl argument + * tty_mode_ioctl - mode related ioctls + * @tty: tty for the ioctl + * @cmd: command + * @arg: ioctl argument * - * Perform non line discipline specific mode control ioctls. This - * is designed to be called by line disciplines to ensure they provide - * consistent mode setting. + * Perform non-line discipline specific mode control ioctls. This is designed + * to be called by line disciplines to ensure they provide consistent mode + * setting. */ - int tty_mode_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct tty_struct *real_tty; diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c index 0d04287da098..ef8741c3e662 100644 --- a/drivers/tty/tty_jobctrl.c +++ b/drivers/tty/tty_jobctrl.c @@ -300,12 +300,7 @@ void disassociate_ctty(int on_exit) return; } - spin_lock_irq(¤t->sighand->siglock); - put_pid(current->signal->tty_old_pgrp); - current->signal->tty_old_pgrp = NULL; - tty = tty_kref_get(current->signal->tty); - spin_unlock_irq(¤t->sighand->siglock); - + tty = get_current_tty(); if (tty) { unsigned long flags; @@ -320,6 +315,16 @@ void disassociate_ctty(int on_exit) tty_kref_put(tty); } + /* If tty->ctrl.pgrp is not NULL, it may be assigned to + * current->signal->tty_old_pgrp in a race condition, and + * cause pid memleak. Release current->signal->tty_old_pgrp + * after tty->ctrl.pgrp set to NULL. + */ + spin_lock_irq(¤t->sighand->siglock); + put_pid(current->signal->tty_old_pgrp); + current->signal->tty_old_pgrp = NULL; + spin_unlock_irq(¤t->sighand->siglock); + /* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); session_clear_tty(task_session(current)); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 624d104bd145..63c125250961 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -79,7 +79,7 @@ const struct tty_port_client_operations tty_port_default_client_ops = { EXPORT_SYMBOL_GPL(tty_port_default_client_ops); /** - * tty_port_init -- initialize tty_port + * tty_port_init - initialize tty_port * @port: tty_port to initialize * * Initializes the state of struct tty_port. When a port was initialized using @@ -267,7 +267,7 @@ void tty_port_free_xmit_buf(struct tty_port *port) EXPORT_SYMBOL(tty_port_free_xmit_buf); /** - * tty_port_destroy -- destroy inited port + * tty_port_destroy - destroy inited port * @port: tty port to be destroyed * * When a port was initialized using tty_port_init(), one has to destroy the @@ -297,7 +297,7 @@ static void tty_port_destructor(struct kref *kref) } /** - * tty_port_put -- drop a reference to tty_port + * tty_port_put - drop a reference to tty_port * @port: port to drop a reference of (can be NULL) * * The final put will destroy and free up the @port using diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index a39ed981bfd3..5b625f20233b 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -579,18 +579,22 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) return -ENOMEM; name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL); + if (!name) { + rv = -ENOMEM; + goto free_port; + } rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions, ARRAY_SIZE(vcc_versions), NULL, name); if (rv) - goto free_port; + goto free_name; port->vio.debug = vcc_dbg_vio; vcc_ldc_cfg.debug = vcc_dbg_ldc; rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port); if (rv) - goto free_port; + goto free_name; spin_lock_init(&port->lock); @@ -624,6 +628,11 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) goto unreg_tty; } port->domain = kstrdup(domain, GFP_KERNEL); + if (!port->domain) { + rv = -ENOMEM; + goto unreg_tty; + } + mdesc_release(hp); @@ -653,8 +662,9 @@ free_table: vcc_table_remove(port->index); free_ldc: vio_ldc_free(&port->vio); -free_port: +free_name: kfree(name); +free_port: kfree(port); return rv; diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index f02d21e2a96e..5e39a4f430ee 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -205,7 +205,7 @@ static enum translation_map inv_translate[MAX_NR_CONSOLES]; FIELD_PREP(UNI_GLYPH_BITS, (glyph))) /** - * struct uni_pagedict -- unicode directory + * struct uni_pagedict - unicode directory * * @uni_pgdir: 32*32*64 table with glyphs * @refcount: reference count of this structure diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 1fe6107b539b..12a192e1196b 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -2079,12 +2079,15 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) return -ENOMEM; spin_lock_irqsave(&func_buf_lock, flags); - len = strlcpy(kbs, func_table[kb_func] ? : "", len); + len = strscpy(kbs, func_table[kb_func] ? : "", len); spin_unlock_irqrestore(&func_buf_lock, flags); + if (len < 0) { + ret = -ENOSPC; + break; + } ret = copy_to_user(user_kdgkb->kb_string, kbs, len + 1) ? -EFAULT : 0; - break; } case KDSKBSENT: diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 829c4be66f3b..67e2cb7c96ee 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -174,7 +174,7 @@ vcs_poll_data_get(struct file *file) } /** - * vcs_vc -- return VC for @inode + * vcs_vc - return VC for @inode * @inode: inode for which to return a VC * @viewed: returns whether this console is currently foreground (viewed) * @@ -199,7 +199,7 @@ static struct vc_data *vcs_vc(struct inode *inode, bool *viewed) } /** - * vcs_size -- return size for a VC in @vc + * vcs_size - return size for a VC in @vc * @vc: which VC * @attr: does it use attributes? * @unicode: is it unicode? @@ -786,23 +786,22 @@ static const struct file_operations vcs_fops = { .release = vcs_release, }; -static struct class *vc_class; +static const struct class vc_class = { + .name = "vc", +}; void vcs_make_sysfs(int index) { - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL, - "vcs%u", index + 1); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 65), NULL, - "vcsu%u", index + 1); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL, - "vcsa%u", index + 1); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL, "vcs%u", index + 1); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 65), NULL, "vcsu%u", index + 1); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL, "vcsa%u", index + 1); } void vcs_remove_sysfs(int index) { - device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1)); - device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 65)); - device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129)); + device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 1)); + device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 65)); + device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 129)); } int __init vcs_init(void) @@ -811,11 +810,12 @@ int __init vcs_init(void) if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) panic("unable to get major %d for vcs device", VCS_MAJOR); - vc_class = class_create("vc"); + if (class_register(&vc_class)) + panic("unable to create vc_class"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 64), NULL, "vcsu"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 64), NULL, "vcsu"); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); for (i = 0; i < MIN_NR_CONSOLES; i++) vcs_make_sysfs(i); return 0; diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 5c47f77804f0..156efda7c80d 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2588,7 +2588,7 @@ static inline int vc_translate_ascii(const struct vc_data *vc, int c) /** - * vc_sanitize_unicode -- Replace invalid Unicode code points with U+FFFD + * vc_sanitize_unicode - Replace invalid Unicode code points with U+FFFD * @c: the received character, or U+FFFD for invalid sequences. */ static inline int vc_sanitize_unicode(const int c) @@ -2600,7 +2600,7 @@ static inline int vc_sanitize_unicode(const int c) } /** - * vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char + * vc_translate_unicode - Combine UTF-8 into Unicode in @vc_utf_char * @vc: virtual console * @c: character to translate * @rescan: we return true if we need more (continuation) data @@ -3155,9 +3155,13 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) switch (type) { case TIOCL_SETSEL: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; return set_selection_user((struct tiocl_selection __user *)(p+1), tty); case TIOCL_PASTESEL: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; return paste_selection(tty); case TIOCL_UNBLANKSCREEN: console_lock(); @@ -3165,6 +3169,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) console_unlock(); break; case TIOCL_SELLOADLUT: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; console_lock(); ret = sel_loadlut(p); console_unlock(); @@ -3565,7 +3571,9 @@ int __init vty_init(const struct file_operations *console_fops) return 0; } -static struct class *vtconsole_class; +static const struct class vtconsole_class = { + .name = "vtconsole", +}; static int do_bind_con_driver(const struct consw *csw, int first, int last, int deflt) @@ -4092,7 +4100,7 @@ static int do_register_con_driver(const struct consw *csw, int first, int last) goto err; con_driver->dev = - device_create_with_groups(vtconsole_class, NULL, + device_create_with_groups(&vtconsole_class, NULL, MKDEV(0, con_driver->node), con_driver, con_dev_groups, "vtcon%i", con_driver->node); @@ -4173,7 +4181,7 @@ static void con_driver_unregister_callback(struct work_struct *ignored) console_unlock(); vtconsole_deinit_device(con_driver); - device_destroy(vtconsole_class, MKDEV(0, con_driver->node)); + device_destroy(&vtconsole_class, MKDEV(0, con_driver->node)); console_lock(); @@ -4234,12 +4242,9 @@ static int __init vtconsole_class_init(void) { int i; - vtconsole_class = class_create("vtconsole"); - if (IS_ERR(vtconsole_class)) { - pr_warn("Unable to create vt console class; errno = %ld\n", - PTR_ERR(vtconsole_class)); - vtconsole_class = NULL; - } + i = class_register(&vtconsole_class); + if (i) + pr_warn("Unable to create vt console class; errno = %d\n", i); /* Add system drivers to sysfs */ for (i = 0; i < MAX_NR_CON_DRIVER; i++) { @@ -4247,7 +4252,7 @@ static int __init vtconsole_class_init(void) if (con->con && !con->dev) { con->dev = - device_create_with_groups(vtconsole_class, NULL, + device_create_with_groups(&vtconsole_class, NULL, MKDEV(0, con->node), con, con_dev_groups, "vtcon%i", con->node); diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 30577b1d3de5..83c2d7329ca5 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -7,9 +7,9 @@ menu "Console display driver support" config VGA_CONSOLE bool "VGA text console" if EXPERT || !X86 - depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC && !SUPERH && \ - (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \ - !ARM64 && !ARC && !MICROBLAZE && !OPENRISC && !S390 && !UML + depends on ALPHA || IA64 || X86 || \ + (ARM && ARCH_FOOTBRIDGE) || \ + (MIPS && (MIPS_MALTA || SIBYTE_BCM112X || SIBYTE_SB1250 || SIBYTE_BCM1x80 || SNI_RM)) select APERTURE_HELPERS if (DRM || FB || VFIO_PCI_CORE) default y help @@ -52,7 +52,7 @@ config DUMMY_CONSOLE config DUMMY_CONSOLE_COLUMNS int "Initial number of console screen columns" - depends on DUMMY_CONSOLE && !ARM + depends on DUMMY_CONSOLE && !ARCH_FOOTBRIDGE default 160 if PARISC default 80 help @@ -62,8 +62,9 @@ config DUMMY_CONSOLE_COLUMNS config DUMMY_CONSOLE_ROWS int "Initial number of console screen rows" - depends on DUMMY_CONSOLE && !ARM + depends on DUMMY_CONSOLE && !ARCH_FOOTBRIDGE default 64 if PARISC + default 30 if ARM default 25 help On PA-RISC, the default value is 64, which should fit a 1280x1024 diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index f1711b2f9ff0..14af5d9e13b0 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -18,9 +18,10 @@ * Dummy console driver */ -#if defined(__arm__) -#define DUMMY_COLUMNS screen_info.orig_video_cols -#define DUMMY_ROWS screen_info.orig_video_lines +#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_VGA_CONSOLE) +#include <asm/vga.h> +#define DUMMY_COLUMNS vgacon_screen_info.orig_video_cols +#define DUMMY_ROWS vgacon_screen_info.orig_video_lines #else /* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */ #define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 7ad047bcae17..8ef1579fa57f 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -89,6 +89,8 @@ static int vga_video_font_height; static int vga_scan_lines __read_mostly; static unsigned int vga_rolled_over; /* last vc_origin offset before wrap */ +static struct screen_info *vga_si; + static bool vga_hardscroll_enabled; static bool vga_hardscroll_user_enable = true; @@ -153,8 +155,9 @@ static const char *vgacon_startup(void) u16 saved1, saved2; volatile u16 *p; - if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB || - screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) { + if (!vga_si || + vga_si->orig_video_isVGA == VIDEO_TYPE_VLFB || + vga_si->orig_video_isVGA == VIDEO_TYPE_EFI) { no_vga: #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -164,29 +167,29 @@ static const char *vgacon_startup(void) #endif } - /* boot_params.screen_info reasonably initialized? */ - if ((screen_info.orig_video_lines == 0) || - (screen_info.orig_video_cols == 0)) + /* vga_si reasonably initialized? */ + if ((vga_si->orig_video_lines == 0) || + (vga_si->orig_video_cols == 0)) goto no_vga; /* VGA16 modes are not handled by VGACON */ - if ((screen_info.orig_video_mode == 0x0D) || /* 320x200/4 */ - (screen_info.orig_video_mode == 0x0E) || /* 640x200/4 */ - (screen_info.orig_video_mode == 0x10) || /* 640x350/4 */ - (screen_info.orig_video_mode == 0x12) || /* 640x480/4 */ - (screen_info.orig_video_mode == 0x6A)) /* 800x600/4 (VESA) */ + if ((vga_si->orig_video_mode == 0x0D) || /* 320x200/4 */ + (vga_si->orig_video_mode == 0x0E) || /* 640x200/4 */ + (vga_si->orig_video_mode == 0x10) || /* 640x350/4 */ + (vga_si->orig_video_mode == 0x12) || /* 640x480/4 */ + (vga_si->orig_video_mode == 0x6A)) /* 800x600/4 (VESA) */ goto no_vga; - vga_video_num_lines = screen_info.orig_video_lines; - vga_video_num_columns = screen_info.orig_video_cols; + vga_video_num_lines = vga_si->orig_video_lines; + vga_video_num_columns = vga_si->orig_video_cols; vgastate.vgabase = NULL; - if (screen_info.orig_video_mode == 7) { + if (vga_si->orig_video_mode == 7) { /* Monochrome display */ vga_vram_base = 0xb0000; vga_video_port_reg = VGA_CRT_IM; vga_video_port_val = VGA_CRT_DM; - if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) { + if ((vga_si->orig_video_ega_bx & 0xff) != 0x10) { static struct resource ega_console_resource = { .name = "ega", .flags = IORESOURCE_IO, @@ -223,12 +226,12 @@ static const char *vgacon_startup(void) vga_vram_base = 0xb8000; vga_video_port_reg = VGA_CRT_IC; vga_video_port_val = VGA_CRT_DC; - if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) { + if ((vga_si->orig_video_ega_bx & 0xff) != 0x10) { int i; vga_vram_size = 0x8000; - if (!screen_info.orig_video_isVGA) { + if (!vga_si->orig_video_isVGA) { static struct resource ega_console_resource = { .name = "ega", .flags = IORESOURCE_IO, @@ -319,14 +322,14 @@ static const char *vgacon_startup(void) || vga_video_type == VIDEO_TYPE_VGAC || vga_video_type == VIDEO_TYPE_EGAM) { vga_hardscroll_enabled = vga_hardscroll_user_enable; - vga_default_font_height = screen_info.orig_video_points; - vga_video_font_height = screen_info.orig_video_points; + vga_default_font_height = vga_si->orig_video_points; + vga_video_font_height = vga_si->orig_video_points; /* This may be suboptimal but is a safe bet - go with it */ vga_scan_lines = vga_video_font_height * vga_video_num_lines; } - vgacon_xres = screen_info.orig_video_cols * VGA_FONTWIDTH; + vgacon_xres = vga_si->orig_video_cols * VGA_FONTWIDTH; vgacon_yres = vga_scan_lines; return display_desc; @@ -371,7 +374,7 @@ static void vgacon_init(struct vc_data *c, int init) /* Only set the default if the user didn't deliberately override it */ if (global_cursor_default == -1) global_cursor_default = - !(screen_info.flags & VIDEO_FLAGS_NOCURSOR); + !(vga_si->flags & VIDEO_FLAGS_NOCURSOR); } static void vgacon_deinit(struct vc_data *c) @@ -589,7 +592,7 @@ static int vgacon_switch(struct vc_data *c) { int x = c->vc_cols * VGA_FONTWIDTH; int y = c->vc_rows * c->vc_cell_height; - int rows = screen_info.orig_video_lines * vga_default_font_height/ + int rows = vga_si->orig_video_lines * vga_default_font_height/ c->vc_cell_height; /* * We need to save screen size here as it's the only way @@ -609,7 +612,7 @@ static int vgacon_switch(struct vc_data *c) if ((vgacon_xres != x || vgacon_yres != y) && (!(vga_video_num_columns % 2) && - vga_video_num_columns <= screen_info.orig_video_cols && + vga_video_num_columns <= vga_si->orig_video_cols && vga_video_num_lines <= rows)) vgacon_doresize(c, c->vc_cols, c->vc_rows); } @@ -1056,13 +1059,13 @@ static int vgacon_resize(struct vc_data *c, unsigned int width, * Ho ho! Someone (svgatextmode, eh?) may have reprogrammed * the video mode! Set the new defaults then and go away. */ - screen_info.orig_video_cols = width; - screen_info.orig_video_lines = height; + vga_si->orig_video_cols = width; + vga_si->orig_video_lines = height; vga_default_font_height = c->vc_cell_height; return 0; } - if (width % 2 || width > screen_info.orig_video_cols || - height > (screen_info.orig_video_lines * vga_default_font_height)/ + if (width % 2 || width > vga_si->orig_video_cols || + height > (vga_si->orig_video_lines * vga_default_font_height)/ c->vc_cell_height) return -EINVAL; @@ -1092,8 +1095,8 @@ static void vgacon_save_screen(struct vc_data *c) * console initialization routines. */ vga_bootup_console = 1; - c->state.x = screen_info.orig_x; - c->state.y = screen_info.orig_y; + c->state.x = vga_si->orig_x; + c->state.y = vga_si->orig_y; } /* We can't copy in more than the size of the video buffer, @@ -1186,4 +1189,13 @@ const struct consw vga_con = { }; EXPORT_SYMBOL(vga_con); +void vgacon_register_screen(struct screen_info *si) +{ + if (!si || vga_si) + return; + + conswitchp = &vga_con; + vga_si = si; +} + MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 96fdc7301481..53693c826ebd 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -364,7 +364,7 @@ config FB_IMSTT config FB_VGA16 tristate "VGA 16-color graphics support" - depends on FB && (X86 || PPC) + depends on FB && X86 select APERTURE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index 2e27c6bd8044..bf59daf862fc 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -1010,7 +1010,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) goto getmem_done; } pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n"); - } else { + } else if (IS_ENABLED(CONFIG_SYSFB)) { base = screen_info.lfb_base; size = screen_info.lfb_size; } @@ -1056,13 +1056,13 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) getmem_done: aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME); - if (gen2vm) { + if (!gen2vm) { + pci_dev_put(pdev); + } else if (IS_ENABLED(CONFIG_SYSFB)) { /* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */ screen_info.lfb_size = 0; screen_info.lfb_base = 0; screen_info.orig_video_isVGA = 0; - } else { - pci_dev_put(pdev); } return 0; diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index ac21942d5311..b485e9198201 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -185,8 +185,6 @@ static inline void setindex(int index) /* Check if the video mode is supported by the driver */ static inline int check_mode_supported(const struct screen_info *si) { - /* non-x86 architectures treat orig_video_isVGA as a boolean flag */ -#if defined(CONFIG_X86) /* only EGA and VGA in 16 color graphic mode are supported */ if (si->orig_video_isVGA != VIDEO_TYPE_EGAC && si->orig_video_isVGA != VIDEO_TYPE_VGAC) @@ -197,7 +195,7 @@ static inline int check_mode_supported(const struct screen_info *si) si->orig_video_mode != 0x10 && /* 640x350/4 (EGA) */ si->orig_video_mode != 0x12) /* 640x480/4 (VGA) */ return -ENODEV; -#endif + return 0; } @@ -1340,12 +1338,7 @@ static int vga16fb_probe(struct platform_device *dev) printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base); par = info->par; -#if defined(CONFIG_X86) par->isVGA = si->orig_video_isVGA == VIDEO_TYPE_VGAC; -#else - /* non-x86 architectures treat orig_video_isVGA as a boolean flag */ - par->isVGA = si->orig_video_isVGA; -#endif par->palette_blanked = 0; par->vesa_blanked = 0; diff --git a/include/linux/console.h b/include/linux/console.h index e4fc6f7c1496..779d388af8a0 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -101,6 +101,13 @@ extern const struct consw dummy_con; /* dummy console buffer */ extern const struct consw vga_con; /* VGA text console */ extern const struct consw newport_con; /* SGI Newport console */ +struct screen_info; +#ifdef CONFIG_VGA_CONSOLE +void vgacon_register_screen(struct screen_info *si); +#else +static inline void vgacon_register_screen(struct screen_info *si) { } +#endif + int con_is_bound(const struct consw *csw); int do_unregister_con_driver(const struct consw *csw); int do_take_over_console(const struct consw *sw, int first, int last, int deflt); @@ -469,7 +476,7 @@ enum con_flush_mode { CONSOLE_REPLAY_ALL, }; -extern int add_preferred_console(char *name, int idx, char *options); +extern int add_preferred_console(const char *name, const short idx, char *options); extern void console_force_preferred_locked(struct console *con); extern void register_console(struct console *); extern int unregister_console(struct console *); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index bb6f073bc159..89f7b6c63598 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -588,6 +588,85 @@ struct uart_port { void *private_data; /* generic platform data pointer */ }; +/** + * uart_port_lock - Lock the UART port + * @up: Pointer to UART port structure + */ +static inline void uart_port_lock(struct uart_port *up) +{ + spin_lock(&up->lock); +} + +/** + * uart_port_lock_irq - Lock the UART port and disable interrupts + * @up: Pointer to UART port structure + */ +static inline void uart_port_lock_irq(struct uart_port *up) +{ + spin_lock_irq(&up->lock); +} + +/** + * uart_port_lock_irqsave - Lock the UART port, save and disable interrupts + * @up: Pointer to UART port structure + * @flags: Pointer to interrupt flags storage + */ +static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) +{ + spin_lock_irqsave(&up->lock, *flags); +} + +/** + * uart_port_trylock - Try to lock the UART port + * @up: Pointer to UART port structure + * + * Returns: True if lock was acquired, false otherwise + */ +static inline bool uart_port_trylock(struct uart_port *up) +{ + return spin_trylock(&up->lock); +} + +/** + * uart_port_trylock_irqsave - Try to lock the UART port, save and disable interrupts + * @up: Pointer to UART port structure + * @flags: Pointer to interrupt flags storage + * + * Returns: True if lock was acquired, false otherwise + */ +static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags) +{ + return spin_trylock_irqsave(&up->lock, *flags); +} + +/** + * uart_port_unlock - Unlock the UART port + * @up: Pointer to UART port structure + */ +static inline void uart_port_unlock(struct uart_port *up) +{ + spin_unlock(&up->lock); +} + +/** + * uart_port_unlock_irq - Unlock the UART port and re-enable interrupts + * @up: Pointer to UART port structure + */ +static inline void uart_port_unlock_irq(struct uart_port *up) +{ + spin_unlock_irq(&up->lock); +} + +/** + * uart_port_unlock_irqrestore - Unlock the UART port, restore interrupts + * @up: Pointer to UART port structure + * @flags: The saved interrupt flags for restore + */ +static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) +{ + spin_unlock_irqrestore(&up->lock, flags); +} + static inline int serial_port_in(struct uart_port *up, int offset) { return up->serial_in(up, offset); @@ -956,14 +1035,14 @@ static inline void uart_unlock_and_check_sysrq(struct uart_port *port) u8 sysrq_ch; if (!port->has_sysrq) { - spin_unlock(&port->lock); + uart_port_unlock(port); return; } sysrq_ch = port->sysrq_ch; port->sysrq_ch = 0; - spin_unlock(&port->lock); + uart_port_unlock(port); if (sysrq_ch) handle_sysrq(sysrq_ch); @@ -975,14 +1054,14 @@ static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port u8 sysrq_ch; if (!port->has_sysrq) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } sysrq_ch = port->sysrq_ch; port->sysrq_ch = 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (sysrq_ch) handle_sysrq(sysrq_ch); @@ -998,12 +1077,12 @@ static inline int uart_prepare_sysrq_char(struct uart_port *port, u8 ch) } static inline void uart_unlock_and_check_sysrq(struct uart_port *port) { - spin_unlock(&port->lock); + uart_port_unlock(port); } static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port, unsigned long flags) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #endif /* CONFIG_MAGIC_SYSRQ_SERIAL */ diff --git a/include/linux/tty.h b/include/linux/tty.h index f002d0f25db7..4b6340ac2af2 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -390,14 +390,12 @@ int vcs_init(void); extern const struct class tty_class; /** - * tty_kref_get - get a tty reference - * @tty: tty device + * tty_kref_get - get a tty reference + * @tty: tty device * - * Return a new reference to a tty object. The caller must hold - * sufficient locks/counts to ensure that their existing reference cannot - * go away + * Returns: a new reference to a tty object. The caller must hold sufficient + * locks/counts to ensure that their existing reference cannot go away */ - static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) { if (tty) @@ -416,8 +414,8 @@ unsigned int tty_chars_in_buffer(struct tty_struct *tty); unsigned int tty_write_room(struct tty_struct *tty); void tty_driver_flush_buffer(struct tty_struct *tty); void tty_unthrottle(struct tty_struct *tty); -int tty_throttle_safe(struct tty_struct *tty); -int tty_unthrottle_safe(struct tty_struct *tty); +bool tty_throttle_safe(struct tty_struct *tty); +bool tty_unthrottle_safe(struct tty_struct *tty); int tty_do_resize(struct tty_struct *tty, struct winsize *ws); int tty_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); @@ -435,14 +433,13 @@ void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud); /** - * tty_get_baud_rate - get tty bit rates - * @tty: tty to query + * tty_get_baud_rate - get tty bit rates + * @tty: tty to query * - * Returns the baud rate as an integer for this terminal. The - * termios lock must be held by the caller and the terminal bit - * flags may be updated. + * Returns: the baud rate as an integer for this terminal. The termios lock + * must be held by the caller and the terminal bit flags may be updated. * - * Locking: none + * Locking: none */ static inline speed_t tty_get_baud_rate(struct tty_struct *tty) { diff --git a/include/uapi/linux/gsmmux.h b/include/uapi/linux/gsmmux.h index 4c878d84dbda..3a93f17ca943 100644 --- a/include/uapi/linux/gsmmux.h +++ b/include/uapi/linux/gsmmux.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (c) 2022/23 Siemens Mobility GmbH */ #ifndef _LINUX_GSMMUX_H #define _LINUX_GSMMUX_H diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index add349889d0a..9c007a106330 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -1,22 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* - * linux/drivers/char/serial_core.h - * * Copyright (C) 2000 Deep Blue Solutions Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _UAPILINUX_SERIAL_CORE_H #define _UAPILINUX_SERIAL_CORE_H @@ -27,6 +11,8 @@ * The type definitions. These are from Ted Ts'o's serial.h * By historical reasons the values from 0 to 13 are defined * in the include/uapi/linux/serial.h, do not define them here. + * Values 0 to 19 are used by setserial from busybox and must never + * be modified. */ #define PORT_NS16550A 14 #define PORT_XSCALE 15 @@ -245,4 +231,7 @@ /* Sunplus UART */ #define PORT_SUNPLUS 123 +/* Generic type identifier for ports which type is not important to userspace. */ +#define PORT_GENERIC (-1) + #endif /* _UAPILINUX_SERIAL_CORE_H */ diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index 08b3527e1b93..9c987b04e2d0 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -49,6 +49,7 @@ #define UART_IIR_FIFO_ENABLED_8250 0x00 /* 8250: no FIFO */ #define UART_IIR_FIFO_ENABLED_16550 0x80 /* 16550: (broken/unusable) FIFO */ #define UART_IIR_FIFO_ENABLED_16550A 0xc0 /* 16550A: FIFO enabled */ +#define UART_IIR_FIFO_ENABLED_16750 0xe0 /* 16750: 64 bytes FIFO enabled */ #define UART_FCR 2 /* Out: FIFO Control Register */ #define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index be95a6851164..f2444b581e16 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2384,13 +2384,21 @@ static void set_user_specified(struct console_cmdline *c, bool user_specified) console_set_on_cmdline = 1; } -static int __add_preferred_console(char *name, int idx, char *options, +static int __add_preferred_console(const char *name, const short idx, char *options, char *brl_options, bool user_specified) { struct console_cmdline *c; int i; /* + * We use a signed short index for struct console for device drivers to + * indicate a not yet assigned index or port. However, a negative index + * value is not valid for preferred console. + */ + if (idx < 0) + return -EINVAL; + + /* * See if this tty is not yet registered, and * if we have a slot free. */ @@ -2493,7 +2501,7 @@ __setup("console=", console_setup); * commonly to provide a default console (ie from PROM variables) when * the user has not supplied one. */ -int add_preferred_console(char *name, int idx, char *options) +int add_preferred_console(const char *name, const short idx, char *options) { return __add_preferred_console(name, idx, options, NULL, false); } |