mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
TTY/Serial driver updates for 5.13-rc1
Here is the big set of tty and serial driver updates for 5.13-rc1. Actually busy this release, with a number of cleanups happening: - much needed core tty cleanups by Jiri Slaby - removal of unused and orphaned old-style serial drivers. If anyone shows up with this hardware, it is trivial to restore these but we really do not think they are in use anymore. - fixes and cleanups from Johan Hovold on a number of termios setting corner cases that loads of drivers got wrong as well as removing unneeded code due to tty core changes from long ago that were never propagated out to the drivers - loads of platform-specific serial port driver updates and fixes - coding style cleanups and other small fixes and updates all over the tty/serial tree. All of these have been in linux-next for a while now with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYIa3NQ8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykMXgCfX3FZgKveI4l94ChXSy4OyKwycHUAn00BzrMC /7BwA1FnjQnC4zSzuHnm =bAas -----END PGP SIGNATURE----- Merge tag 'tty-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty Pull tty and serial driver updates from Greg KH: "Here is the big set of tty and serial driver updates for 5.13-rc1. Actually busy this release, with a number of cleanups happening: - much needed core tty cleanups by Jiri Slaby - removal of unused and orphaned old-style serial drivers. If anyone shows up with this hardware, it is trivial to restore these but we really do not think they are in use anymore. - fixes and cleanups from Johan Hovold on a number of termios setting corner cases that loads of drivers got wrong as well as removing unneeded code due to tty core changes from long ago that were never propagated out to the drivers - loads of platform-specific serial port driver updates and fixes - coding style cleanups and other small fixes and updates all over the tty/serial tree. All of these have been in linux-next for a while now with no reported issues" * tag 'tty-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (186 commits) serial: extend compile-test coverage serial: stm32: add FIFO threshold configuration dt-bindings: serial: 8250: update TX FIFO trigger level dt-bindings: serial: stm32: override FIFO threshold properties dt-bindings: serial: add RX and TX FIFO properties serial: xilinx_uartps: drop low-latency workaround serial: vt8500: drop low-latency workaround serial: timbuart: drop low-latency workaround serial: sunsu: drop low-latency workaround serial: sifive: drop low-latency workaround serial: txx9: drop low-latency workaround serial: sa1100: drop low-latency workaround serial: rp2: drop low-latency workaround serial: rda: drop low-latency workaround serial: owl: drop low-latency workaround serial: msm_serial: drop low-latency workaround serial: mpc52xx_uart: drop low-latency workaround serial: meson: drop low-latency workaround serial: mcf: drop low-latency workaround serial: lpc32xx_hs: drop low-latency workaround ...
This commit is contained in:
commit
d08410d8c9
@ -289,7 +289,7 @@
|
||||
152 = /dev/kpoll Kernel Poll Driver
|
||||
153 = /dev/mergemem Memory merge device
|
||||
154 = /dev/pmu Macintosh PowerBook power manager
|
||||
155 = /dev/isictl MultiTech ISICom serial control
|
||||
155 =
|
||||
156 = /dev/lcd Front panel LCD display
|
||||
157 = /dev/ac Applicom Intl Profibus card
|
||||
158 = /dev/nwbutton Netwinder external button
|
||||
@ -477,11 +477,6 @@
|
||||
18 block Sanyo CD-ROM
|
||||
0 = /dev/sjcd Sanyo CD-ROM
|
||||
|
||||
19 char Cyclades serial card
|
||||
0 = /dev/ttyC0 First Cyclades port
|
||||
...
|
||||
31 = /dev/ttyC31 32nd Cyclades port
|
||||
|
||||
19 block "Double" compressed disk
|
||||
0 = /dev/double0 First compressed disk
|
||||
...
|
||||
@ -493,11 +488,6 @@
|
||||
See the Double documentation for the meaning of the
|
||||
mirror devices.
|
||||
|
||||
20 char Cyclades serial card - alternate devices
|
||||
0 = /dev/cub0 Callout device for ttyC0
|
||||
...
|
||||
31 = /dev/cub31 Callout device for ttyC31
|
||||
|
||||
20 block Hitachi CD-ROM (under development)
|
||||
0 = /dev/hitcd Hitachi CD-ROM
|
||||
|
||||
|
@ -12,8 +12,13 @@ maintainers:
|
||||
allOf:
|
||||
- $ref: /schemas/serial.yaml#
|
||||
- if:
|
||||
required:
|
||||
- aspeed,sirq-polarity-sense
|
||||
anyOf:
|
||||
- required:
|
||||
- aspeed,lpc-io-reg
|
||||
- required:
|
||||
- aspeed,lpc-interrupts
|
||||
- required:
|
||||
- aspeed,sirq-polarity-sense
|
||||
then:
|
||||
properties:
|
||||
compatible:
|
||||
@ -55,6 +60,7 @@ properties:
|
||||
- const: aspeed,ast2500-vuart
|
||||
- const: intel,xscale-uart
|
||||
- const: mrvl,pxa-uart
|
||||
- const: nuvoton,wpcm450-uart
|
||||
- const: nuvoton,npcm750-uart
|
||||
- const: nvidia,tegra20-uart
|
||||
- const: nxp,lpc3220-uart
|
||||
@ -165,7 +171,6 @@ properties:
|
||||
property.
|
||||
|
||||
tx-threshold:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Specify the TX FIFO low water indication for parts with programmable
|
||||
TX FIFO thresholds.
|
||||
@ -188,6 +193,21 @@ properties:
|
||||
offset and bit number to identify how the SIRQ polarity should be
|
||||
configured. One possible data source is the LPC/eSPI mode bit. Only
|
||||
applicable to aspeed,ast2500-vuart.
|
||||
deprecated: true
|
||||
|
||||
aspeed,lpc-io-reg:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: |
|
||||
The VUART LPC address. Only applicable to aspeed,ast2500-vuart.
|
||||
|
||||
aspeed,lpc-interrupts:
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32-array"
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
description: |
|
||||
A 2-cell property describing the VUART SIRQ number and SIRQ
|
||||
polarity (IRQ_TYPE_LEVEL_LOW or IRQ_TYPE_LEVEL_HIGH). Only
|
||||
applicable to aspeed,ast2500-vuart.
|
||||
|
||||
required:
|
||||
- reg
|
||||
@ -220,6 +240,7 @@ examples:
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/clock/aspeed-clock.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
serial@1e787000 {
|
||||
compatible = "aspeed,ast2500-vuart";
|
||||
reg = <0x1e787000 0x40>;
|
||||
@ -227,7 +248,8 @@ examples:
|
||||
interrupts = <8>;
|
||||
clocks = <&syscon ASPEED_CLK_APB>;
|
||||
no-loopback-test;
|
||||
aspeed,sirq-polarity-sense = <&syscon 0x70 25>;
|
||||
aspeed,lpc-io-reg = <0x3f8>;
|
||||
aspeed,lpc-interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
||||
...
|
||||
|
@ -0,0 +1,95 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/brcm,bcm7271-uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom 8250 based serial port devicetree bindings
|
||||
|
||||
maintainers:
|
||||
- Al Cooper <alcooperx@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial.yaml#
|
||||
|
||||
description: |+
|
||||
The Broadcom UART is based on the basic 8250 UART but with
|
||||
enhancements for more accurate high speed baud rates and support
|
||||
for DMA.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- brcm,bcm7271-uart
|
||||
- brcm,bcm7278-uart
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
reg-names:
|
||||
description: The UART register block and optionally the DMA register blocks.
|
||||
oneOf:
|
||||
- items:
|
||||
- const: uart
|
||||
- items:
|
||||
- const: uart
|
||||
- const: dma_arb
|
||||
- const: dma_rx
|
||||
- const: dma_tx
|
||||
- const: dma_intr2
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
|
||||
clock-names:
|
||||
const: sw_baud
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
description: The UART interrupt and optionally the DMA interrupt.
|
||||
minItems: 1
|
||||
items:
|
||||
- const: uart
|
||||
- const: dma
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial@840d000 {
|
||||
compatible = "brcm,bcm7271-uart";
|
||||
reg = <0x840d000 0x20>;
|
||||
reg-names = "uart";
|
||||
interrupts = <0x0 0x62 0x4>;
|
||||
interrupt-names = "uart";
|
||||
clocks = <&scmi_clk 190>;
|
||||
clock-names = "sw_baud";
|
||||
};
|
||||
|
||||
serial@840e000 {
|
||||
compatible = "brcm,bcm7271-uart";
|
||||
reg = <0x840e000 0x20>,
|
||||
<0x840e080 0x8>,
|
||||
<0x840e100 0xa8>,
|
||||
<0x840e200 0x4c>,
|
||||
<0x840e300 0x30>;
|
||||
reg-names = "uart", "dma_arb", "dma_rx", "dma_tx", "dma_intr2";
|
||||
interrupts = <0x0 0x62 0x4>, <0x0 0x75 0x4>;
|
||||
interrupt-names = "uart", "dma";
|
||||
clocks = <&scmi_clk 190>;
|
||||
clock-names = "sw_baud";
|
||||
};
|
@ -20,6 +20,7 @@ Required properties:
|
||||
* "mediatek,mt8173-uart" for MT8173 compatible UARTS
|
||||
* "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
|
||||
* "mediatek,mt8192-uart", "mediatek,mt6577-uart" for MT8192 compatible UARTS
|
||||
* "mediatek,mt8195-uart", "mediatek,mt6577-uart" for MT8195 compatible UARTS
|
||||
* "mediatek,mt8516-uart" for MT8516 compatible UARTS
|
||||
* "mediatek,mt6577-uart" for MT6577 and all of the above
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/serial/samsung_uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S3C, S5P and Exynos SoC UART Controller
|
||||
title: Samsung S3C, S5P, Exynos, and S5L (Apple SoC) SoC UART Controller
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
@ -19,6 +19,7 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,s5l-uart
|
||||
- samsung,s3c2410-uart
|
||||
- samsung,s3c2412-uart
|
||||
- samsung,s3c2440-uart
|
||||
@ -51,6 +52,16 @@ properties:
|
||||
- pattern: '^clk_uart_baud[0-3]$'
|
||||
- pattern: '^clk_uart_baud[0-3]$'
|
||||
|
||||
dmas:
|
||||
items:
|
||||
- description: DMA controller phandle and request line for RX
|
||||
- description: DMA controller phandle and request line for TX
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
|
||||
interrupts:
|
||||
description: RX interrupt and optionally TX interrupt.
|
||||
minItems: 1
|
||||
@ -68,9 +79,11 @@ required:
|
||||
- interrupts
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@ -96,6 +109,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- apple,s5l-uart
|
||||
- samsung,exynos4210-uart
|
||||
then:
|
||||
properties:
|
||||
|
@ -75,6 +75,16 @@ properties:
|
||||
type: boolean
|
||||
description: CTS and RTS pins are swapped.
|
||||
|
||||
rx-threshold:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
RX FIFO threshold configuration (in bytes).
|
||||
|
||||
tx-threshold:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
TX FIFO threshold configuration (in bytes).
|
||||
|
||||
if:
|
||||
required:
|
||||
- uart-has-rtscts
|
||||
|
@ -9,9 +9,6 @@ maintainers:
|
||||
|
||||
title: STMicroelectronics STM32 USART bindings
|
||||
|
||||
allOf:
|
||||
- $ref: rs485.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
@ -40,6 +37,8 @@ properties:
|
||||
|
||||
uart-has-rtscts: true
|
||||
|
||||
rx-tx-swap: true
|
||||
|
||||
dmas:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
@ -66,13 +65,46 @@ properties:
|
||||
linux,rs485-enabled-at-boot-time: true
|
||||
rs485-rx-during-tx: true
|
||||
|
||||
if:
|
||||
required:
|
||||
- st,hw-flow-ctrl
|
||||
then:
|
||||
properties:
|
||||
cts-gpios: false
|
||||
rts-gpios: false
|
||||
rx-threshold:
|
||||
description:
|
||||
If value is set to 1, RX FIFO threshold is disabled.
|
||||
enum: [1, 2, 4, 8, 12, 14, 16]
|
||||
default: 8
|
||||
|
||||
tx-threshold:
|
||||
description:
|
||||
If value is set to 1, TX FIFO threshold is disabled.
|
||||
enum: [1, 2, 4, 8, 12, 14, 16]
|
||||
default: 8
|
||||
|
||||
allOf:
|
||||
- $ref: rs485.yaml#
|
||||
- $ref: serial.yaml#
|
||||
- if:
|
||||
required:
|
||||
- st,hw-flow-ctrl
|
||||
then:
|
||||
properties:
|
||||
cts-gpios: false
|
||||
rts-gpios: false
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-uart
|
||||
then:
|
||||
properties:
|
||||
rx-tx-swap: false
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- st,stm32-uart
|
||||
- st,stm32f7-uart
|
||||
then:
|
||||
properties:
|
||||
rx-threshold: false
|
||||
tx-threshold: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -80,19 +112,22 @@ required:
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
additionalProperties:
|
||||
type: object
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
usart1: serial@40011000 {
|
||||
compatible = "st,stm32-uart";
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x40011000 0x400>;
|
||||
interrupts = <37>;
|
||||
clocks = <&rcc 0 164>;
|
||||
dmas = <&dma2 2 4 0x414 0x0>,
|
||||
<&dma2 7 4 0x414 0x0>;
|
||||
dma-names = "rx", "tx";
|
||||
rx-threshold = <4>;
|
||||
tx-threshold = <4>;
|
||||
rs485-rts-active-low;
|
||||
};
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
================
|
||||
Cyclades-Z notes
|
||||
================
|
||||
|
||||
The Cyclades-Z must have firmware loaded onto the card before it will
|
||||
operate. This operation should be performed during system startup,
|
||||
|
||||
The firmware, loader program and the latest device driver code are
|
||||
available from Cyclades at
|
||||
|
||||
ftp://ftp.cyclades.com/pub/cyclades/cyclades-z/linux/
|
@ -17,7 +17,6 @@ Serial drivers
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
cyclades_z
|
||||
moxa-smartio
|
||||
n_gsm
|
||||
rocket
|
||||
|
@ -1,185 +0,0 @@
|
||||
================================================
|
||||
Comtrol(tm) RocketPort(R)/RocketModem(TM) Series
|
||||
================================================
|
||||
|
||||
Device Driver for the Linux Operating System
|
||||
============================================
|
||||
|
||||
Product overview
|
||||
----------------
|
||||
|
||||
This driver provides a loadable kernel driver for the Comtrol RocketPort
|
||||
and RocketModem PCI boards. These boards provide, 2, 4, 8, 16, or 32
|
||||
high-speed serial ports or modems. This driver supports up to a combination
|
||||
of four RocketPort or RocketModems boards in one machine simultaneously.
|
||||
This file assumes that you are using the RocketPort driver which is
|
||||
integrated into the kernel sources.
|
||||
|
||||
The driver can also be installed as an external module using the usual
|
||||
"make;make install" routine. This external module driver, obtainable
|
||||
from the Comtrol website listed below, is useful for updating the driver
|
||||
or installing it into kernels which do not have the driver configured
|
||||
into them. Installations instructions for the external module
|
||||
are in the included README and HW_INSTALL files.
|
||||
|
||||
RocketPort ISA and RocketModem II PCI boards currently are only supported by
|
||||
this driver in module form.
|
||||
|
||||
The RocketPort ISA board requires I/O ports to be configured by the DIP
|
||||
switches on the board. See the section "ISA Rocketport Boards" below for
|
||||
information on how to set the DIP switches.
|
||||
|
||||
You pass the I/O port to the driver using the following module parameters:
|
||||
|
||||
board1:
|
||||
I/O port for the first ISA board
|
||||
board2:
|
||||
I/O port for the second ISA board
|
||||
board3:
|
||||
I/O port for the third ISA board
|
||||
board4:
|
||||
I/O port for the fourth ISA board
|
||||
|
||||
There is a set of utilities and scripts provided with the external driver
|
||||
(downloadable from http://www.comtrol.com) that ease the configuration and
|
||||
setup of the ISA cards.
|
||||
|
||||
The RocketModem II PCI boards require firmware to be loaded into the card
|
||||
before it will function. The driver has only been tested as a module for this
|
||||
board.
|
||||
|
||||
Installation Procedures
|
||||
-----------------------
|
||||
|
||||
RocketPort/RocketModem PCI cards require no driver configuration, they are
|
||||
automatically detected and configured.
|
||||
|
||||
The RocketPort driver can be installed as a module (recommended) or built
|
||||
into the kernel. This is selected, as for other drivers, through the `make config`
|
||||
command from the root of the Linux source tree during the kernel build process.
|
||||
|
||||
The RocketPort/RocketModem serial ports installed by this driver are assigned
|
||||
device major number 46, and will be named /dev/ttyRx, where x is the port number
|
||||
starting at zero (ex. /dev/ttyR0, /devttyR1, ...). If you have multiple cards
|
||||
installed in the system, the mapping of port names to serial ports is displayed
|
||||
in the system log at /var/log/messages.
|
||||
|
||||
If installed as a module, the module must be loaded. This can be done
|
||||
manually by entering "modprobe rocket". To have the module loaded automatically
|
||||
upon system boot, edit a `/etc/modprobe.d/*.conf` file and add the line
|
||||
"alias char-major-46 rocket".
|
||||
|
||||
In order to use the ports, their device names (nodes) must be created with mknod.
|
||||
This is only required once, the system will retain the names once created. To
|
||||
create the RocketPort/RocketModem device names, use the command
|
||||
"mknod /dev/ttyRx c 46 x" where x is the port number starting at zero.
|
||||
|
||||
For example::
|
||||
|
||||
> mknod /dev/ttyR0 c 46 0
|
||||
> mknod /dev/ttyR1 c 46 1
|
||||
> mknod /dev/ttyR2 c 46 2
|
||||
|
||||
The Linux script MAKEDEV will create the first 16 ttyRx device names (nodes)
|
||||
for you::
|
||||
|
||||
>/dev/MAKEDEV ttyR
|
||||
|
||||
ISA Rocketport Boards
|
||||
---------------------
|
||||
|
||||
You must assign and configure the I/O addresses used by the ISA Rocketport
|
||||
card before installing and using it. This is done by setting a set of DIP
|
||||
switches on the Rocketport board.
|
||||
|
||||
|
||||
Setting the I/O address
|
||||
-----------------------
|
||||
|
||||
Before installing RocketPort(R) or RocketPort RA boards, you must find
|
||||
a range of I/O addresses for it to use. The first RocketPort card
|
||||
requires a 68-byte contiguous block of I/O addresses, starting at one
|
||||
of the following: 0x100h, 0x140h, 0x180h, 0x200h, 0x240h, 0x280h,
|
||||
0x300h, 0x340h, 0x380h. This I/O address must be reflected in the DIP
|
||||
switches of *all* of the Rocketport cards.
|
||||
|
||||
The second, third, and fourth RocketPort cards require a 64-byte
|
||||
contiguous block of I/O addresses, starting at one of the following
|
||||
I/O addresses: 0x100h, 0x140h, 0x180h, 0x1C0h, 0x200h, 0x240h, 0x280h,
|
||||
0x2C0h, 0x300h, 0x340h, 0x380h, 0x3C0h. The I/O address used by the
|
||||
second, third, and fourth Rocketport cards (if present) are set via
|
||||
software control. The DIP switch settings for the I/O address must be
|
||||
set to the value of the first Rocketport cards.
|
||||
|
||||
In order to distinguish each of the card from the others, each card
|
||||
must have a unique board ID set on the dip switches. The first
|
||||
Rocketport board must be set with the DIP switches corresponding to
|
||||
the first board, the second board must be set with the DIP switches
|
||||
corresponding to the second board, etc. IMPORTANT: The board ID is
|
||||
the only place where the DIP switch settings should differ between the
|
||||
various Rocketport boards in a system.
|
||||
|
||||
The I/O address range used by any of the RocketPort cards must not
|
||||
conflict with any other cards in the system, including other
|
||||
RocketPort cards. Below, you will find a list of commonly used I/O
|
||||
address ranges which may be in use by other devices in your system.
|
||||
On a Linux system, "cat /proc/ioports" will also be helpful in
|
||||
identifying what I/O addresses are being used by devices on your
|
||||
system.
|
||||
|
||||
Remember, the FIRST RocketPort uses 68 I/O addresses. So, if you set it
|
||||
for 0x100, it will occupy 0x100 to 0x143. This would mean that you
|
||||
CAN NOT set the second, third or fourth board for address 0x140 since
|
||||
the first 4 bytes of that range are used by the first board. You would
|
||||
need to set the second, third, or fourth board to one of the next available
|
||||
blocks such as 0x180.
|
||||
|
||||
RocketPort and RocketPort RA SW1 Settings::
|
||||
|
||||
+-------------------------------+
|
||||
| 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
||||
+-------+-------+---------------+
|
||||
| Unused| Card | I/O Port Block|
|
||||
+-------------------------------+
|
||||
|
||||
DIP Switches DIP Switches
|
||||
7 8 6 5
|
||||
=================== ===================
|
||||
On On UNUSED, MUST BE ON. On On First Card <==== Default
|
||||
On Off Second Card
|
||||
Off On Third Card
|
||||
Off Off Fourth Card
|
||||
|
||||
DIP Switches I/O Address Range
|
||||
4 3 2 1 Used by the First Card
|
||||
=====================================
|
||||
On Off On Off 100-143
|
||||
On Off Off On 140-183
|
||||
On Off Off Off 180-1C3 <==== Default
|
||||
Off On On Off 200-243
|
||||
Off On Off On 240-283
|
||||
Off On Off Off 280-2C3
|
||||
Off Off On Off 300-343
|
||||
Off Off Off On 340-383
|
||||
Off Off Off Off 380-3C3
|
||||
|
||||
Reporting Bugs
|
||||
--------------
|
||||
|
||||
For technical support, please provide the following
|
||||
information: Driver version, kernel release, distribution of
|
||||
kernel, and type of board you are using. Error messages and log
|
||||
printouts port configuration details are especially helpful.
|
||||
|
||||
USA:
|
||||
:Phone: (612) 494-4100
|
||||
:FAX: (612) 494-4199
|
||||
:email: support@comtrol.com
|
||||
|
||||
Comtrol Europe:
|
||||
:Phone: +44 (0) 1 869 323-220
|
||||
:FAX: +44 (0) 1 869 323-211
|
||||
:email: support@comtrol.co.uk
|
||||
|
||||
Web: http://www.comtrol.com
|
||||
FTP: ftp.comtrol.com
|
@ -73,12 +73,10 @@ CMAGIC 0x0111 user ``include/linux/
|
||||
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel ``drivers/net/mkiss.h``
|
||||
HDLC_MAGIC 0x239e n_hdlc ``drivers/char/n_hdlc.c``
|
||||
APM_BIOS_MAGIC 0x4101 apm_user ``arch/x86/kernel/apm_32.c``
|
||||
CYCLADES_MAGIC 0x4359 cyclades_port ``include/linux/cyclades.h``
|
||||
DB_MAGIC 0x4442 fc_info ``drivers/net/iph5526_novram.c``
|
||||
DL_MAGIC 0x444d fc_info ``drivers/net/iph5526_novram.c``
|
||||
FASYNC_MAGIC 0x4601 fasync_struct ``include/linux/fs.h``
|
||||
FF_MAGIC 0x4646 fc_info ``drivers/net/iph5526_novram.c``
|
||||
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
|
||||
PTY_MAGIC 0x5001 ``drivers/char/pty.c``
|
||||
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
|
||||
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
|
||||
@ -90,14 +88,12 @@ TTY_MAGIC 0x5401 tty_struct ``include/linux/
|
||||
MGSL_MAGIC 0x5401 mgsl_info ``drivers/char/synclink.c``
|
||||
TTY_DRIVER_MAGIC 0x5402 tty_driver ``include/linux/tty_driver.h``
|
||||
MGSLPC_MAGIC 0x5402 mgslpc_info ``drivers/char/pcmcia/synclink_cs.c``
|
||||
TTY_LDISC_MAGIC 0x5403 tty_ldisc ``include/linux/tty_ldisc.h``
|
||||
USB_SERIAL_MAGIC 0x6702 usb_serial ``drivers/usb/serial/usb-serial.h``
|
||||
FULL_DUPLEX_MAGIC 0x6969 ``drivers/net/ethernet/dec/tulip/de2104x.c``
|
||||
USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth ``drivers/usb/class/bluetty.c``
|
||||
RFCOMM_TTY_MAGIC 0x6d02 ``net/bluetooth/rfcomm/tty.c``
|
||||
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port ``drivers/usb/serial/usb-serial.h``
|
||||
CG_MAGIC 0x00090255 ufs_cylinder_group ``include/linux/ufs_fs.h``
|
||||
RPORT_MAGIC 0x00525001 r_port ``drivers/char/rocket_int.h``
|
||||
LSEMAGIC 0x05091998 lse ``drivers/fc4/fc.c``
|
||||
RIEBL_MAGIC 0x09051990 ``drivers/net/atarilance.c``
|
||||
NBD_REQUEST_MAGIC 0x12560953 nbd_request ``include/linux/nbd.h``
|
||||
|
@ -79,12 +79,10 @@ CMAGIC 0x0111 user ``include/linux/
|
||||
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel ``drivers/net/mkiss.h``
|
||||
HDLC_MAGIC 0x239e n_hdlc ``drivers/char/n_hdlc.c``
|
||||
APM_BIOS_MAGIC 0x4101 apm_user ``arch/x86/kernel/apm_32.c``
|
||||
CYCLADES_MAGIC 0x4359 cyclades_port ``include/linux/cyclades.h``
|
||||
DB_MAGIC 0x4442 fc_info ``drivers/net/iph5526_novram.c``
|
||||
DL_MAGIC 0x444d fc_info ``drivers/net/iph5526_novram.c``
|
||||
FASYNC_MAGIC 0x4601 fasync_struct ``include/linux/fs.h``
|
||||
FF_MAGIC 0x4646 fc_info ``drivers/net/iph5526_novram.c``
|
||||
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
|
||||
PTY_MAGIC 0x5001 ``drivers/char/pty.c``
|
||||
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
|
||||
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
|
||||
@ -96,14 +94,12 @@ TTY_MAGIC 0x5401 tty_struct ``include/linux/
|
||||
MGSL_MAGIC 0x5401 mgsl_info ``drivers/char/synclink.c``
|
||||
TTY_DRIVER_MAGIC 0x5402 tty_driver ``include/linux/tty_driver.h``
|
||||
MGSLPC_MAGIC 0x5402 mgslpc_info ``drivers/char/pcmcia/synclink_cs.c``
|
||||
TTY_LDISC_MAGIC 0x5403 tty_ldisc ``include/linux/tty_ldisc.h``
|
||||
USB_SERIAL_MAGIC 0x6702 usb_serial ``drivers/usb/serial/usb-serial.h``
|
||||
FULL_DUPLEX_MAGIC 0x6969 ``drivers/net/ethernet/dec/tulip/de2104x.c``
|
||||
USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth ``drivers/usb/class/bluetty.c``
|
||||
RFCOMM_TTY_MAGIC 0x6d02 ``net/bluetooth/rfcomm/tty.c``
|
||||
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port ``drivers/usb/serial/usb-serial.h``
|
||||
CG_MAGIC 0x00090255 ufs_cylinder_group ``include/linux/ufs_fs.h``
|
||||
RPORT_MAGIC 0x00525001 r_port ``drivers/char/rocket_int.h``
|
||||
LSEMAGIC 0x05091998 lse ``drivers/fc4/fc.c``
|
||||
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str ``drivers/scsi/gdth_ioctl.h``
|
||||
RIEBL_MAGIC 0x09051990 ``drivers/net/atarilance.c``
|
||||
|
@ -62,12 +62,10 @@ CMAGIC 0x0111 user ``include/linux/
|
||||
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel ``drivers/net/mkiss.h``
|
||||
HDLC_MAGIC 0x239e n_hdlc ``drivers/char/n_hdlc.c``
|
||||
APM_BIOS_MAGIC 0x4101 apm_user ``arch/x86/kernel/apm_32.c``
|
||||
CYCLADES_MAGIC 0x4359 cyclades_port ``include/linux/cyclades.h``
|
||||
DB_MAGIC 0x4442 fc_info ``drivers/net/iph5526_novram.c``
|
||||
DL_MAGIC 0x444d fc_info ``drivers/net/iph5526_novram.c``
|
||||
FASYNC_MAGIC 0x4601 fasync_struct ``include/linux/fs.h``
|
||||
FF_MAGIC 0x4646 fc_info ``drivers/net/iph5526_novram.c``
|
||||
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
|
||||
PTY_MAGIC 0x5001 ``drivers/char/pty.c``
|
||||
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
|
||||
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
|
||||
@ -79,14 +77,12 @@ TTY_MAGIC 0x5401 tty_struct ``include/linux/
|
||||
MGSL_MAGIC 0x5401 mgsl_info ``drivers/char/synclink.c``
|
||||
TTY_DRIVER_MAGIC 0x5402 tty_driver ``include/linux/tty_driver.h``
|
||||
MGSLPC_MAGIC 0x5402 mgslpc_info ``drivers/char/pcmcia/synclink_cs.c``
|
||||
TTY_LDISC_MAGIC 0x5403 tty_ldisc ``include/linux/tty_ldisc.h``
|
||||
USB_SERIAL_MAGIC 0x6702 usb_serial ``drivers/usb/serial/usb-serial.h``
|
||||
FULL_DUPLEX_MAGIC 0x6969 ``drivers/net/ethernet/dec/tulip/de2104x.c``
|
||||
USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth ``drivers/usb/class/bluetty.c``
|
||||
RFCOMM_TTY_MAGIC 0x6d02 ``net/bluetooth/rfcomm/tty.c``
|
||||
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port ``drivers/usb/serial/usb-serial.h``
|
||||
CG_MAGIC 0x00090255 ufs_cylinder_group ``include/linux/ufs_fs.h``
|
||||
RPORT_MAGIC 0x00525001 r_port ``drivers/char/rocket_int.h``
|
||||
LSEMAGIC 0x05091998 lse ``drivers/fc4/fc.c``
|
||||
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str ``drivers/scsi/gdth_ioctl.h``
|
||||
RIEBL_MAGIC 0x09051990 ``drivers/net/atarilance.c``
|
||||
|
@ -209,7 +209,6 @@ Code Seq# Include File Comments
|
||||
linux/fs.h,
|
||||
'X' all fs/ocfs2/ocfs_fs.h conflict!
|
||||
'X' 01 linux/pktcdvd.h conflict!
|
||||
'Y' all linux/cyclades.h
|
||||
'Z' 14-15 drivers/message/fusion/mptctl.h
|
||||
'[' 00-3F linux/usb/tmc.h USB Test and Measurement Devices
|
||||
<mailto:gregkh@linuxfoundation.org>
|
||||
|
30
MAINTAINERS
30
MAINTAINERS
@ -3578,6 +3578,14 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/i2c/brcm,brcmstb-i2c.yaml
|
||||
F: drivers/i2c/busses/i2c-brcmstb.c
|
||||
|
||||
BROADCOM BRCMSTB UART DRIVER
|
||||
M: Al Cooper <alcooperx@gmail.com>
|
||||
L: linux-serial@vger.kernel.org
|
||||
L: bcm-kernel-feedback-list@broadcom.com
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml
|
||||
F: drivers/tty/serial/8250/8250_bcm7271.c
|
||||
|
||||
BROADCOM BRCMSTB USB EHCI DRIVER
|
||||
M: Al Cooper <alcooperx@gmail.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
@ -4902,16 +4910,8 @@ S: Maintained
|
||||
W: http://www.armlinux.org.uk/
|
||||
F: drivers/video/fbdev/cyber2000fb.*
|
||||
|
||||
CYCLADES ASYNC MUX DRIVER
|
||||
S: Orphan
|
||||
W: http://www.cyclades.com/
|
||||
F: drivers/tty/cyclades.c
|
||||
F: include/linux/cyclades.h
|
||||
F: include/uapi/linux/cyclades.h
|
||||
|
||||
CYCLADES PC300 DRIVER
|
||||
S: Orphan
|
||||
W: http://www.cyclades.com/
|
||||
F: drivers/net/wan/pc300*
|
||||
|
||||
CYPRESS_FIRMWARE MEDIA DRIVER
|
||||
@ -12167,8 +12167,7 @@ F: drivers/media/pci/meye/
|
||||
F: include/uapi/linux/meye.h
|
||||
|
||||
MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD
|
||||
M: Jiri Slaby <jirislaby@kernel.org>
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: Documentation/driver-api/serial/moxa-smartio.rst
|
||||
F: drivers/tty/mxser.*
|
||||
|
||||
@ -12312,11 +12311,6 @@ F: drivers/mux/
|
||||
F: include/dt-bindings/mux/
|
||||
F: include/linux/mux/
|
||||
|
||||
MULTITECH MULTIPORT CARD (ISICOM)
|
||||
S: Orphan
|
||||
F: drivers/tty/isicom.c
|
||||
F: include/linux/isicom.h
|
||||
|
||||
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
|
||||
M: Bin Liu <b-liu@ti.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
@ -15493,12 +15487,6 @@ L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/rocker/
|
||||
|
||||
ROCKETPORT DRIVER
|
||||
S: Maintained
|
||||
W: http://www.comtrol.com
|
||||
F: Documentation/driver-api/serial/rocket.rst
|
||||
F: drivers/tty/rocket*
|
||||
|
||||
ROCKETPORT EXPRESS/INFINITY DRIVER
|
||||
M: Kevin Cernekee <cernekee@gmail.com>
|
||||
L: linux-serial@vger.kernel.org
|
||||
|
@ -452,32 +452,36 @@ spdifrx: audio-controller@4000d000 {
|
||||
usart2: serial@4000e000 {
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x4000e000 0x400>;
|
||||
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc USART2_K>;
|
||||
wakeup-source;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usart3: serial@4000f000 {
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x4000f000 0x400>;
|
||||
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc USART3_K>;
|
||||
wakeup-source;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart4: serial@40010000 {
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x40010000 0x400>;
|
||||
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc UART4_K>;
|
||||
wakeup-source;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart5: serial@40011000 {
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x40011000 0x400>;
|
||||
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc UART5_K>;
|
||||
wakeup-source;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@ -577,16 +581,18 @@ dac2: dac@2 {
|
||||
uart7: serial@40018000 {
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x40018000 0x400>;
|
||||
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc UART7_K>;
|
||||
wakeup-source;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart8: serial@40019000 {
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x40019000 0x400>;
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc UART8_K>;
|
||||
wakeup-source;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@ -665,8 +671,9 @@ counter {
|
||||
usart6: serial@44003000 {
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x44003000 0x400>;
|
||||
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc USART6_K>;
|
||||
wakeup-source;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@ -1505,8 +1512,9 @@ usbphyc_port1: usb-phy@1 {
|
||||
usart1: serial@5c000000 {
|
||||
compatible = "st,stm32h7-uart";
|
||||
reg = <0x5c000000 0x400>;
|
||||
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc USART1_K>;
|
||||
wakeup-source;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -595,7 +595,6 @@ CONFIG_GAMEPORT_FM801=m
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
CONFIG_ROCKETPORT=m
|
||||
CONFIG_CYCLADES=m
|
||||
CONFIG_SYNCLINK_GT=m
|
||||
CONFIG_NOZOMI=m
|
||||
CONFIG_N_HDLC=m
|
||||
|
@ -31,48 +31,23 @@
|
||||
#define SERIAL_MAX_NUM_LINES 1
|
||||
#define SERIAL_TIMER_VALUE (HZ / 10)
|
||||
|
||||
static void rs_poll(struct timer_list *);
|
||||
|
||||
static struct tty_driver *serial_driver;
|
||||
static struct tty_port serial_port;
|
||||
static struct timer_list serial_timer;
|
||||
|
||||
static DEFINE_TIMER(serial_timer, rs_poll);
|
||||
static DEFINE_SPINLOCK(timer_lock);
|
||||
|
||||
static char *serial_version = "0.1";
|
||||
static char *serial_name = "ISS serial driver";
|
||||
|
||||
/*
|
||||
* This routine is called whenever a serial port is opened. It
|
||||
* enables interrupts for a serial port, linking in its async structure into
|
||||
* the IRQ chain. It also performs the serial-specific
|
||||
* initialization for the tty structure.
|
||||
*/
|
||||
|
||||
static void rs_poll(struct timer_list *);
|
||||
|
||||
static int rs_open(struct tty_struct *tty, struct file * filp)
|
||||
{
|
||||
tty->port = &serial_port;
|
||||
spin_lock_bh(&timer_lock);
|
||||
if (tty->count == 1) {
|
||||
timer_setup(&serial_timer, rs_poll, 0);
|
||||
if (tty->count == 1)
|
||||
mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
|
||||
}
|
||||
spin_unlock_bh(&timer_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------------
|
||||
* iss_serial_close()
|
||||
*
|
||||
* This routine is called when the serial port gets closed. First, we
|
||||
* wait for the last remaining data to be sent. Then, we unlink its
|
||||
* async structure from the interrupt chain if necessary, and we free
|
||||
* that IRQ if nothing is left in the chain.
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
static void rs_close(struct tty_struct *tty, struct file * filp)
|
||||
{
|
||||
spin_lock_bh(&timer_lock);
|
||||
@ -149,7 +124,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
|
||||
static int rs_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
|
||||
seq_printf(m, "serinfo:1.0 driver:0.1\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -166,14 +141,12 @@ static const struct tty_operations serial_ops = {
|
||||
.proc_show = rs_proc_show,
|
||||
};
|
||||
|
||||
int __init rs_init(void)
|
||||
static int __init rs_init(void)
|
||||
{
|
||||
tty_port_init(&serial_port);
|
||||
|
||||
serial_driver = alloc_tty_driver(SERIAL_MAX_NUM_LINES);
|
||||
|
||||
pr_info("%s %s\n", serial_name, serial_version);
|
||||
|
||||
/* Initialize the tty_driver structure */
|
||||
|
||||
serial_driver->driver_name = "iss_serial";
|
||||
@ -198,11 +171,7 @@ int __init rs_init(void)
|
||||
|
||||
static __exit void rs_exit(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = tty_unregister_driver(serial_driver)))
|
||||
pr_err("ISS_SERIAL: failed to unregister serial driver (%d)\n",
|
||||
error);
|
||||
tty_unregister_driver(serial_driver);
|
||||
put_tty_driver(serial_driver);
|
||||
tty_port_destroy(&serial_port);
|
||||
}
|
||||
|
@ -104,7 +104,6 @@ static int spk_ttyio_receive_buf2(struct tty_struct *tty,
|
||||
|
||||
static struct tty_ldisc_ops spk_ttyio_ldisc_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "speakup_ldisc",
|
||||
.open = spk_ttyio_ldisc_open,
|
||||
.close = spk_ttyio_ldisc_close,
|
||||
|
@ -821,7 +821,6 @@ static __poll_t hci_uart_tty_poll(struct tty_struct *tty,
|
||||
|
||||
static struct tty_ldisc_ops hci_uart_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "n_hci",
|
||||
.open = hci_uart_tty_open,
|
||||
.close = hci_uart_tty_close,
|
||||
|
@ -530,8 +530,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
|
||||
info->port.ops = &mgslpc_port_ops;
|
||||
INIT_WORK(&info->task, bh_handler);
|
||||
info->max_frame_size = 4096;
|
||||
info->port.close_delay = 5*HZ/10;
|
||||
info->port.closing_wait = 30*HZ;
|
||||
init_waitqueue_head(&info->status_event_wait_q);
|
||||
init_waitqueue_head(&info->event_wait_q);
|
||||
spin_lock_init(&info->lock);
|
||||
|
@ -158,12 +158,23 @@ static int tpk_ioctl(struct tty_struct *tty,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TTY operations hangup function.
|
||||
*/
|
||||
static void tpk_hangup(struct tty_struct *tty)
|
||||
{
|
||||
struct ttyprintk_port *tpkp = tty->driver_data;
|
||||
|
||||
tty_port_hangup(&tpkp->port);
|
||||
}
|
||||
|
||||
static const struct tty_operations ttyprintk_ops = {
|
||||
.open = tpk_open,
|
||||
.close = tpk_close,
|
||||
.write = tpk_write,
|
||||
.write_room = tpk_write_room,
|
||||
.ioctl = tpk_ioctl,
|
||||
.hangup = tpk_hangup,
|
||||
};
|
||||
|
||||
static const struct tty_port_operations null_ops = { };
|
||||
|
@ -845,7 +845,6 @@ static void st_tty_flush_buffer(struct tty_struct *tty)
|
||||
}
|
||||
|
||||
static struct tty_ldisc_ops st_ldisc_ops = {
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "n_st",
|
||||
.open = st_tty_open,
|
||||
.close = st_tty_close,
|
||||
|
@ -382,7 +382,6 @@ static void ldisc_close(struct tty_struct *tty)
|
||||
/* The line discipline structure. */
|
||||
static struct tty_ldisc_ops caif_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "n_caif",
|
||||
.open = ldisc_open,
|
||||
.close = ldisc_close,
|
||||
@ -390,18 +389,6 @@ static struct tty_ldisc_ops caif_ldisc = {
|
||||
.write_wakeup = ldisc_tx_wakeup
|
||||
};
|
||||
|
||||
static int register_ldisc(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = tty_register_ldisc(N_CAIF, &caif_ldisc);
|
||||
if (result < 0) {
|
||||
pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF,
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static const struct net_device_ops netdev_ops = {
|
||||
.ndo_open = caif_net_open,
|
||||
.ndo_stop = caif_net_close,
|
||||
@ -444,7 +431,10 @@ static int __init caif_ser_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = register_ldisc();
|
||||
ret = tty_register_ldisc(N_CAIF, &caif_ldisc);
|
||||
if (ret < 0)
|
||||
pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF, ret);
|
||||
|
||||
debugfsdir = debugfs_create_dir("caif_serial", NULL);
|
||||
return ret;
|
||||
}
|
||||
|
@ -697,7 +697,6 @@ static int slcan_ioctl(struct tty_struct *tty, struct file *file,
|
||||
|
||||
static struct tty_ldisc_ops slc_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "slcan",
|
||||
.open = slcan_open,
|
||||
.close = slcan_close,
|
||||
|
@ -744,7 +744,6 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
|
||||
|
||||
static struct tty_ldisc_ops sp_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "6pack",
|
||||
.open = sixpack_open,
|
||||
.close = sixpack_close,
|
||||
|
@ -933,7 +933,6 @@ static void mkiss_write_wakeup(struct tty_struct *tty)
|
||||
|
||||
static struct tty_ldisc_ops ax_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "mkiss",
|
||||
.open = mkiss_open,
|
||||
.close = mkiss_close,
|
||||
|
@ -372,7 +372,6 @@ ppp_asynctty_wakeup(struct tty_struct *tty)
|
||||
|
||||
static struct tty_ldisc_ops ppp_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "ppp",
|
||||
.open = ppp_asynctty_open,
|
||||
.close = ppp_asynctty_close,
|
||||
|
@ -365,7 +365,6 @@ ppp_sync_wakeup(struct tty_struct *tty)
|
||||
|
||||
static struct tty_ldisc_ops ppp_sync_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "pppsync",
|
||||
.open = ppp_sync_open,
|
||||
.close = ppp_sync_close,
|
||||
|
@ -1263,7 +1263,6 @@ static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||
|
||||
static struct tty_ldisc_ops sl_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "slip",
|
||||
.open = slip_open,
|
||||
.close = slip_close,
|
||||
|
@ -13,8 +13,6 @@
|
||||
#include <linux/pps_kernel.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
#define PPS_TTY_MAGIC 0x0001
|
||||
|
||||
static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status)
|
||||
{
|
||||
struct pps_device *pps;
|
||||
@ -114,7 +112,6 @@ static int __init pps_tty_init(void)
|
||||
|
||||
/* Init PPS_TTY data */
|
||||
pps_ldisc_ops.owner = THIS_MODULE;
|
||||
pps_ldisc_ops.magic = PPS_TTY_MAGIC;
|
||||
pps_ldisc_ops.name = "pps_tty";
|
||||
pps_ldisc_ops.dcd_change = pps_tty_dcd_change;
|
||||
pps_ldisc_ops.open = pps_tty_open;
|
||||
|
@ -85,7 +85,6 @@ struct raw3215_info {
|
||||
int written; /* number of bytes in write requests */
|
||||
struct raw3215_req *queued_read; /* pointer to queued read requests */
|
||||
struct raw3215_req *queued_write;/* pointer to queued write requests */
|
||||
struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */
|
||||
wait_queue_head_t empty_wait; /* wait queue for flushing */
|
||||
struct timer_list timer; /* timer for delayed output */
|
||||
int line_pos; /* position on the line (for tabs) */
|
||||
@ -329,21 +328,6 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Call tty_wakeup from tasklet context
|
||||
*/
|
||||
static void raw3215_wakeup(unsigned long data)
|
||||
{
|
||||
struct raw3215_info *raw = (struct raw3215_info *) data;
|
||||
struct tty_struct *tty;
|
||||
|
||||
tty = tty_port_tty_get(&raw->port);
|
||||
if (tty) {
|
||||
tty_wakeup(tty);
|
||||
tty_kref_put(tty);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to start the next IO and wake up processes waiting on the tty.
|
||||
*/
|
||||
@ -352,7 +336,7 @@ static void raw3215_next_io(struct raw3215_info *raw, struct tty_struct *tty)
|
||||
raw3215_mk_write_req(raw);
|
||||
raw3215_try_io(raw);
|
||||
if (tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
|
||||
tasklet_schedule(&raw->tlet);
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -644,7 +628,6 @@ static struct raw3215_info *raw3215_alloc_info(void)
|
||||
|
||||
timer_setup(&info->timer, raw3215_timeout, 0);
|
||||
init_waitqueue_head(&info->empty_wait);
|
||||
tasklet_init(&info->tlet, raw3215_wakeup, (unsigned long)info);
|
||||
tty_port_init(&info->port);
|
||||
|
||||
return info;
|
||||
@ -928,15 +911,13 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp)
|
||||
*/
|
||||
static void tty3215_close(struct tty_struct *tty, struct file * filp)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
if (raw == NULL || tty->count > 1)
|
||||
return;
|
||||
tty->closing = 1;
|
||||
/* Shutdown the terminal */
|
||||
raw3215_shutdown(raw);
|
||||
tasklet_kill(&raw->tlet);
|
||||
tty->closing = 0;
|
||||
tty_port_tty_set(&raw->port, NULL);
|
||||
}
|
||||
@ -946,9 +927,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp)
|
||||
*/
|
||||
static int tty3215_write_room(struct tty_struct *tty)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
|
||||
/* Subtract TAB_STOP_SIZE to allow for a tab, 8 <<< 64K */
|
||||
if ((RAW3215_BUFFER_SIZE - raw->count - TAB_STOP_SIZE) >= 0)
|
||||
@ -963,12 +942,9 @@ static int tty3215_write_room(struct tty_struct *tty)
|
||||
static int tty3215_write(struct tty_struct * tty,
|
||||
const unsigned char *buf, int count)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
int i, written;
|
||||
|
||||
if (!tty)
|
||||
return 0;
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
written = count;
|
||||
while (count > 0) {
|
||||
for (i = 0; i < count; i++)
|
||||
@ -991,12 +967,10 @@ static int tty3215_write(struct tty_struct * tty,
|
||||
*/
|
||||
static int tty3215_put_char(struct tty_struct *tty, unsigned char ch)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
|
||||
if (!tty)
|
||||
return 0;
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
raw3215_putchar(raw, ch);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1009,17 +983,15 @@ static void tty3215_flush_chars(struct tty_struct *tty)
|
||||
*/
|
||||
static int tty3215_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
return raw->count;
|
||||
}
|
||||
|
||||
static void tty3215_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
raw3215_flush_buffer(raw);
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
@ -1029,9 +1001,8 @@ static void tty3215_flush_buffer(struct tty_struct *tty)
|
||||
*/
|
||||
static void tty3215_throttle(struct tty_struct * tty)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
raw->flags |= RAW3215_THROTTLED;
|
||||
}
|
||||
|
||||
@ -1040,10 +1011,9 @@ static void tty3215_throttle(struct tty_struct * tty)
|
||||
*/
|
||||
static void tty3215_unthrottle(struct tty_struct * tty)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
if (raw->flags & RAW3215_THROTTLED) {
|
||||
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
|
||||
raw->flags &= ~RAW3215_THROTTLED;
|
||||
@ -1057,9 +1027,8 @@ static void tty3215_unthrottle(struct tty_struct * tty)
|
||||
*/
|
||||
static void tty3215_stop(struct tty_struct *tty)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
raw->flags |= RAW3215_STOPPED;
|
||||
}
|
||||
|
||||
@ -1068,10 +1037,9 @@ static void tty3215_stop(struct tty_struct *tty)
|
||||
*/
|
||||
static void tty3215_start(struct tty_struct *tty)
|
||||
{
|
||||
struct raw3215_info *raw;
|
||||
struct raw3215_info *raw = tty->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
raw = (struct raw3215_info *) tty->driver_data;
|
||||
if (raw->flags & RAW3215_STOPPED) {
|
||||
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
|
||||
raw->flags &= ~RAW3215_STOPPED;
|
||||
|
@ -1218,13 +1218,12 @@ static int get_serial_info(struct tty_struct *tty,
|
||||
struct fwtty_port *port = tty->driver_data;
|
||||
|
||||
mutex_lock(&port->port.mutex);
|
||||
ss->type = PORT_UNKNOWN;
|
||||
ss->line = port->port.tty->index;
|
||||
ss->flags = port->port.flags;
|
||||
ss->xmit_fifo_size = FWTTY_PORT_TXFIFO_LEN;
|
||||
ss->line = port->index;
|
||||
ss->baud_base = 400000000;
|
||||
ss->close_delay = port->port.close_delay;
|
||||
ss->close_delay = jiffies_to_msecs(port->port.close_delay) / 10;
|
||||
ss->closing_wait = 3000;
|
||||
mutex_unlock(&port->port.mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1232,20 +1231,20 @@ static int set_serial_info(struct tty_struct *tty,
|
||||
struct serial_struct *ss)
|
||||
{
|
||||
struct fwtty_port *port = tty->driver_data;
|
||||
unsigned int cdelay;
|
||||
|
||||
if (ss->irq != 0 || ss->port != 0 || ss->custom_divisor != 0 ||
|
||||
ss->baud_base != 400000000)
|
||||
return -EPERM;
|
||||
cdelay = msecs_to_jiffies(ss->close_delay * 10);
|
||||
|
||||
mutex_lock(&port->port.mutex);
|
||||
if (!capable(CAP_SYS_ADMIN)) {
|
||||
if (((ss->flags & ~ASYNC_USR_MASK) !=
|
||||
if (cdelay != port->port.close_delay ||
|
||||
((ss->flags & ~ASYNC_USR_MASK) !=
|
||||
(port->port.flags & ~ASYNC_USR_MASK))) {
|
||||
mutex_unlock(&port->port.mutex);
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
port->port.close_delay = ss->close_delay * HZ / 100;
|
||||
port->port.close_delay = cdelay;
|
||||
mutex_unlock(&port->port.mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -188,7 +188,7 @@ static int gdm_tty_write_room(struct tty_struct *tty)
|
||||
struct gdm *gdm = tty->driver_data;
|
||||
|
||||
if (!GDM_TTY_READY(gdm))
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
|
||||
return WRITE_SIZE;
|
||||
}
|
||||
|
@ -610,14 +610,13 @@ static int get_serial_info(struct tty_struct *tty,
|
||||
{
|
||||
struct gb_tty *gb_tty = tty->driver_data;
|
||||
|
||||
ss->type = PORT_16550A;
|
||||
ss->line = gb_tty->minor;
|
||||
ss->xmit_fifo_size = 16;
|
||||
ss->baud_base = 9600;
|
||||
ss->close_delay = gb_tty->port.close_delay / 10;
|
||||
ss->close_delay = jiffies_to_msecs(gb_tty->port.close_delay) / 10;
|
||||
ss->closing_wait =
|
||||
gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
|
||||
ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10;
|
||||
ASYNC_CLOSING_WAIT_NONE :
|
||||
jiffies_to_msecs(gb_tty->port.closing_wait) / 10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -629,17 +628,16 @@ static int set_serial_info(struct tty_struct *tty,
|
||||
unsigned int close_delay;
|
||||
int retval = 0;
|
||||
|
||||
close_delay = ss->close_delay * 10;
|
||||
close_delay = msecs_to_jiffies(ss->close_delay * 10);
|
||||
closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ?
|
||||
ASYNC_CLOSING_WAIT_NONE : ss->closing_wait * 10;
|
||||
ASYNC_CLOSING_WAIT_NONE :
|
||||
msecs_to_jiffies(ss->closing_wait * 10);
|
||||
|
||||
mutex_lock(&gb_tty->port.mutex);
|
||||
if (!capable(CAP_SYS_ADMIN)) {
|
||||
if ((close_delay != gb_tty->port.close_delay) ||
|
||||
(closing_wait != gb_tty->port.closing_wait))
|
||||
retval = -EPERM;
|
||||
else
|
||||
retval = -EOPNOTSUPP;
|
||||
} else {
|
||||
gb_tty->port.close_delay = close_delay;
|
||||
gb_tty->port.closing_wait = closing_wait;
|
||||
|
@ -181,7 +181,7 @@ config SERIAL_NONSTANDARD
|
||||
help
|
||||
Say Y here if you have any non-standard serial boards -- boards
|
||||
which aren't supported using the standard "dumb" serial driver.
|
||||
This includes intelligent serial boards such as Cyclades,
|
||||
This includes intelligent serial boards such as
|
||||
Digiboards, etc. These are usually used for systems that need many
|
||||
serial ports because they serve many terminals or dial-in
|
||||
connections.
|
||||
@ -192,50 +192,6 @@ config SERIAL_NONSTANDARD
|
||||
|
||||
Most people can say N here.
|
||||
|
||||
config ROCKETPORT
|
||||
tristate "Comtrol RocketPort support"
|
||||
depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
|
||||
help
|
||||
This driver supports Comtrol RocketPort and RocketModem PCI boards.
|
||||
These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or
|
||||
modems. For information about the RocketPort/RocketModem boards
|
||||
and this driver read <file:Documentation/driver-api/serial/rocket.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called rocket.
|
||||
|
||||
If you want to compile this driver into the kernel, say Y here. If
|
||||
you don't have a Comtrol RocketPort/RocketModem card installed, say N.
|
||||
|
||||
config CYCLADES
|
||||
tristate "Cyclades async mux support"
|
||||
depends on SERIAL_NONSTANDARD && (PCI || ISA)
|
||||
select FW_LOADER
|
||||
help
|
||||
This driver supports Cyclades Z and Y multiserial boards.
|
||||
You would need something like this to connect more than two modems to
|
||||
your Linux box, for instance in order to become a dial-in server.
|
||||
|
||||
For information about the Cyclades-Z card, read
|
||||
<file:Documentation/driver-api/serial/cyclades_z.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called cyclades.
|
||||
|
||||
If you haven't heard about it, it's safe to say N.
|
||||
|
||||
config CYZ_INTR
|
||||
bool "Cyclades-Z interrupt mode operation"
|
||||
depends on CYCLADES && PCI
|
||||
help
|
||||
The Cyclades-Z family of multiport cards allows 2 (two) driver op
|
||||
modes: polling and interrupt. In polling mode, the driver will check
|
||||
the status of the Cyclades-Z ports every certain amount of time
|
||||
(which is called polling cycle and is configurable). In interrupt
|
||||
mode, it will use an interrupt line (IRQ) in order to check the
|
||||
status of the Cyclades-Z ports. The default op mode is polling. If
|
||||
unsure, say N.
|
||||
|
||||
config MOXA_INTELLIO
|
||||
tristate "Moxa Intellio support"
|
||||
depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
|
||||
@ -267,16 +223,6 @@ config SYNCLINK_GT
|
||||
synchronous and asynchronous serial adapters
|
||||
manufactured by Microgate Systems, Ltd. (www.microgate.com)
|
||||
|
||||
config ISI
|
||||
tristate "Multi-Tech multiport card support"
|
||||
depends on SERIAL_NONSTANDARD && PCI
|
||||
select FW_LOADER
|
||||
help
|
||||
This is a driver for the Multi-Tech cards which provide several
|
||||
serial ports. The driver is experimental and can currently only be
|
||||
built as a module. The module will be called isicom.
|
||||
If you want to do that, choose M here.
|
||||
|
||||
config N_HDLC
|
||||
tristate "HDLC line discipline support"
|
||||
depends on SERIAL_NONSTANDARD
|
||||
@ -415,36 +361,6 @@ config NULL_TTY
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config TRACE_ROUTER
|
||||
tristate "Trace data router for MIPI P1149.7 cJTAG standard"
|
||||
depends on TRACE_SINK
|
||||
help
|
||||
The trace router uses the Linux tty line discipline framework to
|
||||
route trace data coming from a tty port (say UART for example) to
|
||||
the trace sink line discipline driver and to another tty port (say
|
||||
USB). This is part of a solution for the MIPI P1149.7, compact JTAG,
|
||||
standard, which is for debugging mobile devices. The PTI driver in
|
||||
drivers/misc/pti.c defines the majority of this MIPI solution.
|
||||
|
||||
You should select this driver if the target kernel is meant for
|
||||
a mobile device containing a modem. Then you will need to select
|
||||
"Trace data sink for MIPI P1149.7 cJTAG standard" line discipline
|
||||
driver.
|
||||
|
||||
config TRACE_SINK
|
||||
tristate "Trace data sink for MIPI P1149.7 cJTAG standard"
|
||||
help
|
||||
The trace sink uses the Linux line discipline framework to receive
|
||||
trace data coming from the trace router line discipline driver
|
||||
to a user-defined tty port target, like USB.
|
||||
This is to provide a way to extract modem trace data on
|
||||
devices that do not have a PTI HW module, or just need modem
|
||||
trace data to come out of a different HW output port.
|
||||
This is part of a solution for the P1149.7, compact JTAG, standard.
|
||||
|
||||
If you select this option, you need to select
|
||||
"Trace data router for MIPI P1149.7 cJTAG standard".
|
||||
|
||||
config VCC
|
||||
tristate "Sun Virtual Console Concentrator"
|
||||
depends on SUN_LDOMS
|
||||
|
@ -18,13 +18,10 @@ obj-$(CONFIG_SERIAL_DEV_BUS) += serdev/
|
||||
|
||||
# tty drivers
|
||||
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
|
||||
obj-$(CONFIG_CYCLADES) += cyclades.o
|
||||
obj-$(CONFIG_ISI) += isicom.o
|
||||
obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
|
||||
obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
|
||||
obj-$(CONFIG_NOZOMI) += nozomi.o
|
||||
obj-$(CONFIG_NULL_TTY) += ttynull.o
|
||||
obj-$(CONFIG_ROCKETPORT) += rocket.o
|
||||
obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
|
||||
obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o
|
||||
obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o
|
||||
|
@ -937,15 +937,21 @@ static void rs_unthrottle(struct tty_struct * tty)
|
||||
static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss)
|
||||
{
|
||||
struct serial_state *state = tty->driver_data;
|
||||
unsigned int close_delay, closing_wait;
|
||||
|
||||
tty_lock(tty);
|
||||
close_delay = jiffies_to_msecs(state->tport.close_delay) / 10;
|
||||
closing_wait = state->tport.closing_wait;
|
||||
if (closing_wait != ASYNC_CLOSING_WAIT_NONE)
|
||||
closing_wait = jiffies_to_msecs(closing_wait) / 10;
|
||||
|
||||
ss->line = tty->index;
|
||||
ss->port = state->port;
|
||||
ss->flags = state->tport.flags;
|
||||
ss->xmit_fifo_size = state->xmit_fifo_size;
|
||||
ss->baud_base = state->baud_base;
|
||||
ss->close_delay = state->tport.close_delay;
|
||||
ss->closing_wait = state->tport.closing_wait;
|
||||
ss->close_delay = close_delay;
|
||||
ss->closing_wait = closing_wait;
|
||||
ss->custom_divisor = state->custom_divisor;
|
||||
tty_unlock(tty);
|
||||
return 0;
|
||||
@ -957,6 +963,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)
|
||||
struct tty_port *port = &state->tport;
|
||||
bool change_spd;
|
||||
int retval = 0;
|
||||
unsigned int close_delay, closing_wait;
|
||||
|
||||
tty_lock(tty);
|
||||
change_spd = ((ss->flags ^ port->flags) & ASYNC_SPD_MASK) ||
|
||||
@ -966,10 +973,16 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)
|
||||
tty_unlock(tty);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
close_delay = msecs_to_jiffies(ss->close_delay * 10);
|
||||
closing_wait = ss->closing_wait;
|
||||
if (closing_wait != ASYNC_CLOSING_WAIT_NONE)
|
||||
closing_wait = msecs_to_jiffies(closing_wait * 10);
|
||||
|
||||
if (!serial_isroot()) {
|
||||
if ((ss->baud_base != state->baud_base) ||
|
||||
(ss->close_delay != port->close_delay) ||
|
||||
(close_delay != port->close_delay) ||
|
||||
(closing_wait != port->closing_wait) ||
|
||||
(ss->xmit_fifo_size != state->xmit_fifo_size) ||
|
||||
((ss->flags & ~ASYNC_USR_MASK) !=
|
||||
(port->flags & ~ASYNC_USR_MASK))) {
|
||||
@ -996,8 +1009,8 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)
|
||||
port->flags = ((port->flags & ~ASYNC_FLAGS) |
|
||||
(ss->flags & ASYNC_FLAGS));
|
||||
state->custom_divisor = ss->custom_divisor;
|
||||
port->close_delay = ss->close_delay * HZ/100;
|
||||
port->closing_wait = ss->closing_wait * HZ/100;
|
||||
port->close_delay = close_delay;
|
||||
port->closing_wait = closing_wait;
|
||||
|
||||
check_and_exit:
|
||||
if (tty_port_initialized(port)) {
|
||||
@ -1622,21 +1635,17 @@ static int __init amiga_serial_probe(struct platform_device *pdev)
|
||||
|
||||
static int __exit amiga_serial_remove(struct platform_device *pdev)
|
||||
{
|
||||
int error;
|
||||
struct serial_state *state = platform_get_drvdata(pdev);
|
||||
|
||||
/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
|
||||
error = tty_unregister_driver(serial_driver);
|
||||
if (error)
|
||||
printk("SERIAL: failed to unregister serial driver (%d)\n",
|
||||
error);
|
||||
tty_unregister_driver(serial_driver);
|
||||
put_tty_driver(serial_driver);
|
||||
tty_port_destroy(&state->tport);
|
||||
|
||||
free_irq(IRQ_AMIGA_TBE, state);
|
||||
free_irq(IRQ_AMIGA_RBF, state);
|
||||
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver amiga_serial_driver = {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@
|
||||
|
||||
#include "hvc_console.h"
|
||||
|
||||
struct hvc_struct *hvc_udbg_dev;
|
||||
static struct hvc_struct *hvc_udbg_dev;
|
||||
|
||||
static int hvc_udbg_put(uint32_t vtermno, const char *buf, int count)
|
||||
{
|
||||
|
@ -290,35 +290,11 @@ static LIST_HEAD(hvcs_structs);
|
||||
static DEFINE_SPINLOCK(hvcs_structs_lock);
|
||||
static DEFINE_MUTEX(hvcs_init_mutex);
|
||||
|
||||
static void hvcs_unthrottle(struct tty_struct *tty);
|
||||
static void hvcs_throttle(struct tty_struct *tty);
|
||||
static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance);
|
||||
|
||||
static int hvcs_write(struct tty_struct *tty,
|
||||
const unsigned char *buf, int count);
|
||||
static int hvcs_write_room(struct tty_struct *tty);
|
||||
static int hvcs_chars_in_buffer(struct tty_struct *tty);
|
||||
|
||||
static int hvcs_has_pi(struct hvcs_struct *hvcsd);
|
||||
static void hvcs_set_pi(struct hvcs_partner_info *pi,
|
||||
struct hvcs_struct *hvcsd);
|
||||
static int hvcs_get_pi(struct hvcs_struct *hvcsd);
|
||||
static int hvcs_rescan_devices_list(void);
|
||||
|
||||
static int hvcs_partner_connect(struct hvcs_struct *hvcsd);
|
||||
static void hvcs_partner_free(struct hvcs_struct *hvcsd);
|
||||
|
||||
static int hvcs_enable_device(struct hvcs_struct *hvcsd,
|
||||
uint32_t unit_address, unsigned int irq, struct vio_dev *dev);
|
||||
|
||||
static int hvcs_open(struct tty_struct *tty, struct file *filp);
|
||||
static void hvcs_close(struct tty_struct *tty, struct file *filp);
|
||||
static void hvcs_hangup(struct tty_struct * tty);
|
||||
|
||||
static int hvcs_probe(struct vio_dev *dev,
|
||||
const struct vio_device_id *id);
|
||||
static int __init hvcs_module_init(void);
|
||||
static void __exit hvcs_module_exit(void);
|
||||
static int hvcs_initialize(void);
|
||||
|
||||
#define HVCS_SCHED_READ 0x00000001
|
||||
|
@ -235,10 +235,10 @@ static int ipw_write_room(struct tty_struct *linux_tty)
|
||||
|
||||
/* FIXME: Exactly how is the tty object locked here .. */
|
||||
if (!tty)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
|
||||
if (!tty->port.count)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
|
||||
if (room < 0)
|
||||
@ -596,13 +596,8 @@ int ipwireless_tty_init(void)
|
||||
|
||||
void ipwireless_tty_release(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = tty_unregister_driver(ipw_tty_driver);
|
||||
tty_unregister_driver(ipw_tty_driver);
|
||||
put_tty_driver(ipw_tty_driver);
|
||||
if (ret != 0)
|
||||
printk(KERN_ERR IPWIRELESS_PCCARD_NAME
|
||||
": tty_unregister_driver failed with code %d\n", ret);
|
||||
}
|
||||
|
||||
int ipwireless_tty_is_modem(struct ipw_tty *tty)
|
||||
|
1699
drivers/tty/isicom.c
1699
drivers/tty/isicom.c
File diff suppressed because it is too large
Load Diff
@ -1118,9 +1118,7 @@ static void __exit moxa_exit(void)
|
||||
|
||||
del_timer_sync(&moxaTimer);
|
||||
|
||||
if (tty_unregister_driver(moxaDriver))
|
||||
printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
|
||||
"serial driver\n");
|
||||
tty_unregister_driver(moxaDriver);
|
||||
put_tty_driver(moxaDriver);
|
||||
}
|
||||
|
||||
@ -2040,7 +2038,7 @@ static int moxa_get_serial_info(struct tty_struct *tty,
|
||||
ss->line = info->port.tty->index,
|
||||
ss->flags = info->port.flags,
|
||||
ss->baud_base = 921600,
|
||||
ss->close_delay = info->port.close_delay;
|
||||
ss->close_delay = jiffies_to_msecs(info->port.close_delay) / 10;
|
||||
mutex_unlock(&info->port.mutex);
|
||||
return 0;
|
||||
}
|
||||
@ -2050,30 +2048,31 @@ static int moxa_set_serial_info(struct tty_struct *tty,
|
||||
struct serial_struct *ss)
|
||||
{
|
||||
struct moxa_port *info = tty->driver_data;
|
||||
unsigned int close_delay;
|
||||
|
||||
if (tty->index == MAX_PORTS)
|
||||
return -EINVAL;
|
||||
if (!info)
|
||||
return -ENODEV;
|
||||
|
||||
if (ss->irq != 0 || ss->port != 0 ||
|
||||
ss->custom_divisor != 0 ||
|
||||
ss->baud_base != 921600)
|
||||
return -EPERM;
|
||||
close_delay = msecs_to_jiffies(ss->close_delay * 10);
|
||||
|
||||
mutex_lock(&info->port.mutex);
|
||||
if (!capable(CAP_SYS_ADMIN)) {
|
||||
if (((ss->flags & ~ASYNC_USR_MASK) !=
|
||||
if (close_delay != info->port.close_delay ||
|
||||
ss->type != info->type ||
|
||||
((ss->flags & ~ASYNC_USR_MASK) !=
|
||||
(info->port.flags & ~ASYNC_USR_MASK))) {
|
||||
mutex_unlock(&info->port.mutex);
|
||||
return -EPERM;
|
||||
}
|
||||
} else {
|
||||
info->port.close_delay = close_delay;
|
||||
|
||||
MoxaSetFifo(info, ss->type == PORT_16550A);
|
||||
|
||||
info->type = ss->type;
|
||||
}
|
||||
info->port.close_delay = ss->close_delay * HZ / 100;
|
||||
|
||||
MoxaSetFifo(info, ss->type == PORT_16550A);
|
||||
|
||||
info->type = ss->type;
|
||||
mutex_unlock(&info->port.mutex);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1208,19 +1208,26 @@ static int mxser_get_serial_info(struct tty_struct *tty,
|
||||
{
|
||||
struct mxser_port *info = tty->driver_data;
|
||||
struct tty_port *port = &info->port;
|
||||
unsigned int closing_wait, close_delay;
|
||||
|
||||
if (tty->index == MXSER_PORTS)
|
||||
return -ENOTTY;
|
||||
|
||||
mutex_lock(&port->mutex);
|
||||
|
||||
close_delay = jiffies_to_msecs(info->port.close_delay) / 10;
|
||||
closing_wait = info->port.closing_wait;
|
||||
if (closing_wait != ASYNC_CLOSING_WAIT_NONE)
|
||||
closing_wait = jiffies_to_msecs(closing_wait) / 10;
|
||||
|
||||
ss->type = info->type,
|
||||
ss->line = tty->index,
|
||||
ss->port = info->ioaddr,
|
||||
ss->irq = info->board->irq,
|
||||
ss->flags = info->port.flags,
|
||||
ss->baud_base = info->baud_base,
|
||||
ss->close_delay = info->port.close_delay,
|
||||
ss->closing_wait = info->port.closing_wait,
|
||||
ss->close_delay = close_delay;
|
||||
ss->closing_wait = closing_wait;
|
||||
ss->custom_divisor = info->custom_divisor,
|
||||
mutex_unlock(&port->mutex);
|
||||
return 0;
|
||||
@ -1233,7 +1240,7 @@ static int mxser_set_serial_info(struct tty_struct *tty,
|
||||
struct tty_port *port = &info->port;
|
||||
speed_t baud;
|
||||
unsigned long sl_flags;
|
||||
unsigned int flags;
|
||||
unsigned int flags, close_delay, closing_wait;
|
||||
int retval = 0;
|
||||
|
||||
if (tty->index == MXSER_PORTS)
|
||||
@ -1255,9 +1262,15 @@ static int mxser_set_serial_info(struct tty_struct *tty,
|
||||
|
||||
flags = port->flags & ASYNC_SPD_MASK;
|
||||
|
||||
close_delay = msecs_to_jiffies(ss->close_delay * 10);
|
||||
closing_wait = ss->closing_wait;
|
||||
if (closing_wait != ASYNC_CLOSING_WAIT_NONE)
|
||||
closing_wait = msecs_to_jiffies(closing_wait * 10);
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN)) {
|
||||
if ((ss->baud_base != info->baud_base) ||
|
||||
(ss->close_delay != info->port.close_delay) ||
|
||||
(close_delay != info->port.close_delay) ||
|
||||
(closing_wait != info->port.closing_wait) ||
|
||||
((ss->flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) {
|
||||
mutex_unlock(&port->mutex);
|
||||
return -EPERM;
|
||||
@ -1271,8 +1284,8 @@ static int mxser_set_serial_info(struct tty_struct *tty,
|
||||
*/
|
||||
port->flags = ((port->flags & ~ASYNC_FLAGS) |
|
||||
(ss->flags & ASYNC_FLAGS));
|
||||
port->close_delay = ss->close_delay * HZ / 100;
|
||||
port->closing_wait = ss->closing_wait * HZ / 100;
|
||||
port->close_delay = close_delay;
|
||||
port->closing_wait = closing_wait;
|
||||
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
|
||||
(ss->baud_base != info->baud_base ||
|
||||
ss->custom_divisor !=
|
||||
@ -1284,12 +1297,12 @@ static int mxser_set_serial_info(struct tty_struct *tty,
|
||||
baud = ss->baud_base / ss->custom_divisor;
|
||||
tty_encode_baud_rate(tty, baud, baud);
|
||||
}
|
||||
|
||||
info->type = ss->type;
|
||||
|
||||
process_txrx_fifo(info);
|
||||
}
|
||||
|
||||
info->type = ss->type;
|
||||
|
||||
process_txrx_fifo(info);
|
||||
|
||||
if (tty_port_initialized(port)) {
|
||||
if (flags != (port->flags & ASYNC_SPD_MASK)) {
|
||||
spin_lock_irqsave(&info->slock, sl_flags);
|
||||
@ -2142,14 +2155,7 @@ static void mxser_receive_chars(struct tty_struct *tty,
|
||||
port->mon_data.rxcnt += cnt;
|
||||
port->mon_data.up_rxcnt += cnt;
|
||||
|
||||
/*
|
||||
* We are called from an interrupt context with &port->slock
|
||||
* being held. Drop it temporarily in order to prevent
|
||||
* recursive locking.
|
||||
*/
|
||||
spin_unlock(&port->slock);
|
||||
tty_flip_buffer_push(&port->port);
|
||||
spin_lock(&port->slock);
|
||||
}
|
||||
|
||||
static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port)
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/gsmmux.h>
|
||||
#include "tty.h"
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0600);
|
||||
@ -266,7 +267,7 @@ struct gsm_mux {
|
||||
|
||||
#define MAX_MUX 4 /* 256 minors */
|
||||
static struct gsm_mux *gsm_mux[MAX_MUX]; /* GSM muxes */
|
||||
static spinlock_t gsm_mux_lock;
|
||||
static DEFINE_SPINLOCK(gsm_mux_lock);
|
||||
|
||||
static struct tty_driver *gsm_tty_driver;
|
||||
|
||||
@ -2384,8 +2385,18 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
|
||||
/* Don't register device 0 - this is the control channel and not
|
||||
a usable tty interface */
|
||||
base = mux_num_to_base(gsm); /* Base for this MUX */
|
||||
for (i = 1; i < NUM_DLCI; i++)
|
||||
tty_register_device(gsm_tty_driver, base + i, NULL);
|
||||
for (i = 1; i < NUM_DLCI; i++) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tty_register_device(gsm_tty_driver,
|
||||
base + i, NULL);
|
||||
if (IS_ERR(dev)) {
|
||||
for (i--; i >= 1; i--)
|
||||
tty_unregister_device(gsm_tty_driver,
|
||||
base + i);
|
||||
return PTR_ERR(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -2416,27 +2427,24 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char *fp, int count)
|
||||
{
|
||||
struct gsm_mux *gsm = tty->disc_data;
|
||||
const unsigned char *dp;
|
||||
char *f;
|
||||
int i;
|
||||
char flags = TTY_NORMAL;
|
||||
|
||||
if (debug & 4)
|
||||
print_hex_dump_bytes("gsmld_receive: ", DUMP_PREFIX_OFFSET,
|
||||
cp, count);
|
||||
|
||||
for (i = count, dp = cp, f = fp; i; i--, dp++) {
|
||||
if (f)
|
||||
flags = *f++;
|
||||
for (; count; count--, cp++) {
|
||||
if (fp)
|
||||
flags = *fp++;
|
||||
switch (flags) {
|
||||
case TTY_NORMAL:
|
||||
gsm->receive(gsm, *dp);
|
||||
gsm->receive(gsm, *cp);
|
||||
break;
|
||||
case TTY_OVERRUN:
|
||||
case TTY_BREAK:
|
||||
case TTY_PARITY:
|
||||
case TTY_FRAME:
|
||||
gsm_error(gsm, *dp, flags);
|
||||
gsm_error(gsm, *cp, flags);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "%s: unknown flag %d\n",
|
||||
@ -2849,7 +2857,6 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc)
|
||||
/* Line discipline for real tty */
|
||||
static struct tty_ldisc_ops tty_ldisc_packet = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "n_gsm",
|
||||
.open = gsmld_open,
|
||||
.close = gsmld_close,
|
||||
@ -3052,7 +3059,7 @@ static int gsmtty_write_room(struct tty_struct *tty)
|
||||
{
|
||||
struct gsm_dlci *dlci = tty->driver_data;
|
||||
if (dlci->state == DLCI_CLOSED)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return TX_SIZE - kfifo_len(&dlci->fifo);
|
||||
}
|
||||
|
||||
@ -3060,7 +3067,7 @@ static int gsmtty_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct gsm_dlci *dlci = tty->driver_data;
|
||||
if (dlci->state == DLCI_CLOSED)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return kfifo_len(&dlci->fifo);
|
||||
}
|
||||
|
||||
@ -3261,8 +3268,6 @@ static int __init gsm_init(void)
|
||||
gsm_tty_driver->init_termios.c_lflag &= ~ECHO;
|
||||
tty_set_operations(gsm_tty_driver, &gsmtty_ops);
|
||||
|
||||
spin_lock_init(&gsm_mux_lock);
|
||||
|
||||
if (tty_register_driver(gsm_tty_driver)) {
|
||||
put_tty_driver(gsm_tty_driver);
|
||||
tty_unregister_ldisc(N_GSM0710);
|
||||
|
@ -100,6 +100,7 @@
|
||||
|
||||
#include <asm/termios.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include "tty.h"
|
||||
|
||||
/*
|
||||
* Buffers for individual HDLC frames
|
||||
@ -787,7 +788,6 @@ static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *buf_list)
|
||||
|
||||
static struct tty_ldisc_ops n_hdlc_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "hdlc",
|
||||
.open = n_hdlc_tty_open,
|
||||
.close = n_hdlc_tty_close,
|
||||
|
@ -40,7 +40,6 @@ static void n_null_receivebuf(struct tty_struct *tty,
|
||||
|
||||
static struct tty_ldisc_ops null_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "n_null",
|
||||
.open = n_null_open,
|
||||
.close = n_null_close,
|
||||
|
@ -146,7 +146,6 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
|
||||
static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = "R3964",
|
||||
.open = r3964_open,
|
||||
.close = r3964_close,
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include "tty.h"
|
||||
|
||||
/*
|
||||
* Until this number of characters is queued in the xmit buffer, select will
|
||||
@ -2488,7 +2489,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
|
||||
}
|
||||
|
||||
static struct tty_ldisc_ops n_tty_ops = {
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.owner = THIS_MODULE,
|
||||
.name = "n_tty",
|
||||
.open = n_tty_open,
|
||||
.close = n_tty_close,
|
||||
|
@ -47,9 +47,6 @@
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
#define VERSION_STRING DRIVER_DESC " 2.1d"
|
||||
|
||||
/* Default debug printout level */
|
||||
#define NOZOMI_DEBUG_LEVEL 0x00
|
||||
static int debug = NOZOMI_DEBUG_LEVEL;
|
||||
@ -89,7 +86,6 @@ do { \
|
||||
/* Defines */
|
||||
#define NOZOMI_NAME "nozomi"
|
||||
#define NOZOMI_NAME_TTY "nozomi_tty"
|
||||
#define DRIVER_DESC "Nozomi driver"
|
||||
|
||||
#define NTTY_TTY_MAXMINORS 256
|
||||
#define NTTY_FIFO_BUFFER_SIZE 8192
|
||||
@ -359,12 +355,6 @@ struct nozomi {
|
||||
u32 open_ttys;
|
||||
};
|
||||
|
||||
/* This is a data packet that is read or written to/from card */
|
||||
struct buffer {
|
||||
u32 size; /* size is the length of the data buffer */
|
||||
u8 *data;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Global variables */
|
||||
static const struct pci_device_id nozomi_pci_tbl[] = {
|
||||
{PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */
|
||||
@ -787,7 +777,6 @@ static int receive_data(enum port_type index, struct nozomi *dc)
|
||||
int i, ret;
|
||||
|
||||
size = __le32_to_cpu(readl(addr));
|
||||
/* DBG1( "%d bytes port: %d", size, index); */
|
||||
|
||||
if (tty && tty_throttled(tty)) {
|
||||
DBG1("No room in tty, don't read data, don't ack interrupt, "
|
||||
@ -1318,8 +1307,6 @@ static int nozomi_card_init(struct pci_dev *pdev,
|
||||
int ndev_idx;
|
||||
int i;
|
||||
|
||||
dev_dbg(&pdev->dev, "Init, new card found\n");
|
||||
|
||||
for (ndev_idx = 0; ndev_idx < ARRAY_SIZE(ndevs); ndev_idx++)
|
||||
if (!ndevs[ndev_idx])
|
||||
break;
|
||||
@ -1453,8 +1440,6 @@ static void tty_exit(struct nozomi *dc)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
DBG1(" ");
|
||||
|
||||
for (i = 0; i < MAX_PORT; ++i)
|
||||
tty_port_tty_hangup(&dc->port[i].port, false);
|
||||
|
||||
@ -1619,8 +1604,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
|
||||
struct port *port = tty->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
/* DBG1( "WRITEx: %d, index = %d", count, index); */
|
||||
|
||||
if (!dc || !port)
|
||||
return -ENODEV;
|
||||
|
||||
@ -1746,8 +1729,6 @@ static int ntty_ioctl(struct tty_struct *tty,
|
||||
struct port *port = tty->driver_data;
|
||||
int rval = -ENOIOCTLCMD;
|
||||
|
||||
DBG1("******** IOCTL, cmd: %d", cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case TIOCMIWAIT: {
|
||||
struct async_icount cprev = port->tty_icount;
|
||||
@ -1773,7 +1754,6 @@ static void ntty_unthrottle(struct tty_struct *tty)
|
||||
struct nozomi *dc = get_dc_by_tty(tty);
|
||||
unsigned long flags;
|
||||
|
||||
DBG1("UNTHROTTLE");
|
||||
spin_lock_irqsave(&dc->spin_mutex, flags);
|
||||
enable_transmit_dl(tty->index % MAX_PORT, dc);
|
||||
set_rts(tty, 1);
|
||||
@ -1790,7 +1770,6 @@ static void ntty_throttle(struct tty_struct *tty)
|
||||
struct nozomi *dc = get_dc_by_tty(tty);
|
||||
unsigned long flags;
|
||||
|
||||
DBG1("THROTTLE");
|
||||
spin_lock_irqsave(&dc->spin_mutex, flags);
|
||||
set_rts(tty, 0);
|
||||
spin_unlock_irqrestore(&dc->spin_mutex, flags);
|
||||
@ -1847,8 +1826,6 @@ static __init int nozomi_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "Initializing %s\n", VERSION_STRING);
|
||||
|
||||
ntty_driver = alloc_tty_driver(NTTY_TTY_MAXMINORS);
|
||||
if (!ntty_driver)
|
||||
return -ENOMEM;
|
||||
@ -1888,7 +1865,6 @@ static __init int nozomi_init(void)
|
||||
|
||||
static __exit void nozomi_exit(void)
|
||||
{
|
||||
printk(KERN_INFO "Unloading %s\n", DRIVER_DESC);
|
||||
pci_unregister_driver(&nozomi_driver);
|
||||
tty_unregister_driver(ntty_driver);
|
||||
put_tty_driver(ntty_driver);
|
||||
@ -1898,4 +1874,4 @@ module_init(nozomi_init);
|
||||
module_exit(nozomi_exit);
|
||||
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_DESCRIPTION("Nozomi driver");
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <linux/file.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/compat.h>
|
||||
#include "tty.h"
|
||||
|
||||
#undef TTY_DEBUG_HANGUP
|
||||
#ifdef TTY_DEBUG_HANGUP
|
||||
@ -159,6 +160,7 @@ static int pty_chars_in_buffer(struct tty_struct *tty)
|
||||
static int pty_set_lock(struct tty_struct *tty, int __user *arg)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (get_user(val, arg))
|
||||
return -EFAULT;
|
||||
if (val)
|
||||
@ -171,6 +173,7 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg)
|
||||
static int pty_get_lock(struct tty_struct *tty, int __user *arg)
|
||||
{
|
||||
int locked = test_bit(TTY_PTY_LOCK, &tty->flags);
|
||||
|
||||
return put_user(locked, arg);
|
||||
}
|
||||
|
||||
@ -200,6 +203,7 @@ static int pty_set_pktmode(struct tty_struct *tty, int __user *arg)
|
||||
static int pty_get_pktmode(struct tty_struct *tty, int __user *arg)
|
||||
{
|
||||
int pktmode = tty->packet;
|
||||
|
||||
return put_user(pktmode, arg);
|
||||
}
|
||||
|
||||
@ -463,6 +467,7 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
|
||||
static void pty_remove(struct tty_driver *driver, struct tty_struct *tty)
|
||||
{
|
||||
struct tty_struct *pair = tty->link;
|
||||
|
||||
driver->ttys[tty->index] = NULL;
|
||||
if (pair)
|
||||
pair->driver->ttys[pair->index] = NULL;
|
||||
|
3127
drivers/tty/rocket.c
3127
drivers/tty/rocket.c
File diff suppressed because it is too large
Load Diff
@ -1,111 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* rocket.h --- the exported interface of the rocket driver to its configuration program.
|
||||
*
|
||||
* Written by Theodore Ts'o, Copyright 1997.
|
||||
* Copyright 1997 Comtrol Corporation.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Model Information Struct */
|
||||
typedef struct {
|
||||
unsigned long model;
|
||||
char modelString[80];
|
||||
unsigned long numPorts;
|
||||
int loadrm2;
|
||||
int startingPortNumber;
|
||||
} rocketModel_t;
|
||||
|
||||
struct rocket_config {
|
||||
int line;
|
||||
int flags;
|
||||
int closing_wait;
|
||||
int close_delay;
|
||||
int port;
|
||||
int reserved[32];
|
||||
};
|
||||
|
||||
struct rocket_ports {
|
||||
int tty_major;
|
||||
int callout_major;
|
||||
rocketModel_t rocketModel[8];
|
||||
};
|
||||
|
||||
struct rocket_version {
|
||||
char rocket_version[32];
|
||||
char rocket_date[32];
|
||||
char reserved[64];
|
||||
};
|
||||
|
||||
/*
|
||||
* Rocketport flags
|
||||
*/
|
||||
/*#define ROCKET_CALLOUT_NOHUP 0x00000001 */
|
||||
#define ROCKET_FORCE_CD 0x00000002
|
||||
#define ROCKET_HUP_NOTIFY 0x00000004
|
||||
#define ROCKET_SPLIT_TERMIOS 0x00000008
|
||||
#define ROCKET_SPD_MASK 0x00000070
|
||||
#define ROCKET_SPD_HI 0x00000010 /* Use 57600 instead of 38400 bps */
|
||||
#define ROCKET_SPD_VHI 0x00000020 /* Use 115200 instead of 38400 bps */
|
||||
#define ROCKET_SPD_SHI 0x00000030 /* Use 230400 instead of 38400 bps */
|
||||
#define ROCKET_SPD_WARP 0x00000040 /* Use 460800 instead of 38400 bps */
|
||||
#define ROCKET_SAK 0x00000080
|
||||
#define ROCKET_SESSION_LOCKOUT 0x00000100
|
||||
#define ROCKET_PGRP_LOCKOUT 0x00000200
|
||||
#define ROCKET_RTS_TOGGLE 0x00000400
|
||||
#define ROCKET_MODE_MASK 0x00003000
|
||||
#define ROCKET_MODE_RS232 0x00000000
|
||||
#define ROCKET_MODE_RS485 0x00001000
|
||||
#define ROCKET_MODE_RS422 0x00002000
|
||||
#define ROCKET_FLAGS 0x00003FFF
|
||||
|
||||
#define ROCKET_USR_MASK 0x0071 /* Legal flags that non-privileged
|
||||
* users can set or reset */
|
||||
|
||||
/*
|
||||
* For closing_wait and closing_wait2
|
||||
*/
|
||||
#define ROCKET_CLOSING_WAIT_NONE ASYNC_CLOSING_WAIT_NONE
|
||||
#define ROCKET_CLOSING_WAIT_INF ASYNC_CLOSING_WAIT_INF
|
||||
|
||||
/*
|
||||
* Rocketport ioctls -- "RP"
|
||||
*/
|
||||
#define RCKP_GET_CONFIG 0x00525002
|
||||
#define RCKP_SET_CONFIG 0x00525003
|
||||
#define RCKP_GET_PORTS 0x00525004
|
||||
#define RCKP_RESET_RM2 0x00525005
|
||||
#define RCKP_GET_VERSION 0x00525006
|
||||
|
||||
/* Rocketport Models */
|
||||
#define MODEL_RP32INTF 0x0001 /* RP 32 port w/external I/F */
|
||||
#define MODEL_RP8INTF 0x0002 /* RP 8 port w/external I/F */
|
||||
#define MODEL_RP16INTF 0x0003 /* RP 16 port w/external I/F */
|
||||
#define MODEL_RP8OCTA 0x0005 /* RP 8 port w/octa cable */
|
||||
#define MODEL_RP4QUAD 0x0004 /* RP 4 port w/quad cable */
|
||||
#define MODEL_RP8J 0x0006 /* RP 8 port w/RJ11 connectors */
|
||||
#define MODEL_RP4J 0x0007 /* RP 4 port w/RJ45 connectors */
|
||||
#define MODEL_RP8SNI 0x0008 /* RP 8 port w/ DB78 SNI connector */
|
||||
#define MODEL_RP16SNI 0x0009 /* RP 16 port w/ DB78 SNI connector */
|
||||
#define MODEL_RPP4 0x000A /* RP Plus 4 port */
|
||||
#define MODEL_RPP8 0x000B /* RP Plus 8 port */
|
||||
#define MODEL_RP2_232 0x000E /* RP Plus 2 port RS232 */
|
||||
#define MODEL_RP2_422 0x000F /* RP Plus 2 port RS232 */
|
||||
|
||||
/* Rocketmodem II Models */
|
||||
#define MODEL_RP6M 0x000C /* RM 6 port */
|
||||
#define MODEL_RP4M 0x000D /* RM 4 port */
|
||||
|
||||
/* Universal PCI boards */
|
||||
#define MODEL_UPCI_RP32INTF 0x0801 /* RP UPCI 32 port w/external I/F */
|
||||
#define MODEL_UPCI_RP8INTF 0x0802 /* RP UPCI 8 port w/external I/F */
|
||||
#define MODEL_UPCI_RP16INTF 0x0803 /* RP UPCI 16 port w/external I/F */
|
||||
#define MODEL_UPCI_RP8OCTA 0x0805 /* RP UPCI 8 port w/octa cable */
|
||||
#define MODEL_UPCI_RM3_8PORT 0x080C /* RP UPCI Rocketmodem III 8 port */
|
||||
#define MODEL_UPCI_RM3_4PORT 0x080C /* RP UPCI Rocketmodem III 4 port */
|
||||
|
||||
/* Compact PCI 16 port */
|
||||
#define MODEL_CPCI_RP16INTF 0x0903 /* RP Compact PCI 16 port w/external I/F */
|
||||
|
||||
/* All ISA boards */
|
||||
#define MODEL_ISA 0x1000
|
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,10 @@
|
||||
#define ASPEED_VUART_ADDRL 0x28
|
||||
#define ASPEED_VUART_ADDRH 0x2c
|
||||
|
||||
#define ASPEED_VUART_DEFAULT_LPC_ADDR 0x3f8
|
||||
#define ASPEED_VUART_DEFAULT_SIRQ 4
|
||||
#define ASPEED_VUART_DEFAULT_SIRQ_POLARITY IRQ_TYPE_LEVEL_LOW
|
||||
|
||||
struct aspeed_vuart {
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
@ -72,22 +76,31 @@ static ssize_t lpc_address_show(struct device *dev,
|
||||
return snprintf(buf, PAGE_SIZE - 1, "0x%x\n", addr);
|
||||
}
|
||||
|
||||
static int aspeed_vuart_set_lpc_address(struct aspeed_vuart *vuart, u32 addr)
|
||||
{
|
||||
if (addr > U16_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
writeb(addr >> 8, vuart->regs + ASPEED_VUART_ADDRH);
|
||||
writeb(addr >> 0, vuart->regs + ASPEED_VUART_ADDRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t lpc_address_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct aspeed_vuart *vuart = dev_get_drvdata(dev);
|
||||
unsigned long val;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
err = kstrtoul(buf, 0, &val);
|
||||
err = kstrtou32(buf, 0, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
writeb(val >> 8, vuart->regs + ASPEED_VUART_ADDRH);
|
||||
writeb(val >> 0, vuart->regs + ASPEED_VUART_ADDRL);
|
||||
|
||||
return count;
|
||||
err = aspeed_vuart_set_lpc_address(vuart, val);
|
||||
return err ? : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(lpc_address);
|
||||
@ -105,27 +118,37 @@ static ssize_t sirq_show(struct device *dev,
|
||||
return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg);
|
||||
}
|
||||
|
||||
static int aspeed_vuart_set_sirq(struct aspeed_vuart *vuart, u32 sirq)
|
||||
{
|
||||
u8 reg;
|
||||
|
||||
if (sirq > (ASPEED_VUART_GCRB_HOST_SIRQ_MASK >> ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT))
|
||||
return -EINVAL;
|
||||
|
||||
sirq <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT;
|
||||
sirq &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
|
||||
|
||||
reg = readb(vuart->regs + ASPEED_VUART_GCRB);
|
||||
reg &= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
|
||||
reg |= sirq;
|
||||
writeb(reg, vuart->regs + ASPEED_VUART_GCRB);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t sirq_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct aspeed_vuart *vuart = dev_get_drvdata(dev);
|
||||
unsigned long val;
|
||||
int err;
|
||||
u8 reg;
|
||||
|
||||
err = kstrtoul(buf, 0, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT;
|
||||
val &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
|
||||
|
||||
reg = readb(vuart->regs + ASPEED_VUART_GCRB);
|
||||
reg &= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
|
||||
reg |= val;
|
||||
writeb(reg, vuart->regs + ASPEED_VUART_GCRB);
|
||||
|
||||
return count;
|
||||
err = aspeed_vuart_set_sirq(vuart, val);
|
||||
return err ? : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(sirq);
|
||||
@ -297,7 +320,6 @@ static int aspeed_vuart_handle_irq(struct uart_port *port)
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
unsigned int iir, lsr;
|
||||
unsigned long flags;
|
||||
int space, count;
|
||||
|
||||
iir = serial_port_in(port, UART_IIR);
|
||||
@ -305,7 +327,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);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
lsr = serial_port_in(port, UART_LSR);
|
||||
|
||||
@ -341,7 +363,7 @@ static int aspeed_vuart_handle_irq(struct uart_port *port)
|
||||
if (lsr & UART_LSR_THRE)
|
||||
serial8250_tx_chars(up);
|
||||
|
||||
uart_unlock_and_check_sysrq(port, flags);
|
||||
uart_unlock_and_check_sysrq(port);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -367,6 +389,18 @@ static void aspeed_vuart_auto_configure_sirq_polarity(
|
||||
aspeed_vuart_set_sirq_polarity(vuart, (value & reg_mask) == 0);
|
||||
}
|
||||
|
||||
static int aspeed_vuart_map_irq_polarity(u32 dt)
|
||||
{
|
||||
switch (dt) {
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
return 0;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
return 1;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int aspeed_vuart_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct of_phandle_args sirq_polarity_sense_args;
|
||||
@ -374,8 +408,8 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
|
||||
struct aspeed_vuart *vuart;
|
||||
struct device_node *np;
|
||||
struct resource *res;
|
||||
u32 clk, prop;
|
||||
int rc;
|
||||
u32 clk, prop, sirq[2];
|
||||
int rc, sirq_polarity;
|
||||
|
||||
np = pdev->dev.of_node;
|
||||
|
||||
@ -482,6 +516,37 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
|
||||
of_node_put(sirq_polarity_sense_args.np);
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(np, "aspeed,lpc-io-reg", &prop);
|
||||
if (rc < 0)
|
||||
prop = ASPEED_VUART_DEFAULT_LPC_ADDR;
|
||||
|
||||
rc = aspeed_vuart_set_lpc_address(vuart, prop);
|
||||
if (rc < 0) {
|
||||
dev_err(&pdev->dev, "invalid value in aspeed,lpc-io-reg property\n");
|
||||
goto err_clk_disable;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(np, "aspeed,lpc-interrupts", sirq, 2);
|
||||
if (rc < 0) {
|
||||
sirq[0] = ASPEED_VUART_DEFAULT_SIRQ;
|
||||
sirq[1] = ASPEED_VUART_DEFAULT_SIRQ_POLARITY;
|
||||
}
|
||||
|
||||
rc = aspeed_vuart_set_sirq(vuart, sirq[0]);
|
||||
if (rc < 0) {
|
||||
dev_err(&pdev->dev, "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;
|
||||
goto err_clk_disable;
|
||||
}
|
||||
|
||||
aspeed_vuart_set_sirq_polarity(vuart, sirq_polarity);
|
||||
|
||||
aspeed_vuart_set_enabled(vuart, true);
|
||||
aspeed_vuart_set_host_tx_discard(vuart, true);
|
||||
platform_set_drvdata(pdev, vuart);
|
||||
|
1202
drivers/tty/serial/8250/8250_bcm7271.c
Normal file
1202
drivers/tty/serial/8250/8250_bcm7271.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -354,7 +354,7 @@ static void setup_gpio(struct pci_dev *pcidev, u8 __iomem *p)
|
||||
|
||||
static void *
|
||||
__xr17v35x_register_gpio(struct pci_dev *pcidev,
|
||||
const struct property_entry *properties)
|
||||
const struct software_node *node)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
|
||||
@ -365,7 +365,7 @@ __xr17v35x_register_gpio(struct pci_dev *pcidev,
|
||||
pdev->dev.parent = &pcidev->dev;
|
||||
ACPI_COMPANION_SET(&pdev->dev, ACPI_COMPANION(&pcidev->dev));
|
||||
|
||||
if (platform_device_add_properties(pdev, properties) < 0 ||
|
||||
if (device_add_software_node(&pdev->dev, node) < 0 ||
|
||||
platform_device_add(pdev) < 0) {
|
||||
platform_device_put(pdev);
|
||||
return NULL;
|
||||
@ -380,12 +380,16 @@ static const struct property_entry exar_gpio_properties[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node exar_gpio_node = {
|
||||
.properties = exar_gpio_properties,
|
||||
};
|
||||
|
||||
static int xr17v35x_register_gpio(struct pci_dev *pcidev,
|
||||
struct uart_8250_port *port)
|
||||
{
|
||||
if (pcidev->vendor == PCI_VENDOR_ID_EXAR)
|
||||
port->port.private_data =
|
||||
__xr17v35x_register_gpio(pcidev, exar_gpio_properties);
|
||||
__xr17v35x_register_gpio(pcidev, &exar_gpio_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -457,6 +461,10 @@ static const struct property_entry iot2040_gpio_properties[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node iot2040_gpio_node = {
|
||||
.properties = iot2040_gpio_properties,
|
||||
};
|
||||
|
||||
static int iot2040_register_gpio(struct pci_dev *pcidev,
|
||||
struct uart_8250_port *port)
|
||||
{
|
||||
@ -468,7 +476,7 @@ static int iot2040_register_gpio(struct pci_dev *pcidev,
|
||||
writeb(IOT2040_UARTS_GPIO_HI_MODE, p + UART_EXAR_MPIOSEL_15_8);
|
||||
|
||||
port->port.private_data =
|
||||
__xr17v35x_register_gpio(pcidev, iot2040_gpio_properties);
|
||||
__xr17v35x_register_gpio(pcidev, &iot2040_gpio_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -547,6 +555,7 @@ static void pci_xr17v35x_exit(struct pci_dev *pcidev)
|
||||
struct uart_8250_port *port = serial8250_get_port(priv->line[0]);
|
||||
struct platform_device *pdev = port->port.private_data;
|
||||
|
||||
device_remove_software_node(&pdev->dev);
|
||||
platform_device_unregister(pdev);
|
||||
port->port.private_data = NULL;
|
||||
}
|
||||
|
@ -30,15 +30,14 @@ struct fsl8250_data {
|
||||
int fsl8250_handle_irq(struct uart_port *port)
|
||||
{
|
||||
unsigned char lsr, orig_lsr;
|
||||
unsigned long flags;
|
||||
unsigned int iir;
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
|
||||
spin_lock_irqsave(&up->port.lock, flags);
|
||||
spin_lock(&up->port.lock);
|
||||
|
||||
iir = port->serial_in(port, UART_IIR);
|
||||
if (iir & UART_IIR_NO_INT) {
|
||||
spin_unlock_irqrestore(&up->port.lock, flags);
|
||||
spin_unlock(&up->port.lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -46,7 +45,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);
|
||||
spin_unlock(&up->port.lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -82,7 +81,9 @@ int fsl8250_handle_irq(struct uart_port *port)
|
||||
serial8250_tx_chars(up);
|
||||
|
||||
up->lsr_saved_flags = orig_lsr;
|
||||
uart_unlock_and_check_sysrq(&up->port, flags);
|
||||
|
||||
uart_unlock_and_check_sysrq(&up->port);
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsl8250_handle_irq);
|
||||
@ -104,11 +105,8 @@ static int fsl8250_acpi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
if (irq != -EPROBE_DEFER)
|
||||
dev_err(dev, "cannot get irq\n");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
memset(&port8250, 0, sizeof(port8250));
|
||||
|
||||
|
@ -318,6 +318,7 @@ static const struct of_device_id of_platform_serial_table[] = {
|
||||
{ .compatible = "mrvl,mmp-uart",
|
||||
.data = (void *)PORT_XSCALE, },
|
||||
{ .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, },
|
||||
{ .compatible = "nuvoton,wpcm450-uart", .data = (void *)PORT_NPCM, },
|
||||
{ .compatible = "nuvoton,npcm750-uart", .data = (void *)PORT_NPCM, },
|
||||
{ /* end of list */ },
|
||||
};
|
||||
|
@ -1143,7 +1143,6 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
struct omap8250_priv *priv = up->port.private_data;
|
||||
unsigned char status;
|
||||
unsigned long flags;
|
||||
u8 iir;
|
||||
|
||||
serial8250_rpm_get(up);
|
||||
@ -1154,7 +1153,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
status = serial_port_in(port, UART_LSR);
|
||||
|
||||
@ -1179,7 +1178,8 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
|
||||
}
|
||||
}
|
||||
|
||||
uart_unlock_and_check_sysrq(port, flags);
|
||||
uart_unlock_and_check_sysrq(port);
|
||||
|
||||
serial8250_rpm_put(up);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1466,13 +1466,11 @@ EXPORT_SYMBOL_GPL(serial8250_em485_stop_tx);
|
||||
|
||||
static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t)
|
||||
{
|
||||
struct uart_8250_em485 *em485;
|
||||
struct uart_8250_port *p;
|
||||
struct uart_8250_em485 *em485 = container_of(t, struct uart_8250_em485,
|
||||
stop_tx_timer);
|
||||
struct uart_8250_port *p = em485->port;
|
||||
unsigned long flags;
|
||||
|
||||
em485 = container_of(t, struct uart_8250_em485, stop_tx_timer);
|
||||
p = em485->port;
|
||||
|
||||
serial8250_rpm_get(p);
|
||||
spin_lock_irqsave(&p->port.lock, flags);
|
||||
if (em485->active_timer == &em485->stop_tx_timer) {
|
||||
@ -1482,16 +1480,13 @@ static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t)
|
||||
}
|
||||
spin_unlock_irqrestore(&p->port.lock, flags);
|
||||
serial8250_rpm_put(p);
|
||||
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
|
||||
{
|
||||
long sec = msec / 1000;
|
||||
long nsec = (msec % 1000) * 1000000;
|
||||
ktime_t t = ktime_set(sec, nsec);
|
||||
|
||||
hrtimer_start(hrt, t, HRTIMER_MODE_REL);
|
||||
hrtimer_start(hrt, ms_to_ktime(msec), HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
static void __stop_tx_rs485(struct uart_8250_port *p)
|
||||
@ -1633,19 +1628,18 @@ static inline void start_tx_rs485(struct uart_port *port)
|
||||
|
||||
static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t)
|
||||
{
|
||||
struct uart_8250_em485 *em485;
|
||||
struct uart_8250_port *p;
|
||||
struct uart_8250_em485 *em485 = container_of(t, struct uart_8250_em485,
|
||||
start_tx_timer);
|
||||
struct uart_8250_port *p = em485->port;
|
||||
unsigned long flags;
|
||||
|
||||
em485 = container_of(t, struct uart_8250_em485, start_tx_timer);
|
||||
p = em485->port;
|
||||
|
||||
spin_lock_irqsave(&p->port.lock, flags);
|
||||
if (em485->active_timer == &em485->start_tx_timer) {
|
||||
__start_tx(&p->port);
|
||||
em485->active_timer = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&p->port.lock, flags);
|
||||
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
@ -1885,14 +1879,13 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
|
||||
int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
|
||||
{
|
||||
unsigned char status;
|
||||
unsigned long flags;
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
bool skip_rx = false;
|
||||
|
||||
if (iir & UART_IIR_NO_INT)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
status = serial_port_in(port, UART_LSR);
|
||||
|
||||
@ -1918,7 +1911,8 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
|
||||
(up->ier & UART_IER_THRI))
|
||||
serial8250_tx_chars(up);
|
||||
|
||||
uart_unlock_and_check_sysrq(port, flags);
|
||||
uart_unlock_and_check_sysrq(port);
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_handle_irq);
|
||||
|
@ -15,8 +15,7 @@ config SERIAL_8250
|
||||
here are those that are setting up dedicated Ethernet WWW/FTP
|
||||
servers, or users that have one of the various bus mice instead of a
|
||||
serial mouse and don't intend to use their machine's standard serial
|
||||
port for anything. (Note that the Cyclades multi serial port driver
|
||||
does not need this driver built in for it to work.)
|
||||
port for anything.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called 8250.
|
||||
@ -226,7 +225,7 @@ config SERIAL_8250_MANY_PORTS
|
||||
serial port hardware which acts similar to standard serial port
|
||||
hardware. If you only use the standard COM 1/2/3/4 ports, you can
|
||||
say N here to save some memory. You can also say Y if you have an
|
||||
"intelligent" multiport card such as Cyclades, Digiboards, etc.
|
||||
"intelligent" multiport card such as Digiboards, etc.
|
||||
|
||||
#
|
||||
# Multi-port serial cards
|
||||
@ -404,7 +403,8 @@ config SERIAL_8250_RT288X
|
||||
|
||||
config SERIAL_8250_OMAP
|
||||
tristate "Support for OMAP internal UART (8250 based driver)"
|
||||
depends on SERIAL_8250 && (ARCH_OMAP2PLUS || ARCH_K3)
|
||||
depends on SERIAL_8250
|
||||
depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST
|
||||
help
|
||||
If you have a machine based on an Texas Instruments OMAP CPU you
|
||||
can enable its onboard serial ports by enabling this option.
|
||||
@ -440,7 +440,8 @@ config SERIAL_8250_LPC18XX
|
||||
|
||||
config SERIAL_8250_MT6577
|
||||
tristate "Mediatek serial port support"
|
||||
depends on SERIAL_8250 && ARCH_MEDIATEK
|
||||
depends on SERIAL_8250
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
help
|
||||
If you have a Mediatek based board and want to use the
|
||||
serial port, say Y to this option. If unsure, say N.
|
||||
@ -510,6 +511,16 @@ config SERIAL_8250_TEGRA
|
||||
Select this option if you have machine with an NVIDIA Tegra SoC and
|
||||
wish to enable 8250 serial driver for the Tegra serial interfaces.
|
||||
|
||||
config SERIAL_8250_BCM7271
|
||||
tristate "Broadcom 8250 based serial port"
|
||||
depends on SERIAL_8250 && (ARCH_BRCMSTB || COMPILE_TEST)
|
||||
default ARCH_BRCMSTB
|
||||
help
|
||||
If you have a Broadcom STB based board and want to use the
|
||||
enhanced features of the Broadcom 8250 based serial port,
|
||||
including DMA support and high accuracy BAUD rates, say
|
||||
Y to this option. If unsure, say N.
|
||||
|
||||
config SERIAL_OF_PLATFORM
|
||||
tristate "Devicetree based probing for 8250 ports"
|
||||
depends on SERIAL_8250 && OF
|
||||
|
@ -38,6 +38,7 @@ obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o
|
||||
obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
|
||||
obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.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
|
||||
|
@ -456,11 +456,11 @@ static int simple_config(struct pcmcia_device *link)
|
||||
* its base address, then try to grab any standard serial port
|
||||
* address, and finally try to get any free port.
|
||||
*/
|
||||
if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
|
||||
goto found_port;
|
||||
|
||||
dev_warn(&link->dev, "no usable port range found, giving up\n");
|
||||
return -1;
|
||||
ret = pcmcia_loop_config(link, simple_config_check_notpicky, NULL);
|
||||
if (ret) {
|
||||
dev_warn(&link->dev, "no usable port range found, giving up\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
found_port:
|
||||
if (info->multi && (info->manfid == MANFID_3COM))
|
||||
@ -474,7 +474,7 @@ static int simple_config(struct pcmcia_device *link)
|
||||
|
||||
ret = pcmcia_enable_device(link);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
return ret;
|
||||
return setup_serial(link, info, link->resource[0]->start, link->irq);
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ comment "Non-8250 serial port support"
|
||||
|
||||
config SERIAL_AMBA_PL010
|
||||
tristate "ARM AMBA PL010 serial port support"
|
||||
depends on ARM_AMBA
|
||||
depends on ARM_AMBA || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
help
|
||||
This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have
|
||||
@ -198,7 +198,7 @@ config SERIAL_KGDB_NMI
|
||||
|
||||
config SERIAL_MESON
|
||||
tristate "Meson serial port support"
|
||||
depends on ARCH_MESON
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
help
|
||||
This enables the driver for the on-chip UARTs of the Amlogic
|
||||
@ -236,7 +236,7 @@ config SERIAL_CLPS711X_CONSOLE
|
||||
|
||||
config SERIAL_SAMSUNG
|
||||
tristate "Samsung SoC serial support"
|
||||
depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
|
||||
depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || ARCH_APPLE || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
help
|
||||
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
|
||||
@ -278,7 +278,7 @@ config SERIAL_SAMSUNG_CONSOLE
|
||||
|
||||
config SERIAL_TEGRA
|
||||
tristate "NVIDIA Tegra20/30 SoC serial controller"
|
||||
depends on ARCH_TEGRA && TEGRA20_APB_DMA
|
||||
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
help
|
||||
Support for the on-chip UARTs on the NVIDIA Tegra series SOCs
|
||||
@ -289,7 +289,8 @@ config SERIAL_TEGRA
|
||||
|
||||
config SERIAL_TEGRA_TCU
|
||||
tristate "NVIDIA Tegra Combined UART"
|
||||
depends on ARCH_TEGRA && TEGRA_HSP_MBOX
|
||||
depends on MAILBOX
|
||||
depends on (ARCH_TEGRA && TEGRA_HSP_MBOX) || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
help
|
||||
Support for the mailbox-based TCU (Tegra Combined UART) serial port.
|
||||
@ -498,6 +499,7 @@ config SERIAL_IMX_EARLYCON
|
||||
bool "Earlycon on IMX serial port"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
depends on OF
|
||||
select SERIAL_CORE
|
||||
select SERIAL_EARLYCON
|
||||
select SERIAL_CORE_CONSOLE
|
||||
default y if SERIAL_IMX_CONSOLE
|
||||
@ -851,7 +853,8 @@ config SERIAL_MPC52xx_CONSOLE_BAUD
|
||||
|
||||
config SERIAL_ICOM
|
||||
tristate "IBM Multiport Serial Adapter"
|
||||
depends on PCI && PPC_PSERIES
|
||||
depends on PCI
|
||||
depends on PPC_PSERIES || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
select FW_LOADER
|
||||
help
|
||||
@ -920,7 +923,7 @@ config SERIAL_JSM
|
||||
|
||||
config SERIAL_MSM
|
||||
tristate "MSM on-chip serial port support"
|
||||
depends on ARCH_QCOM
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
|
||||
config SERIAL_MSM_CONSOLE
|
||||
@ -946,7 +949,7 @@ config SERIAL_QCOM_GENI_CONSOLE
|
||||
|
||||
config SERIAL_VT8500
|
||||
bool "VIA VT8500 on-chip serial port support"
|
||||
depends on ARCH_VT8500
|
||||
depends on ARCH_VT8500 || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
|
||||
config SERIAL_VT8500_CONSOLE
|
||||
@ -956,7 +959,7 @@ config SERIAL_VT8500_CONSOLE
|
||||
|
||||
config SERIAL_OMAP
|
||||
tristate "OMAP serial port support"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
depends on ARCH_OMAP2PLUS || COMPILE_TEST
|
||||
select SERIAL_CORE
|
||||
help
|
||||
If you have a machine based on an Texas Instruments OMAP CPU you
|
||||
|
@ -131,9 +131,7 @@ static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp)
|
||||
uart_insert_char(port, 0, 0, ch, flag);
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(&port->state->port);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp)
|
||||
|
@ -243,9 +243,7 @@ static void altera_uart_rx_chars(struct altera_uart *pp)
|
||||
flag);
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(&port->state->port);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static void altera_uart_tx_chars(struct altera_uart *pp)
|
||||
|
@ -159,9 +159,7 @@ static void pl010_rx_chars(struct uart_amba_port *uap)
|
||||
ignore_char:
|
||||
status = readb(uap->port.membase + UART01x_FR);
|
||||
}
|
||||
spin_unlock(&uap->port.lock);
|
||||
tty_flip_buffer_push(&uap->port.state->port);
|
||||
spin_lock(&uap->port.lock);
|
||||
}
|
||||
|
||||
static void pl010_tx_chars(struct uart_amba_port *uap)
|
||||
|
@ -937,12 +937,10 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap,
|
||||
fifotaken = pl011_fifo_to_tty(uap);
|
||||
}
|
||||
|
||||
spin_unlock(&uap->port.lock);
|
||||
dev_vdbg(uap->port.dev,
|
||||
"Took %d chars from DMA buffer and %d chars from the FIFO\n",
|
||||
dma_count, fifotaken);
|
||||
tty_flip_buffer_push(port);
|
||||
spin_lock(&uap->port.lock);
|
||||
}
|
||||
|
||||
static void pl011_dma_rx_irq(struct uart_amba_port *uap)
|
||||
|
@ -117,9 +117,7 @@ static void apbuart_rx_chars(struct uart_port *port)
|
||||
status = UART_GET_STATUS(port);
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(&port->state->port);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static void apbuart_tx_chars(struct uart_port *port)
|
||||
|
@ -385,9 +385,7 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up)
|
||||
tty_insert_flip_char(port, ch, TTY_NORMAL);
|
||||
} while (max_count-- > 0);
|
||||
|
||||
spin_unlock(&up->port.lock);
|
||||
tty_flip_buffer_push(port);
|
||||
spin_lock(&up->port.lock);
|
||||
}
|
||||
|
||||
static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
|
||||
|
@ -236,9 +236,7 @@ static void arc_serial_rx_chars(struct uart_port *port, unsigned int status)
|
||||
if (!(uart_handle_sysrq_char(port, ch)))
|
||||
uart_insert_char(port, status, RXOERR, ch, flg);
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(&port->state->port);
|
||||
spin_lock(&port->lock);
|
||||
} while (!((status = UART_GET_STATUS(port)) & RXEMPTY));
|
||||
}
|
||||
|
||||
|
@ -1178,13 +1178,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
|
||||
1,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
/*
|
||||
* Drop the lock here since it might end up calling
|
||||
* uart_start(), which takes the lock.
|
||||
*/
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(tport);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_TIMEOUT);
|
||||
}
|
||||
@ -1576,13 +1570,7 @@ static void atmel_rx_from_ring(struct uart_port *port)
|
||||
uart_insert_char(port, status, ATMEL_US_OVRE, c.ch, flg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop the lock here since it might end up calling
|
||||
* uart_start(), which takes the lock.
|
||||
*/
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(&port->state->port);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static void atmel_release_rx_pdc(struct uart_port *port)
|
||||
@ -1667,13 +1655,7 @@ static void atmel_rx_from_pdc(struct uart_port *port)
|
||||
}
|
||||
} while (head >= pdc->dma_size);
|
||||
|
||||
/*
|
||||
* Drop the lock here since it might end up calling
|
||||
* uart_start(), which takes the lock.
|
||||
*/
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(tport);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
atmel_uart_writel(port, ATMEL_US_IER,
|
||||
ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
|
||||
|
@ -294,9 +294,7 @@ static void bcm_uart_do_rx(struct uart_port *port)
|
||||
|
||||
} while (--max_count);
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(tty_port);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -829,9 +829,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
|
||||
}
|
||||
icom_port->next_rcv = rcv_buff;
|
||||
|
||||
spin_unlock(&icom_port->uart_port.lock);
|
||||
tty_flip_buffer_push(port);
|
||||
spin_lock(&icom_port->uart_port.lock);
|
||||
}
|
||||
|
||||
static void process_interrupt(u16 port_int_reg,
|
||||
|
@ -394,11 +394,7 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2)
|
||||
|
||||
static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
|
||||
{
|
||||
long sec = msec / MSEC_PER_SEC;
|
||||
long nsec = (msec % MSEC_PER_SEC) * 1000000;
|
||||
ktime_t t = ktime_set(sec, nsec);
|
||||
|
||||
hrtimer_start(hrt, t, HRTIMER_MODE_REL);
|
||||
hrtimer_start(hrt, ms_to_ktime(msec), HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
/* called with port.lock taken and irqs off */
|
||||
@ -922,14 +918,8 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
|
||||
struct imx_port *sport = dev_id;
|
||||
unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
unsigned long flags = 0;
|
||||
|
||||
/*
|
||||
* IRQs might not be disabled upon entering this interrupt handler,
|
||||
* e.g. when interrupt handlers are forced to be threaded. To support
|
||||
* this scenario as well, disable IRQs when acquiring the spinlock.
|
||||
*/
|
||||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
spin_lock(&sport->port.lock);
|
||||
|
||||
usr1 = imx_uart_readl(sport, USR1);
|
||||
usr2 = imx_uart_readl(sport, USR2);
|
||||
@ -999,7 +989,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
spin_unlock(&sport->port.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -603,18 +603,22 @@ void jsm_input(struct jsm_channel *ch)
|
||||
|
||||
if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
|
||||
for (i = 0; i < s; i++) {
|
||||
u8 chr = ch->ch_rqueue[tail + i];
|
||||
u8 error = ch->ch_equeue[tail + i];
|
||||
char flag = TTY_NORMAL;
|
||||
|
||||
/*
|
||||
* Give the Linux ld the flags in the
|
||||
* format it likes.
|
||||
* Give the Linux ld the flags in the format it
|
||||
* likes.
|
||||
*/
|
||||
if (*(ch->ch_equeue + tail + i) & UART_LSR_BI)
|
||||
tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_BREAK);
|
||||
else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE)
|
||||
tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_PARITY);
|
||||
else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE)
|
||||
tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_FRAME);
|
||||
else
|
||||
tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_NORMAL);
|
||||
if (error & UART_LSR_BI)
|
||||
flag = TTY_BREAK;
|
||||
else if (error & UART_LSR_PE)
|
||||
flag = TTY_PARITY;
|
||||
else if (error & UART_LSR_FE)
|
||||
flag = TTY_FRAME;
|
||||
|
||||
tty_insert_flip_char(port, chr, flag);
|
||||
}
|
||||
} else {
|
||||
tty_insert_flip_string(port, ch->ch_rqueue + tail, s);
|
||||
|
@ -373,9 +373,7 @@ int kgdb_unregister_nmi_console(void)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = tty_unregister_driver(kgdb_nmi_tty_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
tty_unregister_driver(kgdb_nmi_tty_driver);
|
||||
put_tty_driver(kgdb_nmi_tty_driver);
|
||||
|
||||
return 0;
|
||||
|
@ -270,8 +270,8 @@ static int liteuart_probe(struct platform_device *pdev)
|
||||
|
||||
/* get membase */
|
||||
port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (!port->membase)
|
||||
return -ENXIO;
|
||||
if (IS_ERR(port->membase))
|
||||
return PTR_ERR(port->membase);
|
||||
|
||||
/* values not from device tree */
|
||||
port->dev = &pdev->dev;
|
||||
|
@ -273,9 +273,7 @@ static void __serial_lpc32xx_rx(struct uart_port *port)
|
||||
tmp = readl(LPC32XX_HSUART_FIFO(port->membase));
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(tport);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static void __serial_lpc32xx_tx(struct uart_port *port)
|
||||
|
@ -273,7 +273,7 @@ struct max310x_port {
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
struct gpio_chip gpio;
|
||||
#endif
|
||||
struct max310x_one p[0];
|
||||
struct max310x_one p[];
|
||||
};
|
||||
|
||||
static struct uart_driver max310x_uart = {
|
||||
|
@ -319,9 +319,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
|
||||
uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(&port->state->port);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -226,9 +226,7 @@ static void meson_receive_chars(struct uart_port *port)
|
||||
|
||||
} while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY));
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(tport);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static irqreturn_t meson_uart_interrupt(int irq, void *dev_id)
|
||||
|
@ -1421,9 +1421,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(tport);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
return psc_ops->raw_rx_rdy(port);
|
||||
}
|
||||
|
@ -757,9 +757,7 @@ static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr)
|
||||
count -= r_count;
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(tport);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
if (misr & (UART_IMR_RXSTALE))
|
||||
msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
|
||||
@ -819,9 +817,7 @@ static void msm_handle_rx(struct uart_port *port)
|
||||
tty_insert_flip_char(tport, c, flag);
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(tport);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static void msm_handle_tx_pio(struct uart_port *port, unsigned int tx_count)
|
||||
|
@ -159,6 +159,8 @@ struct uart_omap_port {
|
||||
u32 calc_latency;
|
||||
struct work_struct qos_work;
|
||||
bool is_suspending;
|
||||
|
||||
unsigned int rs485_tx_filter_count;
|
||||
};
|
||||
|
||||
#define to_uart_omap_port(p) ((container_of((p), struct uart_omap_port, port)))
|
||||
@ -302,7 +304,8 @@ static void serial_omap_stop_tx(struct uart_port *port)
|
||||
serial_out(up, UART_OMAP_SCR, up->scr);
|
||||
res = (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) ?
|
||||
1 : 0;
|
||||
if (gpiod_get_value(up->rts_gpiod) != res) {
|
||||
if (up->rts_gpiod &&
|
||||
gpiod_get_value(up->rts_gpiod) != res) {
|
||||
if (port->rs485.delay_rts_after_send > 0)
|
||||
mdelay(
|
||||
port->rs485.delay_rts_after_send);
|
||||
@ -328,19 +331,6 @@ static void serial_omap_stop_tx(struct uart_port *port)
|
||||
serial_out(up, UART_IER, up->ier);
|
||||
}
|
||||
|
||||
if ((port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(port->rs485.flags & SER_RS485_RX_DURING_TX)) {
|
||||
/*
|
||||
* Empty the RX FIFO, we are not interested in anything
|
||||
* received during the half-duplex transmission.
|
||||
*/
|
||||
serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_RCVR);
|
||||
/* Re-enable RX interrupts */
|
||||
up->ier |= UART_IER_RLSI | UART_IER_RDI;
|
||||
up->port.read_status_mask |= UART_LSR_DR;
|
||||
serial_out(up, UART_IER, up->ier);
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(up->dev);
|
||||
pm_runtime_put_autosuspend(up->dev);
|
||||
}
|
||||
@ -366,6 +356,10 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr)
|
||||
serial_out(up, UART_TX, up->port.x_char);
|
||||
up->port.icount.tx++;
|
||||
up->port.x_char = 0;
|
||||
if ((up->port.rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(up->port.rs485.flags & SER_RS485_RX_DURING_TX))
|
||||
up->rs485_tx_filter_count++;
|
||||
|
||||
return;
|
||||
}
|
||||
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
|
||||
@ -377,6 +371,10 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr)
|
||||
serial_out(up, UART_TX, xmit->buf[xmit->tail]);
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
up->port.icount.tx++;
|
||||
if ((up->port.rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(up->port.rs485.flags & SER_RS485_RX_DURING_TX))
|
||||
up->rs485_tx_filter_count++;
|
||||
|
||||
if (uart_circ_empty(xmit))
|
||||
break;
|
||||
} while (--count > 0);
|
||||
@ -411,7 +409,7 @@ static void serial_omap_start_tx(struct uart_port *port)
|
||||
|
||||
/* if rts not already enabled */
|
||||
res = (port->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0;
|
||||
if (gpiod_get_value(up->rts_gpiod) != res) {
|
||||
if (up->rts_gpiod && gpiod_get_value(up->rts_gpiod) != res) {
|
||||
gpiod_set_value(up->rts_gpiod, res);
|
||||
if (port->rs485.delay_rts_before_send > 0)
|
||||
mdelay(port->rs485.delay_rts_before_send);
|
||||
@ -420,7 +418,7 @@ static void serial_omap_start_tx(struct uart_port *port)
|
||||
|
||||
if ((port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(port->rs485.flags & SER_RS485_RX_DURING_TX))
|
||||
serial_omap_stop_rx(port);
|
||||
up->rs485_tx_filter_count = 0;
|
||||
|
||||
serial_omap_enable_ier_thri(up);
|
||||
pm_runtime_mark_last_busy(up->dev);
|
||||
@ -491,8 +489,13 @@ static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr)
|
||||
* Read one data character out to avoid stalling the receiver according
|
||||
* to the table 23-246 of the omap4 TRM.
|
||||
*/
|
||||
if (likely(lsr & UART_LSR_DR))
|
||||
if (likely(lsr & UART_LSR_DR)) {
|
||||
serial_in(up, UART_RX);
|
||||
if ((up->port.rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(up->port.rs485.flags & SER_RS485_RX_DURING_TX) &&
|
||||
up->rs485_tx_filter_count)
|
||||
up->rs485_tx_filter_count--;
|
||||
}
|
||||
|
||||
up->port.icount.rx++;
|
||||
flag = TTY_NORMAL;
|
||||
@ -543,6 +546,13 @@ static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr)
|
||||
return;
|
||||
|
||||
ch = serial_in(up, UART_RX);
|
||||
if ((up->port.rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(up->port.rs485.flags & SER_RS485_RX_DURING_TX) &&
|
||||
up->rs485_tx_filter_count) {
|
||||
up->rs485_tx_filter_count--;
|
||||
return;
|
||||
}
|
||||
|
||||
flag = TTY_NORMAL;
|
||||
up->port.icount.rx++;
|
||||
|
||||
@ -1407,18 +1417,13 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485)
|
||||
/* store new config */
|
||||
port->rs485 = *rs485;
|
||||
|
||||
/*
|
||||
* Just as a precaution, only allow rs485
|
||||
* to be enabled if the gpio pin is valid
|
||||
*/
|
||||
if (up->rts_gpiod) {
|
||||
/* enable / disable rts */
|
||||
val = (port->rs485.flags & SER_RS485_ENABLED) ?
|
||||
SER_RS485_RTS_AFTER_SEND : SER_RS485_RTS_ON_SEND;
|
||||
val = (port->rs485.flags & val) ? 1 : 0;
|
||||
gpiod_set_value(up->rts_gpiod, val);
|
||||
} else
|
||||
port->rs485.flags &= ~SER_RS485_ENABLED;
|
||||
}
|
||||
|
||||
/* Enable interrupts */
|
||||
up->ier = mode;
|
||||
|
@ -247,9 +247,7 @@ static void owl_uart_receive_chars(struct uart_port *port)
|
||||
stat = owl_uart_read(port, OWL_UART_STAT);
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(&port->state->port);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static irqreturn_t owl_uart_irq(int irq, void *dev_id)
|
||||
|
@ -236,7 +236,6 @@ struct eg20t_port {
|
||||
void *rx_buf_virt;
|
||||
dma_addr_t rx_buf_dma;
|
||||
|
||||
struct dentry *debugfs;
|
||||
#define IRQ_NAME_SIZE 17
|
||||
char irq_name[IRQ_NAME_SIZE];
|
||||
|
||||
@ -292,8 +291,6 @@ static const int trigger_level_64[4] = { 1, 16, 32, 56 };
|
||||
static const int trigger_level_16[4] = { 1, 4, 8, 14 };
|
||||
static const int trigger_level_1[4] = { 1, 1, 1, 1 };
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
#define PCH_REGS_BUFSIZE 1024
|
||||
|
||||
|
||||
@ -353,7 +350,6 @@ static const struct file_operations port_regs_ops = {
|
||||
.read = port_show_regs,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
static const struct dmi_system_id pch_uart_dmi_table[] = {
|
||||
{
|
||||
@ -1735,9 +1731,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
|
||||
int fifosize;
|
||||
int port_type;
|
||||
struct pch_uart_driver_data *board;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
char name[32]; /* for debugfs file name */
|
||||
#endif
|
||||
char name[32];
|
||||
|
||||
board = &drv_dat[id->driver_data];
|
||||
port_type = board->port_type;
|
||||
@ -1813,11 +1807,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
|
||||
if (ret < 0)
|
||||
goto init_port_hal_free;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
snprintf(name, sizeof(name), "uart%d_regs", board->line_no);
|
||||
priv->debugfs = debugfs_create_file(name, S_IFREG | S_IRUGO,
|
||||
NULL, priv, &port_regs_ops);
|
||||
#endif
|
||||
snprintf(name, sizeof(name), "uart%d_regs", priv->port.line);
|
||||
debugfs_create_file(name, S_IFREG | S_IRUGO, NULL, priv,
|
||||
&port_regs_ops);
|
||||
|
||||
return priv;
|
||||
|
||||
@ -1835,10 +1827,10 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
|
||||
|
||||
static void pch_uart_exit_port(struct eg20t_port *priv)
|
||||
{
|
||||
char name[32];
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
debugfs_remove(priv->debugfs);
|
||||
#endif
|
||||
snprintf(name, sizeof(name), "uart%d_regs", priv->port.line);
|
||||
debugfs_remove(debugfs_lookup(name, NULL));
|
||||
uart_remove_one_port(&pch_uart_driver, &priv->port);
|
||||
free_page((unsigned long)priv->rxbuf.buf);
|
||||
}
|
||||
|
@ -818,7 +818,6 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
|
||||
u32 s_irq_status;
|
||||
u32 geni_status;
|
||||
struct uart_port *uport = dev;
|
||||
unsigned long flags;
|
||||
bool drop_rx = false;
|
||||
struct tty_port *tport = &uport->state->port;
|
||||
struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
|
||||
@ -826,7 +825,8 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
|
||||
if (uport->suspended)
|
||||
return IRQ_NONE;
|
||||
|
||||
spin_lock_irqsave(&uport->lock, flags);
|
||||
spin_lock(&uport->lock);
|
||||
|
||||
m_irq_status = readl(uport->membase + SE_GENI_M_IRQ_STATUS);
|
||||
s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS);
|
||||
geni_status = readl(uport->membase + SE_GENI_STATUS);
|
||||
@ -861,7 +861,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
|
||||
qcom_geni_serial_handle_rx(uport, drop_rx);
|
||||
|
||||
out_unlock:
|
||||
uart_unlock_and_check_sysrq(uport, flags);
|
||||
uart_unlock_and_check_sysrq(uport);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -398,9 +398,7 @@ static void rda_uart_receive_chars(struct uart_port *port)
|
||||
status = rda_uart_read(port, RDA_UART_STATUS);
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
tty_flip_buffer_push(&port->state->port);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static irqreturn_t rda_interrupt(int irq, void *dev_id)
|
||||
|
@ -424,9 +424,7 @@ static void rp2_rx_chars(struct rp2_uart_port *up)
|
||||
up->port.icount.rx++;
|
||||
}
|
||||
|
||||
spin_unlock(&up->port.lock);
|
||||
tty_flip_buffer_push(port);
|
||||
spin_lock(&up->port.lock);
|
||||
}
|
||||
|
||||
static void rp2_tx_chars(struct rp2_uart_port *up)
|
||||
|
@ -223,9 +223,7 @@ sa1100_rx_chars(struct sa1100_port *sport)
|
||||
UTSR0_TO_SM(UART_GET_UTSR0(sport));
|
||||
}
|
||||
|
||||
spin_unlock(&sport->port.lock);
|
||||
tty_flip_buffer_push(&sport->port.state->port);
|
||||
spin_lock(&sport->port.lock);
|
||||
}
|
||||
|
||||
static void sa1100_tx_chars(struct sa1100_port *sport)
|
||||
|
@ -56,9 +56,16 @@
|
||||
/* flag to ignore all characters coming in */
|
||||
#define RXSTAT_DUMMY_READ (0x10000000)
|
||||
|
||||
enum s3c24xx_port_type {
|
||||
TYPE_S3C24XX,
|
||||
TYPE_S3C6400,
|
||||
TYPE_APPLE_S5L,
|
||||
};
|
||||
|
||||
struct s3c24xx_uart_info {
|
||||
char *name;
|
||||
unsigned int type;
|
||||
enum s3c24xx_port_type type;
|
||||
unsigned int port_type;
|
||||
unsigned int fifosize;
|
||||
unsigned long rx_fifomask;
|
||||
unsigned long rx_fifoshift;
|
||||
@ -70,6 +77,7 @@ struct s3c24xx_uart_info {
|
||||
unsigned long num_clks;
|
||||
unsigned long clksel_mask;
|
||||
unsigned long clksel_shift;
|
||||
unsigned long ucon_mask;
|
||||
|
||||
/* uart port features */
|
||||
|
||||
@ -144,6 +152,8 @@ struct s3c24xx_uart_port {
|
||||
#endif
|
||||
};
|
||||
|
||||
static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport);
|
||||
|
||||
/* conversion functions */
|
||||
|
||||
#define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
|
||||
@ -228,16 +238,6 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
|
||||
return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE;
|
||||
}
|
||||
|
||||
/*
|
||||
* s3c64xx and later SoC's include the interrupt mask and status registers in
|
||||
* the controller itself, unlike the s3c24xx SoC's which have these registers
|
||||
* in the interrupt controller. Check if the port type is s3c64xx or higher.
|
||||
*/
|
||||
static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
|
||||
{
|
||||
return to_ourport(port)->info->type == PORT_S3C6400;
|
||||
}
|
||||
|
||||
static void s3c24xx_serial_rx_enable(struct uart_port *port)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
@ -289,10 +289,17 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
|
||||
if (!ourport->tx_enabled)
|
||||
return;
|
||||
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
switch (ourport->info->type) {
|
||||
case TYPE_S3C6400:
|
||||
s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
|
||||
else
|
||||
break;
|
||||
case TYPE_APPLE_S5L:
|
||||
s3c24xx_clear_bit(port, APPLE_S5L_UCON_TXTHRESH_ENA, S3C2410_UCON);
|
||||
break;
|
||||
default:
|
||||
disable_irq_nosync(ourport->tx_irq);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) {
|
||||
dmaengine_pause(dma->tx_chan);
|
||||
@ -353,10 +360,17 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
|
||||
u32 ucon;
|
||||
|
||||
/* Mask Tx interrupt */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
switch (ourport->info->type) {
|
||||
case TYPE_S3C6400:
|
||||
s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM);
|
||||
else
|
||||
break;
|
||||
case TYPE_APPLE_S5L:
|
||||
WARN_ON(1); // No DMA
|
||||
break;
|
||||
default:
|
||||
disable_irq_nosync(ourport->tx_irq);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable tx dma mode */
|
||||
ucon = rd_regl(port, S3C2410_UCON);
|
||||
@ -386,13 +400,28 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport)
|
||||
wr_regl(port, S3C2410_UCON, ucon);
|
||||
|
||||
/* Unmask Tx interrupt */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
switch (ourport->info->type) {
|
||||
case TYPE_S3C6400:
|
||||
s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD,
|
||||
S3C64XX_UINTM);
|
||||
else
|
||||
break;
|
||||
case TYPE_APPLE_S5L:
|
||||
ucon |= APPLE_S5L_UCON_TXTHRESH_ENA_MSK;
|
||||
wr_regl(port, S3C2410_UCON, ucon);
|
||||
break;
|
||||
default:
|
||||
enable_irq(ourport->tx_irq);
|
||||
break;
|
||||
}
|
||||
|
||||
ourport->tx_mode = S3C24XX_TX_PIO;
|
||||
|
||||
/*
|
||||
* The Apple version only has edge triggered TX IRQs, so we need
|
||||
* to kick off the process by sending some characters here.
|
||||
*/
|
||||
if (ourport->info->type == TYPE_APPLE_S5L)
|
||||
s3c24xx_serial_tx_chars(ourport);
|
||||
}
|
||||
|
||||
static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport)
|
||||
@ -513,11 +542,19 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
|
||||
|
||||
if (ourport->rx_enabled) {
|
||||
dev_dbg(port->dev, "stopping rx\n");
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
switch (ourport->info->type) {
|
||||
case TYPE_S3C6400:
|
||||
s3c24xx_set_bit(port, S3C64XX_UINTM_RXD,
|
||||
S3C64XX_UINTM);
|
||||
else
|
||||
break;
|
||||
case TYPE_APPLE_S5L:
|
||||
s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
|
||||
s3c24xx_clear_bit(port, APPLE_S5L_UCON_RXTO_ENA, S3C2410_UCON);
|
||||
break;
|
||||
default:
|
||||
disable_irq_nosync(ourport->rx_irq);
|
||||
break;
|
||||
}
|
||||
ourport->rx_enabled = 0;
|
||||
}
|
||||
if (dma && dma->rx_chan) {
|
||||
@ -651,14 +688,18 @@ static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
|
||||
|
||||
/* set Rx mode to DMA mode */
|
||||
ucon = rd_regl(port, S3C2410_UCON);
|
||||
ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
|
||||
S3C64XX_UCON_EMPTYINT_EN |
|
||||
S3C64XX_UCON_DMASUS_EN |
|
||||
S3C64XX_UCON_TIMEOUT_EN |
|
||||
S3C64XX_UCON_RXMODE_MASK);
|
||||
ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
|
||||
S3C64XX_UCON_TIMEOUT_EN |
|
||||
S3C64XX_UCON_RXMODE_CPU;
|
||||
ucon &= ~S3C64XX_UCON_RXMODE_MASK;
|
||||
ucon |= S3C64XX_UCON_RXMODE_CPU;
|
||||
|
||||
/* Apple types use these bits for IRQ masks */
|
||||
if (ourport->info->type != TYPE_APPLE_S5L) {
|
||||
ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
|
||||
S3C64XX_UCON_EMPTYINT_EN |
|
||||
S3C64XX_UCON_DMASUS_EN |
|
||||
S3C64XX_UCON_TIMEOUT_EN);
|
||||
ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
|
||||
S3C64XX_UCON_TIMEOUT_EN;
|
||||
}
|
||||
wr_regl(port, S3C2410_UCON, ucon);
|
||||
|
||||
ourport->rx_mode = S3C24XX_RX_PIO;
|
||||
@ -674,13 +715,12 @@ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
|
||||
struct s3c24xx_uart_dma *dma = ourport->dma;
|
||||
struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port);
|
||||
struct tty_port *t = &port->state->port;
|
||||
unsigned long flags;
|
||||
struct dma_tx_state state;
|
||||
|
||||
utrstat = rd_regl(port, S3C2410_UTRSTAT);
|
||||
rd_regl(port, S3C2410_UFSTAT);
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) {
|
||||
s3c64xx_start_rx_dma(ourport);
|
||||
@ -709,7 +749,7 @@ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
|
||||
wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT);
|
||||
|
||||
finish:
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
spin_unlock(&port->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -805,16 +845,15 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = dev_id;
|
||||
struct uart_port *port = &ourport->port;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
spin_lock(&port->lock);
|
||||
s3c24xx_serial_rx_drain_fifo(ourport);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
spin_unlock(&port->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
|
||||
static irqreturn_t s3c24xx_serial_rx_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = dev_id;
|
||||
|
||||
@ -823,16 +862,12 @@ static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
|
||||
return s3c24xx_serial_rx_chars_pio(dev_id);
|
||||
}
|
||||
|
||||
static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
|
||||
static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = id;
|
||||
struct uart_port *port = &ourport->port;
|
||||
struct circ_buf *xmit = &port->state->xmit;
|
||||
unsigned long flags;
|
||||
int count, dma_count = 0;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
|
||||
|
||||
if (ourport->dma && ourport->dma->tx_chan &&
|
||||
@ -849,7 +884,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
|
||||
wr_reg(port, S3C2410_UTXH, port->x_char);
|
||||
port->icount.tx++;
|
||||
port->x_char = 0;
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
/* if there isn't anything more to transmit, or the uart is now
|
||||
@ -858,7 +893,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
|
||||
|
||||
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
|
||||
s3c24xx_serial_stop_tx(port);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
/* try and drain the buffer... */
|
||||
@ -880,7 +915,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
|
||||
|
||||
if (!count && dma_count) {
|
||||
s3c24xx_serial_start_tx_dma(ourport, dma_count);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
|
||||
@ -891,9 +926,18 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
|
||||
|
||||
if (uart_circ_empty(xmit))
|
||||
s3c24xx_serial_stop_tx(port);
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
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);
|
||||
|
||||
s3c24xx_serial_tx_chars(ourport);
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -906,16 +950,37 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
|
||||
irqreturn_t ret = IRQ_HANDLED;
|
||||
|
||||
if (pend & S3C64XX_UINTM_RXD_MSK) {
|
||||
ret = s3c24xx_serial_rx_chars(irq, id);
|
||||
ret = s3c24xx_serial_rx_irq(irq, id);
|
||||
wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
|
||||
}
|
||||
if (pend & S3C64XX_UINTM_TXD_MSK) {
|
||||
ret = s3c24xx_serial_tx_chars(irq, id);
|
||||
ret = s3c24xx_serial_tx_irq(irq, id);
|
||||
wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* interrupt handler for Apple SoC's.*/
|
||||
static irqreturn_t apple_serial_handle_irq(int irq, void *id)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = id;
|
||||
struct uart_port *port = &ourport->port;
|
||||
unsigned int pend = rd_regl(port, S3C2410_UTRSTAT);
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
if (pend & (APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO)) {
|
||||
wr_regl(port, S3C2410_UTRSTAT,
|
||||
APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO);
|
||||
ret = s3c24xx_serial_rx_irq(irq, id);
|
||||
}
|
||||
if (pend & APPLE_S5L_UTRSTAT_TXTHRESH) {
|
||||
wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_TXTHRESH);
|
||||
ret = s3c24xx_serial_tx_irq(irq, id);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
|
||||
{
|
||||
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
|
||||
@ -1098,27 +1163,62 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
|
||||
if (ourport->tx_claimed) {
|
||||
if (!s3c24xx_serial_has_interrupt_mask(port))
|
||||
free_irq(ourport->tx_irq, ourport);
|
||||
free_irq(ourport->tx_irq, ourport);
|
||||
ourport->tx_enabled = 0;
|
||||
ourport->tx_claimed = 0;
|
||||
ourport->tx_mode = 0;
|
||||
}
|
||||
|
||||
if (ourport->rx_claimed) {
|
||||
if (!s3c24xx_serial_has_interrupt_mask(port))
|
||||
free_irq(ourport->rx_irq, ourport);
|
||||
free_irq(ourport->rx_irq, ourport);
|
||||
ourport->rx_claimed = 0;
|
||||
ourport->rx_enabled = 0;
|
||||
}
|
||||
|
||||
/* Clear pending interrupts and mask all interrupts */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port)) {
|
||||
free_irq(port->irq, ourport);
|
||||
if (ourport->dma)
|
||||
s3c24xx_serial_release_dma(ourport);
|
||||
|
||||
wr_regl(port, S3C64XX_UINTP, 0xf);
|
||||
wr_regl(port, S3C64XX_UINTM, 0xf);
|
||||
}
|
||||
ourport->tx_in_progress = 0;
|
||||
}
|
||||
|
||||
static void s3c64xx_serial_shutdown(struct uart_port *port)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
|
||||
ourport->tx_enabled = 0;
|
||||
ourport->tx_mode = 0;
|
||||
ourport->rx_enabled = 0;
|
||||
|
||||
free_irq(port->irq, ourport);
|
||||
|
||||
wr_regl(port, S3C64XX_UINTP, 0xf);
|
||||
wr_regl(port, S3C64XX_UINTM, 0xf);
|
||||
|
||||
if (ourport->dma)
|
||||
s3c24xx_serial_release_dma(ourport);
|
||||
|
||||
ourport->tx_in_progress = 0;
|
||||
}
|
||||
|
||||
static void apple_s5l_serial_shutdown(struct uart_port *port)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
|
||||
unsigned int ucon;
|
||||
|
||||
ucon = rd_regl(port, S3C2410_UCON);
|
||||
ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
|
||||
APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
|
||||
APPLE_S5L_UCON_RXTO_ENA_MSK);
|
||||
wr_regl(port, S3C2410_UCON, ucon);
|
||||
|
||||
wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
|
||||
|
||||
free_irq(port->irq, ourport);
|
||||
|
||||
ourport->tx_enabled = 0;
|
||||
ourport->tx_mode = 0;
|
||||
ourport->rx_enabled = 0;
|
||||
|
||||
if (ourport->dma)
|
||||
s3c24xx_serial_release_dma(ourport);
|
||||
@ -1133,7 +1233,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
|
||||
|
||||
ourport->rx_enabled = 1;
|
||||
|
||||
ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
|
||||
ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_irq, 0,
|
||||
s3c24xx_serial_portname(port), ourport);
|
||||
|
||||
if (ret != 0) {
|
||||
@ -1147,7 +1247,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
|
||||
|
||||
ourport->tx_enabled = 1;
|
||||
|
||||
ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
|
||||
ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_irq, 0,
|
||||
s3c24xx_serial_portname(port), ourport);
|
||||
|
||||
if (ret) {
|
||||
@ -1193,9 +1293,7 @@ static int s3c64xx_serial_startup(struct uart_port *port)
|
||||
|
||||
/* For compatibility with s3c24xx Soc's */
|
||||
ourport->rx_enabled = 1;
|
||||
ourport->rx_claimed = 1;
|
||||
ourport->tx_enabled = 0;
|
||||
ourport->tx_claimed = 1;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
@ -1215,6 +1313,45 @@ static int s3c64xx_serial_startup(struct uart_port *port)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int apple_s5l_serial_startup(struct uart_port *port)
|
||||
{
|
||||
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||
unsigned long flags;
|
||||
unsigned int ufcon;
|
||||
int ret;
|
||||
|
||||
wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
|
||||
|
||||
ret = request_irq(port->irq, apple_serial_handle_irq, 0,
|
||||
s3c24xx_serial_portname(port), ourport);
|
||||
if (ret) {
|
||||
dev_err(port->dev, "cannot get irq %d\n", port->irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* For compatibility with s3c24xx Soc's */
|
||||
ourport->rx_enabled = 1;
|
||||
ourport->tx_enabled = 0;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
ufcon = rd_regl(port, S3C2410_UFCON);
|
||||
ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
|
||||
if (!uart_console(port))
|
||||
ufcon |= S3C2410_UFCON_RESETTX;
|
||||
wr_regl(port, S3C2410_UFCON, ufcon);
|
||||
|
||||
enable_rx_pio(ourport);
|
||||
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
||||
/* Enable Rx Interrupt */
|
||||
s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
|
||||
s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTO_ENA, S3C2410_UCON);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* power power management control */
|
||||
|
||||
static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
|
||||
@ -1535,41 +1672,26 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
|
||||
|
||||
static const char *s3c24xx_serial_type(struct uart_port *port)
|
||||
{
|
||||
switch (port->type) {
|
||||
case PORT_S3C2410:
|
||||
return "S3C2410";
|
||||
case PORT_S3C2440:
|
||||
return "S3C2440";
|
||||
case PORT_S3C2412:
|
||||
return "S3C2412";
|
||||
case PORT_S3C6400:
|
||||
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:
|
||||
return "APPLE S5L";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAP_SIZE (0x100)
|
||||
|
||||
static void s3c24xx_serial_release_port(struct uart_port *port)
|
||||
{
|
||||
release_mem_region(port->mapbase, MAP_SIZE);
|
||||
}
|
||||
|
||||
static int s3c24xx_serial_request_port(struct uart_port *port)
|
||||
{
|
||||
const char *name = s3c24xx_serial_portname(port);
|
||||
|
||||
return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
|
||||
}
|
||||
|
||||
static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
|
||||
{
|
||||
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
|
||||
|
||||
if (flags & UART_CONFIG_TYPE &&
|
||||
s3c24xx_serial_request_port(port) == 0)
|
||||
port->type = info->type;
|
||||
if (flags & UART_CONFIG_TYPE)
|
||||
port->type = info->port_type;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1580,7 +1702,7 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
|
||||
{
|
||||
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
|
||||
|
||||
if (ser->type != PORT_UNKNOWN && ser->type != info->type)
|
||||
if (ser->type != PORT_UNKNOWN && ser->type != info->port_type)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@ -1608,7 +1730,7 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
|
||||
unsigned char c);
|
||||
#endif
|
||||
|
||||
static struct uart_ops s3c24xx_serial_ops = {
|
||||
static const struct uart_ops s3c24xx_serial_ops = {
|
||||
.pm = s3c24xx_serial_pm,
|
||||
.tx_empty = s3c24xx_serial_tx_empty,
|
||||
.get_mctrl = s3c24xx_serial_get_mctrl,
|
||||
@ -1621,8 +1743,48 @@ static struct uart_ops s3c24xx_serial_ops = {
|
||||
.shutdown = s3c24xx_serial_shutdown,
|
||||
.set_termios = s3c24xx_serial_set_termios,
|
||||
.type = s3c24xx_serial_type,
|
||||
.release_port = s3c24xx_serial_release_port,
|
||||
.request_port = s3c24xx_serial_request_port,
|
||||
.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,
|
||||
.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 = s3c64xx_serial_startup,
|
||||
.shutdown = s3c64xx_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 apple_s5l_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 = apple_s5l_serial_startup,
|
||||
.shutdown = apple_s5l_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)
|
||||
@ -1706,14 +1868,9 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
|
||||
{
|
||||
struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
|
||||
unsigned long ucon = rd_regl(port, S3C2410_UCON);
|
||||
unsigned int ucon_mask;
|
||||
|
||||
ucon_mask = info->clksel_mask;
|
||||
if (info->type == PORT_S3C2440)
|
||||
ucon_mask |= S3C2440_UCON0_DIVMASK;
|
||||
|
||||
ucon &= ucon_mask;
|
||||
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
|
||||
ucon &= (info->clksel_mask | info->ucon_mask);
|
||||
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
|
||||
|
||||
/* reset both fifos */
|
||||
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
|
||||
@ -1868,10 +2025,6 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
||||
/* setup info for port */
|
||||
port->dev = &platdev->dev;
|
||||
|
||||
/* Startup sequence is different for s3c64xx and higher SoC's */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port))
|
||||
s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
|
||||
|
||||
port->uartclk = 1;
|
||||
|
||||
if (cfg->uart_flags & UPF_CONS_FLOW) {
|
||||
@ -1889,8 +2042,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
||||
|
||||
dev_dbg(port->dev, "resource %pR)\n", res);
|
||||
|
||||
port->membase = devm_ioremap(port->dev, res->start, resource_size(res));
|
||||
if (!port->membase) {
|
||||
port->membase = devm_ioremap_resource(port->dev, res);
|
||||
if (IS_ERR(port->membase)) {
|
||||
dev_err(port->dev, "failed to remap controller address\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -1905,11 +2058,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
||||
ourport->tx_irq = ret + 1;
|
||||
}
|
||||
|
||||
if (!s3c24xx_serial_has_interrupt_mask(port)) {
|
||||
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.
|
||||
@ -1945,10 +2103,26 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
||||
pr_warn("uart: failed to enable baudclk\n");
|
||||
|
||||
/* Keep all interrupts masked and cleared */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port)) {
|
||||
switch (ourport->info->type) {
|
||||
case TYPE_S3C6400:
|
||||
wr_regl(port, S3C64XX_UINTM, 0xf);
|
||||
wr_regl(port, S3C64XX_UINTP, 0xf);
|
||||
wr_regl(port, S3C64XX_UINTSP, 0xf);
|
||||
break;
|
||||
case TYPE_APPLE_S5L: {
|
||||
unsigned int ucon;
|
||||
|
||||
ucon = rd_regl(port, S3C2410_UCON);
|
||||
ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
|
||||
APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
|
||||
APPLE_S5L_UCON_RXTO_ENA_MSK);
|
||||
wr_regl(port, S3C2410_UCON, ucon);
|
||||
|
||||
wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(port->dev, "port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n",
|
||||
@ -2019,6 +2193,18 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
|
||||
dev_get_platdata(&pdev->dev) :
|
||||
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;
|
||||
case TYPE_APPLE_S5L:
|
||||
ourport->port.ops = &apple_s5l_serial_ops;
|
||||
break;
|
||||
}
|
||||
|
||||
if (np) {
|
||||
of_property_read_u32(np,
|
||||
"samsung,uart-fifosize", &ourport->port.fifosize);
|
||||
@ -2142,7 +2328,8 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
|
||||
|
||||
if (port) {
|
||||
/* restore IRQ mask */
|
||||
if (s3c24xx_serial_has_interrupt_mask(port)) {
|
||||
switch (ourport->info->type) {
|
||||
case TYPE_S3C6400: {
|
||||
unsigned int uintm = 0xf;
|
||||
|
||||
if (ourport->tx_enabled)
|
||||
@ -2156,6 +2343,47 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
|
||||
if (!IS_ERR(ourport->baudclk))
|
||||
clk_disable_unprepare(ourport->baudclk);
|
||||
clk_disable_unprepare(ourport->clk);
|
||||
break;
|
||||
}
|
||||
case TYPE_APPLE_S5L: {
|
||||
unsigned int ucon;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(ourport->clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "clk_enable clk failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (!IS_ERR(ourport->baudclk)) {
|
||||
ret = clk_prepare_enable(ourport->baudclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "clk_enable baudclk failed: %d\n", ret);
|
||||
clk_disable_unprepare(ourport->clk);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ucon = rd_regl(port, S3C2410_UCON);
|
||||
|
||||
ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
|
||||
APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
|
||||
APPLE_S5L_UCON_RXTO_ENA_MSK);
|
||||
|
||||
if (ourport->tx_enabled)
|
||||
ucon |= APPLE_S5L_UCON_TXTHRESH_ENA_MSK;
|
||||
if (ourport->rx_enabled)
|
||||
ucon |= APPLE_S5L_UCON_RXTHRESH_ENA_MSK |
|
||||
APPLE_S5L_UCON_RXTO_ENA_MSK;
|
||||
|
||||
wr_regl(port, S3C2410_UCON, ucon);
|
||||
|
||||
if (!IS_ERR(ourport->baudclk))
|
||||
clk_disable_unprepare(ourport->baudclk);
|
||||
clk_disable_unprepare(ourport->clk);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2380,7 +2608,8 @@ static struct console s3c24xx_serial_console = {
|
||||
static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
|
||||
.info = &(struct s3c24xx_uart_info) {
|
||||
.name = "Samsung S3C2410 UART",
|
||||
.type = PORT_S3C2410,
|
||||
.type = TYPE_S3C24XX,
|
||||
.port_type = PORT_S3C2410,
|
||||
.fifosize = 16,
|
||||
.rx_fifomask = S3C2410_UFSTAT_RXMASK,
|
||||
.rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
|
||||
@ -2407,7 +2636,8 @@ static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
|
||||
static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
|
||||
.info = &(struct s3c24xx_uart_info) {
|
||||
.name = "Samsung S3C2412 UART",
|
||||
.type = PORT_S3C2412,
|
||||
.type = TYPE_S3C24XX,
|
||||
.port_type = PORT_S3C2412,
|
||||
.fifosize = 64,
|
||||
.has_divslot = 1,
|
||||
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
|
||||
@ -2436,7 +2666,8 @@ static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
|
||||
static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
|
||||
.info = &(struct s3c24xx_uart_info) {
|
||||
.name = "Samsung S3C2440 UART",
|
||||
.type = PORT_S3C2440,
|
||||
.type = TYPE_S3C24XX,
|
||||
.port_type = PORT_S3C2440,
|
||||
.fifosize = 64,
|
||||
.has_divslot = 1,
|
||||
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
|
||||
@ -2449,6 +2680,7 @@ static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
|
||||
.num_clks = 4,
|
||||
.clksel_mask = S3C2412_UCON_CLKMASK,
|
||||
.clksel_shift = S3C2412_UCON_CLKSHIFT,
|
||||
.ucon_mask = S3C2440_UCON0_DIVMASK,
|
||||
},
|
||||
.def_cfg = &(struct s3c2410_uartcfg) {
|
||||
.ucon = S3C2410_UCON_DEFAULT,
|
||||
@ -2464,7 +2696,8 @@ static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
|
||||
static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
|
||||
.info = &(struct s3c24xx_uart_info) {
|
||||
.name = "Samsung S3C6400 UART",
|
||||
.type = PORT_S3C6400,
|
||||
.type = TYPE_S3C6400,
|
||||
.port_type = PORT_S3C6400,
|
||||
.fifosize = 64,
|
||||
.has_divslot = 1,
|
||||
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
|
||||
@ -2492,7 +2725,8 @@ static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
|
||||
static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
|
||||
.info = &(struct s3c24xx_uart_info) {
|
||||
.name = "Samsung S5PV210 UART",
|
||||
.type = PORT_S3C6400,
|
||||
.type = TYPE_S3C6400,
|
||||
.port_type = PORT_S3C6400,
|
||||
.has_divslot = 1,
|
||||
.rx_fifomask = S5PV210_UFSTAT_RXMASK,
|
||||
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
|
||||
@ -2520,7 +2754,8 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
|
||||
#define EXYNOS_COMMON_SERIAL_DRV_DATA \
|
||||
.info = &(struct s3c24xx_uart_info) { \
|
||||
.name = "Samsung Exynos UART", \
|
||||
.type = PORT_S3C6400, \
|
||||
.type = TYPE_S3C6400, \
|
||||
.port_type = PORT_S3C6400, \
|
||||
.has_divslot = 1, \
|
||||
.rx_fifomask = S5PV210_UFSTAT_RXMASK, \
|
||||
.rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
|
||||
@ -2556,6 +2791,34 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
|
||||
#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_APPLE
|
||||
static struct s3c24xx_serial_drv_data s5l_serial_drv_data = {
|
||||
.info = &(struct s3c24xx_uart_info) {
|
||||
.name = "Apple S5L UART",
|
||||
.type = TYPE_APPLE_S5L,
|
||||
.port_type = PORT_8250,
|
||||
.fifosize = 16,
|
||||
.rx_fifomask = S3C2410_UFSTAT_RXMASK,
|
||||
.rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
|
||||
.rx_fifofull = S3C2410_UFSTAT_RXFULL,
|
||||
.tx_fifofull = S3C2410_UFSTAT_TXFULL,
|
||||
.tx_fifomask = S3C2410_UFSTAT_TXMASK,
|
||||
.tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
|
||||
.def_clk_sel = S3C2410_UCON_CLKSEL0,
|
||||
.num_clks = 1,
|
||||
.clksel_mask = 0,
|
||||
.clksel_shift = 0,
|
||||
},
|
||||
.def_cfg = &(struct s3c2410_uartcfg) {
|
||||
.ucon = APPLE_S5L_UCON_DEFAULT,
|
||||
.ufcon = S3C2410_UFCON_DEFAULT,
|
||||
},
|
||||
};
|
||||
#define S5L_SERIAL_DRV_DATA ((kernel_ulong_t)&s5l_serial_drv_data)
|
||||
#else
|
||||
#define S5L_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
|
||||
#endif
|
||||
|
||||
static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
|
||||
{
|
||||
.name = "s3c2410-uart",
|
||||
@ -2578,6 +2841,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
|
||||
}, {
|
||||
.name = "exynos5433-uart",
|
||||
.driver_data = EXYNOS5433_SERIAL_DRV_DATA,
|
||||
}, {
|
||||
.name = "s5l-uart",
|
||||
.driver_data = S5L_SERIAL_DRV_DATA,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
@ -2599,6 +2865,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = {
|
||||
.data = (void *)EXYNOS4210_SERIAL_DRV_DATA },
|
||||
{ .compatible = "samsung,exynos5433-uart",
|
||||
.data = (void *)EXYNOS5433_SERIAL_DRV_DATA },
|
||||
{ .compatible = "apple,s5l-uart",
|
||||
.data = (void *)S5L_SERIAL_DRV_DATA },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
|
||||
@ -2730,6 +2998,23 @@ OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart",
|
||||
s5pv210_early_console_setup);
|
||||
OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",
|
||||
s5pv210_early_console_setup);
|
||||
|
||||
/* Apple S5L */
|
||||
static int __init apple_s5l_early_console_setup(struct earlycon_device *device,
|
||||
const char *opt)
|
||||
{
|
||||
/* Close enough to S3C2410 for earlycon... */
|
||||
device->port.private_data = &s3c2410_early_console_data;
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
/* ... but we need to override the existing fixmap entry as nGnRnE */
|
||||
__set_fixmap(FIX_EARLYCON_MEM_BASE, device->port.mapbase,
|
||||
__pgprot(PROT_DEVICE_nGnRnE));
|
||||
#endif
|
||||
return samsung_early_console_setup(device, opt);
|
||||
}
|
||||
|
||||
OF_EARLYCON_DECLARE(s5l, "apple,s5l-uart", apple_s5l_early_console_setup);
|
||||
#endif
|
||||
|
||||
MODULE_ALIAS("platform:samsung-uart");
|
||||
|
@ -1196,7 +1196,7 @@ static int sc16is7xx_probe(struct device *dev,
|
||||
ret = regmap_read(regmap,
|
||||
SC16IS7XX_LSR_REG << SC16IS7XX_REG_SHIFT, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
/* Alloc port structure */
|
||||
s = devm_kzalloc(dev, struct_size(s, p, devtype->nr_uart), GFP_KERNEL);
|
||||
|
@ -759,8 +759,6 @@ static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo)
|
||||
struct uart_port *uport;
|
||||
int ret = -ENODEV;
|
||||
|
||||
memset(retinfo, 0, sizeof(*retinfo));
|
||||
|
||||
/*
|
||||
* Ensure the state we copy is consistent and no hardware changes
|
||||
* occur as we go
|
||||
@ -1305,7 +1303,7 @@ static int uart_set_rs485_config(struct uart_port *port,
|
||||
unsigned long flags;
|
||||
|
||||
if (!port->rs485_config)
|
||||
return -ENOIOCTLCMD;
|
||||
return -ENOTTY;
|
||||
|
||||
if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user)))
|
||||
return -EFAULT;
|
||||
@ -1329,7 +1327,7 @@ static int uart_get_iso7816_config(struct uart_port *port,
|
||||
struct serial_iso7816 aux;
|
||||
|
||||
if (!port->iso7816_config)
|
||||
return -ENOIOCTLCMD;
|
||||
return -ENOTTY;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
aux = port->iso7816;
|
||||
@ -1349,7 +1347,7 @@ static int uart_set_iso7816_config(struct uart_port *port,
|
||||
unsigned long flags;
|
||||
|
||||
if (!port->iso7816_config)
|
||||
return -ENOIOCTLCMD;
|
||||
return -ENOTTY;
|
||||
|
||||
if (copy_from_user(&iso7816, iso7816_user, sizeof(*iso7816_user)))
|
||||
return -EFAULT;
|
||||
|
@ -330,9 +330,9 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status)
|
||||
up->port.ignore_status_mask = next_ignore_status_mask;
|
||||
disr = sio_in(up, TXX9_SIDISR);
|
||||
} while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
|
||||
spin_unlock(&up->port.lock);
|
||||
|
||||
tty_flip_buffer_push(&up->port.state->port);
|
||||
spin_lock(&up->port.lock);
|
||||
|
||||
*status = disr;
|
||||
}
|
||||
|
||||
|
@ -2124,7 +2124,7 @@ static void sci_break_ctl(struct uart_port *port, int break_state)
|
||||
unsigned short scscr, scsptr;
|
||||
unsigned long flags;
|
||||
|
||||
/* check wheter the port has SCSPTR */
|
||||
/* check whether the port has SCSPTR */
|
||||
if (!sci_getreg(port, SCSPTR)->size) {
|
||||
/*
|
||||
* Not supported by hardware. Most parts couple break and rx
|
||||
@ -2609,21 +2609,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
udelay(DIV_ROUND_UP(10 * 1000000, baud));
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate delay for 2 DMA buffers (4 FIFO).
|
||||
* See serial_core.c::uart_update_timeout().
|
||||
* With 10 bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above
|
||||
* function calculates 1 jiffie for the data plus 5 jiffies for the
|
||||
* "slop(e)." Then below we calculate 5 jiffies (20ms) for 2 DMA
|
||||
* buffers (4 FIFO sizes), but when performing a faster transfer, the
|
||||
* value obtained by this formula is too small. Therefore, if the value
|
||||
* is smaller than 20ms, use 20ms as the timeout value for DMA.
|
||||
*/
|
||||
/* Calculate delay for 2 DMA buffers (4 FIFO). */
|
||||
s->rx_frame = (10000 * bits) / (baud / 100);
|
||||
#ifdef CONFIG_SERIAL_SH_SCI_DMA
|
||||
s->rx_timeout = s->buf_len_rx * 2 * s->rx_frame;
|
||||
if (s->rx_timeout < 20)
|
||||
s->rx_timeout = 20;
|
||||
#endif
|
||||
|
||||
if ((termios->c_cflag & CREAD) != 0)
|
||||
|
@ -448,9 +448,7 @@ static void __ssp_receive_chars(struct sifive_serial_port *ssp)
|
||||
uart_insert_char(&ssp->port, 0, 0, ch, TTY_NORMAL);
|
||||
}
|
||||
|
||||
spin_unlock(&ssp->port.lock);
|
||||
tty_flip_buffer_push(&ssp->port.state->port);
|
||||
spin_lock(&ssp->port.lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,8 +218,7 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded)
|
||||
u32 sr;
|
||||
char flag;
|
||||
|
||||
if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
|
||||
pm_wakeup_event(tport->tty->dev, 0);
|
||||
spin_lock(&port->lock);
|
||||
|
||||
while (stm32_usart_pending_rx(port, &sr, &stm32_port->last_res,
|
||||
threaded)) {
|
||||
@ -271,14 +270,14 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded)
|
||||
}
|
||||
}
|
||||
|
||||
if (uart_handle_sysrq_char(port, c))
|
||||
if (uart_prepare_sysrq_char(port, c))
|
||||
continue;
|
||||
uart_insert_char(port, sr, USART_SR_ORE, c, flag);
|
||||
}
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
uart_unlock_and_check_sysrq(port);
|
||||
|
||||
tty_flip_buffer_push(tport);
|
||||
spin_lock(&port->lock);
|
||||
}
|
||||
|
||||
static void stm32_usart_tx_dma_complete(void *arg)
|
||||
@ -286,12 +285,16 @@ static void stm32_usart_tx_dma_complete(void *arg)
|
||||
struct uart_port *port = arg;
|
||||
struct stm32_port *stm32port = to_stm32_port(port);
|
||||
const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
|
||||
unsigned long flags;
|
||||
|
||||
dmaengine_terminate_async(stm32port->tx_ch);
|
||||
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
|
||||
stm32port->tx_dma_busy = false;
|
||||
|
||||
/* Let's see if we have pending data to send */
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
stm32_usart_transmit_chars(port);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
static void stm32_usart_tx_interrupt_enable(struct uart_port *port)
|
||||
@ -303,7 +306,7 @@ static void stm32_usart_tx_interrupt_enable(struct uart_port *port)
|
||||
* Enables TX FIFO threashold irq when FIFO is enabled,
|
||||
* or TX empty irq when FIFO is disabled
|
||||
*/
|
||||
if (stm32_port->fifoen)
|
||||
if (stm32_port->fifoen && stm32_port->txftcfg >= 0)
|
||||
stm32_usart_set_bits(port, ofs->cr3, USART_CR3_TXFTIE);
|
||||
else
|
||||
stm32_usart_set_bits(port, ofs->cr1, USART_CR1_TXEIE);
|
||||
@ -314,7 +317,7 @@ static void stm32_usart_tx_interrupt_disable(struct uart_port *port)
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
|
||||
|
||||
if (stm32_port->fifoen)
|
||||
if (stm32_port->fifoen && stm32_port->txftcfg >= 0)
|
||||
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_TXFTIE);
|
||||
else
|
||||
stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TXEIE);
|
||||
@ -455,29 +458,34 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
|
||||
static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)
|
||||
{
|
||||
struct uart_port *port = ptr;
|
||||
struct tty_port *tport = &port->state->port;
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
|
||||
u32 sr;
|
||||
|
||||
spin_lock(&port->lock);
|
||||
|
||||
sr = readl_relaxed(port->membase + ofs->isr);
|
||||
|
||||
if ((sr & USART_SR_RTOF) && ofs->icr != UNDEF_REG)
|
||||
writel_relaxed(USART_ICR_RTOCF,
|
||||
port->membase + ofs->icr);
|
||||
|
||||
if ((sr & USART_SR_WUF) && ofs->icr != UNDEF_REG)
|
||||
if ((sr & USART_SR_WUF) && ofs->icr != UNDEF_REG) {
|
||||
/* Clear wake up flag and disable wake up interrupt */
|
||||
writel_relaxed(USART_ICR_WUCF,
|
||||
port->membase + ofs->icr);
|
||||
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_WUFIE);
|
||||
if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
|
||||
pm_wakeup_event(tport->tty->dev, 0);
|
||||
}
|
||||
|
||||
if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch))
|
||||
stm32_usart_receive_chars(port, false);
|
||||
|
||||
if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch))
|
||||
if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) {
|
||||
spin_lock(&port->lock);
|
||||
stm32_usart_transmit_chars(port);
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
spin_unlock(&port->lock);
|
||||
}
|
||||
|
||||
if (stm32_port->rx_ch)
|
||||
return IRQ_WAKE_THREAD;
|
||||
@ -490,13 +498,9 @@ static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr)
|
||||
struct uart_port *port = ptr;
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
|
||||
spin_lock(&port->lock);
|
||||
|
||||
if (stm32_port->rx_ch)
|
||||
stm32_usart_receive_chars(port, true);
|
||||
|
||||
spin_unlock(&port->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -505,7 +509,10 @@ static unsigned int stm32_usart_tx_empty(struct uart_port *port)
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
|
||||
|
||||
return readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE;
|
||||
if (readl_relaxed(port->membase + ofs->isr) & USART_SR_TC)
|
||||
return TIOCSER_TEMT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stm32_usart_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
@ -584,6 +591,19 @@ static void stm32_usart_start_tx(struct uart_port *port)
|
||||
stm32_usart_transmit_chars(port);
|
||||
}
|
||||
|
||||
/* Flush the transmit buffer. */
|
||||
static void stm32_usart_flush_buffer(struct uart_port *port)
|
||||
{
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
|
||||
|
||||
if (stm32_port->tx_ch) {
|
||||
dmaengine_terminate_async(stm32_port->tx_ch);
|
||||
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
|
||||
stm32_port->tx_dma_busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Throttle the remote when input buffer is about to overflow. */
|
||||
static void stm32_usart_throttle(struct uart_port *port)
|
||||
{
|
||||
@ -634,33 +654,30 @@ static int stm32_usart_startup(struct uart_port *port)
|
||||
{
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
|
||||
const struct stm32_usart_config *cfg = &stm32_port->info->cfg;
|
||||
const char *name = to_platform_device(port->dev)->name;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = request_threaded_irq(port->irq, stm32_usart_interrupt,
|
||||
stm32_usart_threaded_interrupt,
|
||||
IRQF_NO_SUSPEND, name, port);
|
||||
IRQF_ONESHOT | IRQF_NO_SUSPEND,
|
||||
name, port);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* RX FIFO Flush */
|
||||
if (ofs->rqr != UNDEF_REG)
|
||||
stm32_usart_set_bits(port, ofs->rqr, USART_RQR_RXFRQ);
|
||||
|
||||
/* Tx and RX FIFO configuration */
|
||||
if (stm32_port->fifoen) {
|
||||
val = readl_relaxed(port->membase + ofs->cr3);
|
||||
val &= ~(USART_CR3_TXFTCFG_MASK | USART_CR3_RXFTCFG_MASK);
|
||||
val |= USART_CR3_TXFTCFG_HALF << USART_CR3_TXFTCFG_SHIFT;
|
||||
val |= USART_CR3_RXFTCFG_HALF << USART_CR3_RXFTCFG_SHIFT;
|
||||
writel_relaxed(val, port->membase + ofs->cr3);
|
||||
if (stm32_port->swap) {
|
||||
val = readl_relaxed(port->membase + ofs->cr2);
|
||||
val |= USART_CR2_SWAP;
|
||||
writel_relaxed(val, port->membase + ofs->cr2);
|
||||
}
|
||||
|
||||
/* RX FIFO enabling */
|
||||
val = stm32_port->cr1_irq | USART_CR1_RE;
|
||||
if (stm32_port->fifoen)
|
||||
val |= USART_CR1_FIFOEN;
|
||||
/* RX FIFO Flush */
|
||||
if (ofs->rqr != UNDEF_REG)
|
||||
writel_relaxed(USART_RQR_RXFRQ, port->membase + ofs->rqr);
|
||||
|
||||
/* RX enabling */
|
||||
val = stm32_port->cr1_irq | USART_CR1_RE | BIT(cfg->uart_enable_bit);
|
||||
stm32_usart_set_bits(port, ofs->cr1, val);
|
||||
|
||||
return 0;
|
||||
@ -691,6 +708,11 @@ static void stm32_usart_shutdown(struct uart_port *port)
|
||||
if (ret)
|
||||
dev_err(port->dev, "Transmission is not complete\n");
|
||||
|
||||
/* flush RX & TX FIFO */
|
||||
if (ofs->rqr != UNDEF_REG)
|
||||
writel_relaxed(USART_RQR_TXFRQ | USART_RQR_RXFRQ,
|
||||
port->membase + ofs->rqr);
|
||||
|
||||
stm32_usart_clr_bits(port, ofs->cr1, val);
|
||||
|
||||
free_irq(port->irq, port);
|
||||
@ -737,8 +759,9 @@ static void stm32_usart_set_termios(struct uart_port *port,
|
||||
unsigned int baud, bits;
|
||||
u32 usartdiv, mantissa, fraction, oversampling;
|
||||
tcflag_t cflag = termios->c_cflag;
|
||||
u32 cr1, cr2, cr3;
|
||||
u32 cr1, cr2, cr3, isr;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (!stm32_port->hw_flow_control)
|
||||
cflag &= ~CRTSCTS;
|
||||
@ -747,21 +770,37 @@ static void stm32_usart_set_termios(struct uart_port *port,
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
|
||||
isr,
|
||||
(isr & USART_SR_TC),
|
||||
10, 100000);
|
||||
|
||||
/* Send the TC error message only when ISR_TC is not set. */
|
||||
if (ret)
|
||||
dev_err(port->dev, "Transmission is not complete\n");
|
||||
|
||||
/* Stop serial port and reset value */
|
||||
writel_relaxed(0, port->membase + ofs->cr1);
|
||||
|
||||
/* flush RX & TX FIFO */
|
||||
if (ofs->rqr != UNDEF_REG)
|
||||
stm32_usart_set_bits(port, ofs->rqr,
|
||||
USART_RQR_TXFRQ | USART_RQR_RXFRQ);
|
||||
writel_relaxed(USART_RQR_TXFRQ | USART_RQR_RXFRQ,
|
||||
port->membase + ofs->rqr);
|
||||
|
||||
cr1 = USART_CR1_TE | USART_CR1_RE;
|
||||
if (stm32_port->fifoen)
|
||||
cr1 |= USART_CR1_FIFOEN;
|
||||
cr2 = 0;
|
||||
cr2 = stm32_port->swap ? USART_CR2_SWAP : 0;
|
||||
|
||||
/* Tx and RX FIFO configuration */
|
||||
cr3 = readl_relaxed(port->membase + ofs->cr3);
|
||||
cr3 &= USART_CR3_TXFTIE | USART_CR3_RXFTCFG_MASK | USART_CR3_RXFTIE
|
||||
| USART_CR3_TXFTCFG_MASK;
|
||||
cr3 &= USART_CR3_TXFTIE | USART_CR3_RXFTIE;
|
||||
if (stm32_port->fifoen) {
|
||||
if (stm32_port->txftcfg >= 0)
|
||||
cr3 |= stm32_port->txftcfg << USART_CR3_TXFTCFG_SHIFT;
|
||||
if (stm32_port->rxftcfg >= 0)
|
||||
cr3 |= stm32_port->rxftcfg << USART_CR3_RXFTCFG_SHIFT;
|
||||
}
|
||||
|
||||
if (cflag & CSTOPB)
|
||||
cr2 |= USART_CR2_STOP_2B;
|
||||
@ -790,7 +829,8 @@ static void stm32_usart_set_termios(struct uart_port *port,
|
||||
, bits);
|
||||
|
||||
if (ofs->rtor != UNDEF_REG && (stm32_port->rx_ch ||
|
||||
stm32_port->fifoen)) {
|
||||
(stm32_port->fifoen &&
|
||||
stm32_port->rxftcfg >= 0))) {
|
||||
if (cflag & CSTOPB)
|
||||
bits = bits + 3; /* 1 start bit + 2 stop bits */
|
||||
else
|
||||
@ -817,12 +857,6 @@ static void stm32_usart_set_termios(struct uart_port *port,
|
||||
cr3 |= USART_CR3_CTSE | USART_CR3_RTSE;
|
||||
}
|
||||
|
||||
/* Handle modem control interrupts */
|
||||
if (UART_ENABLE_MS(port, termios->c_cflag))
|
||||
stm32_usart_enable_ms(port);
|
||||
else
|
||||
stm32_usart_disable_ms(port);
|
||||
|
||||
usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud);
|
||||
|
||||
/*
|
||||
@ -892,12 +926,24 @@ static void stm32_usart_set_termios(struct uart_port *port,
|
||||
cr1 &= ~(USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK);
|
||||
}
|
||||
|
||||
/* Configure wake up from low power on start bit detection */
|
||||
if (stm32_port->wakeup_src) {
|
||||
cr3 &= ~USART_CR3_WUS_MASK;
|
||||
cr3 |= USART_CR3_WUS_START_BIT;
|
||||
}
|
||||
|
||||
writel_relaxed(cr3, port->membase + ofs->cr3);
|
||||
writel_relaxed(cr2, port->membase + ofs->cr2);
|
||||
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);
|
||||
|
||||
/* Handle modem control interrupts */
|
||||
if (UART_ENABLE_MS(port, termios->c_cflag))
|
||||
stm32_usart_enable_ms(port);
|
||||
else
|
||||
stm32_usart_disable_ms(port);
|
||||
}
|
||||
|
||||
static const char *stm32_usart_type(struct uart_port *port)
|
||||
@ -962,6 +1008,7 @@ static const struct uart_ops stm32_uart_ops = {
|
||||
.break_ctl = stm32_usart_break_ctl,
|
||||
.startup = stm32_usart_startup,
|
||||
.shutdown = stm32_usart_shutdown,
|
||||
.flush_buffer = stm32_usart_flush_buffer,
|
||||
.set_termios = stm32_usart_set_termios,
|
||||
.pm = stm32_usart_pm,
|
||||
.type = stm32_usart_type,
|
||||
@ -971,6 +1018,39 @@ static const struct uart_ops stm32_uart_ops = {
|
||||
.verify_port = stm32_usart_verify_port,
|
||||
};
|
||||
|
||||
/*
|
||||
* STM32H7 RX & TX FIFO threshold configuration (CR3 RXFTCFG / TXFTCFG)
|
||||
* Note: 1 isn't a valid value in RXFTCFG / TXFTCFG. In this case,
|
||||
* RXNEIE / TXEIE can be used instead of threshold irqs: RXFTIE / TXFTIE.
|
||||
* So, RXFTCFG / TXFTCFG bitfields values are encoded as array index + 1.
|
||||
*/
|
||||
static const u32 stm32h7_usart_fifo_thresh_cfg[] = { 1, 2, 4, 8, 12, 14, 16 };
|
||||
|
||||
static void stm32_usart_get_ftcfg(struct platform_device *pdev, const char *p,
|
||||
int *ftcfg)
|
||||
{
|
||||
u32 bytes, i;
|
||||
|
||||
/* DT option to get RX & TX FIFO threshold (default to 8 bytes) */
|
||||
if (of_property_read_u32(pdev->dev.of_node, p, &bytes))
|
||||
bytes = 8;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg); i++)
|
||||
if (stm32h7_usart_fifo_thresh_cfg[i] >= bytes)
|
||||
break;
|
||||
if (i >= ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg))
|
||||
i = ARRAY_SIZE(stm32h7_usart_fifo_thresh_cfg) - 1;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s set to %d bytes\n", p,
|
||||
stm32h7_usart_fifo_thresh_cfg[i]);
|
||||
|
||||
/* Provide FIFO threshold ftcfg (1 is invalid: threshold irq unused) */
|
||||
if (i)
|
||||
*ftcfg = i - 1;
|
||||
else
|
||||
*ftcfg = -EINVAL;
|
||||
}
|
||||
|
||||
static void stm32_usart_deinit_port(struct stm32_port *stm32port)
|
||||
{
|
||||
clk_disable_unprepare(stm32port->clk);
|
||||
@ -1000,13 +1080,19 @@ static int stm32_usart_init_port(struct stm32_port *stm32port,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (stm32port->info->cfg.has_wakeup) {
|
||||
stm32port->wakeirq = platform_get_irq_optional(pdev, 1);
|
||||
if (stm32port->wakeirq <= 0 && stm32port->wakeirq != -ENXIO)
|
||||
return stm32port->wakeirq ? : -ENODEV;
|
||||
}
|
||||
stm32port->wakeup_src = stm32port->info->cfg.has_wakeup &&
|
||||
of_property_read_bool(pdev->dev.of_node, "wakeup-source");
|
||||
|
||||
stm32port->swap = stm32port->info->cfg.has_swap &&
|
||||
of_property_read_bool(pdev->dev.of_node, "rx-tx-swap");
|
||||
|
||||
stm32port->fifoen = stm32port->info->cfg.has_fifo;
|
||||
if (stm32port->fifoen) {
|
||||
stm32_usart_get_ftcfg(pdev, "rx-threshold",
|
||||
&stm32port->rxftcfg);
|
||||
stm32_usart_get_ftcfg(pdev, "tx-threshold",
|
||||
&stm32port->txftcfg);
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
port->membase = devm_ioremap_resource(&pdev->dev, res);
|
||||
@ -1106,6 +1192,13 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port,
|
||||
struct dma_async_tx_descriptor *desc = NULL;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Using DMA and threaded handler for the console could lead to
|
||||
* deadlocks.
|
||||
*/
|
||||
if (uart_console(port))
|
||||
return -ENODEV;
|
||||
|
||||
/* Request DMA RX channel */
|
||||
stm32port->rx_ch = dma_request_slave_channel(dev, "rx");
|
||||
if (!stm32port->rx_ch) {
|
||||
@ -1239,23 +1332,13 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (stm32port->wakeirq > 0) {
|
||||
ret = device_init_wakeup(&pdev->dev, true);
|
||||
if (ret)
|
||||
goto err_uninit;
|
||||
|
||||
ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
|
||||
stm32port->wakeirq);
|
||||
if (stm32port->wakeup_src) {
|
||||
device_set_wakeup_capable(&pdev->dev, true);
|
||||
ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq);
|
||||
if (ret)
|
||||
goto err_nowup;
|
||||
|
||||
device_set_wakeup_enable(&pdev->dev, false);
|
||||
}
|
||||
|
||||
ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port);
|
||||
if (ret)
|
||||
goto err_wirq;
|
||||
|
||||
ret = stm32_usart_of_dma_rx_probe(stm32port, pdev);
|
||||
if (ret)
|
||||
dev_info(&pdev->dev, "interrupt mode used for rx (no dma)\n");
|
||||
@ -1269,19 +1352,47 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port);
|
||||
if (ret)
|
||||
goto err_port;
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_wirq:
|
||||
if (stm32port->wakeirq > 0)
|
||||
err_port:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
|
||||
if (stm32port->rx_ch) {
|
||||
dmaengine_terminate_async(stm32port->rx_ch);
|
||||
dma_release_channel(stm32port->rx_ch);
|
||||
}
|
||||
|
||||
if (stm32port->rx_dma_buf)
|
||||
dma_free_coherent(&pdev->dev,
|
||||
RX_BUF_L, stm32port->rx_buf,
|
||||
stm32port->rx_dma_buf);
|
||||
|
||||
if (stm32port->tx_ch) {
|
||||
dmaengine_terminate_async(stm32port->tx_ch);
|
||||
dma_release_channel(stm32port->tx_ch);
|
||||
}
|
||||
|
||||
if (stm32port->tx_dma_buf)
|
||||
dma_free_coherent(&pdev->dev,
|
||||
TX_BUF_L, stm32port->tx_buf,
|
||||
stm32port->tx_dma_buf);
|
||||
|
||||
if (stm32port->wakeup_src)
|
||||
dev_pm_clear_wake_irq(&pdev->dev);
|
||||
|
||||
err_nowup:
|
||||
if (stm32port->wakeirq > 0)
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
if (stm32port->wakeup_src)
|
||||
device_set_wakeup_capable(&pdev->dev, false);
|
||||
|
||||
err_uninit:
|
||||
stm32_usart_deinit_port(stm32port);
|
||||
|
||||
return ret;
|
||||
@ -1295,11 +1406,20 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)
|
||||
int err;
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
err = uart_remove_one_port(&stm32_usart_driver, port);
|
||||
if (err)
|
||||
return(err);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
|
||||
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR);
|
||||
|
||||
if (stm32_port->rx_ch)
|
||||
if (stm32_port->rx_ch) {
|
||||
dmaengine_terminate_async(stm32_port->rx_ch);
|
||||
dma_release_channel(stm32_port->rx_ch);
|
||||
}
|
||||
|
||||
if (stm32_port->rx_dma_buf)
|
||||
dma_free_coherent(&pdev->dev,
|
||||
@ -1308,27 +1428,24 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)
|
||||
|
||||
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
|
||||
|
||||
if (stm32_port->tx_ch)
|
||||
if (stm32_port->tx_ch) {
|
||||
dmaengine_terminate_async(stm32_port->tx_ch);
|
||||
dma_release_channel(stm32_port->tx_ch);
|
||||
}
|
||||
|
||||
if (stm32_port->tx_dma_buf)
|
||||
dma_free_coherent(&pdev->dev,
|
||||
TX_BUF_L, stm32_port->tx_buf,
|
||||
stm32_port->tx_dma_buf);
|
||||
|
||||
if (stm32_port->wakeirq > 0) {
|
||||
if (stm32_port->wakeup_src) {
|
||||
dev_pm_clear_wake_irq(&pdev->dev);
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
}
|
||||
|
||||
stm32_usart_deinit_port(stm32_port);
|
||||
|
||||
err = uart_remove_one_port(&stm32_usart_driver, port);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_STM32_CONSOLE
|
||||
@ -1354,13 +1471,10 @@ static void stm32_usart_console_write(struct console *co, const char *s,
|
||||
u32 old_cr1, new_cr1;
|
||||
int locked = 1;
|
||||
|
||||
local_irq_save(flags);
|
||||
if (port->sysrq)
|
||||
locked = 0;
|
||||
else if (oops_in_progress)
|
||||
locked = spin_trylock(&port->lock);
|
||||
if (oops_in_progress)
|
||||
locked = spin_trylock_irqsave(&port->lock, flags);
|
||||
else
|
||||
spin_lock(&port->lock);
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
/* Save and disable interrupts, enable the transmitter */
|
||||
old_cr1 = readl_relaxed(port->membase + ofs->cr1);
|
||||
@ -1374,8 +1488,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(&port->lock);
|
||||
local_irq_restore(flags);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
static int stm32_usart_console_setup(struct console *co, char *options)
|
||||
@ -1436,23 +1549,20 @@ static void __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port,
|
||||
{
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
|
||||
const struct stm32_usart_config *cfg = &stm32_port->info->cfg;
|
||||
u32 val;
|
||||
|
||||
if (stm32_port->wakeirq <= 0)
|
||||
if (!stm32_port->wakeup_src)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Enable low-power wake-up and wake-up irq if argument is set to
|
||||
* "enable", disable low-power wake-up and wake-up irq otherwise
|
||||
*/
|
||||
if (enable) {
|
||||
stm32_usart_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
|
||||
stm32_usart_set_bits(port, ofs->cr1, USART_CR1_UESM);
|
||||
val = readl_relaxed(port->membase + ofs->cr3);
|
||||
val &= ~USART_CR3_WUS_MASK;
|
||||
/* Enable Wake up interrupt from low power on start bit */
|
||||
val |= USART_CR3_WUS_START_BIT | USART_CR3_WUFIE;
|
||||
writel_relaxed(val, port->membase + ofs->cr3);
|
||||
stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
|
||||
stm32_usart_set_bits(port, ofs->cr3, USART_CR3_WUFIE);
|
||||
} else {
|
||||
stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_UESM);
|
||||
stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_WUFIE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1462,10 +1572,8 @@ static int __maybe_unused stm32_usart_serial_suspend(struct device *dev)
|
||||
|
||||
uart_suspend_port(&stm32_usart_driver, port);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
if (device_may_wakeup(dev) || device_wakeup_path(dev))
|
||||
stm32_usart_serial_en_wakeup(port, true);
|
||||
else
|
||||
stm32_usart_serial_en_wakeup(port, false);
|
||||
|
||||
/*
|
||||
* When "no_console_suspend" is enabled, keep the pinctrl default state
|
||||
@ -1474,7 +1582,7 @@ static int __maybe_unused stm32_usart_serial_suspend(struct device *dev)
|
||||
* capabilities.
|
||||
*/
|
||||
if (console_suspend_enabled || !uart_console(port)) {
|
||||
if (device_may_wakeup(dev))
|
||||
if (device_may_wakeup(dev) || device_wakeup_path(dev))
|
||||
pinctrl_pm_select_idle_state(dev);
|
||||
else
|
||||
pinctrl_pm_select_sleep_state(dev);
|
||||
@ -1489,7 +1597,7 @@ static int __maybe_unused stm32_usart_serial_resume(struct device *dev)
|
||||
|
||||
pinctrl_pm_select_default_state(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
if (device_may_wakeup(dev) || device_wakeup_path(dev))
|
||||
stm32_usart_serial_en_wakeup(port, false);
|
||||
|
||||
return uart_resume_port(&stm32_usart_driver, port);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user