Commit b3a5e648 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tty-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial updates from Greg KH:
 "Here is the "big" set of tty/serial driver patches for 5.2-rc1.

  It's really pretty small, not much happening in this portion of the
  kernel at the moment. When the "highlight" is the movement of the
  documentation from .txt to .rst files, it's a good merge window.

  There's a number of small fixes and updates over the various serial
  drivers, and a new "tty null" driver for those embedded systems that
  like to make things even smaller and not break things.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'tty-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (45 commits)
  tty: serial: add driver for the SiFive UART
  dt-bindings: serial: add documentation for the SiFive UART driver
  serial: uartps: Add support for cts-override
  dt-bindings: xilinx-uartps: Add support for cts-override
  serial: milbeaut_usio: Fix error handling in probe and remove
  tty: rocket: deprecate the rp_ioctl
  tty: rocket: Remove RCPK_GET_STRUCT ioctl
  tty: update obsolete termios comment
  tty: serial_core: fix error code returned by uart_register_driver()
  serial: 8250-mtk: modify baudrate setting
  serial: 8250-mtk: add follow control
  docs: serial: convert docs to ReST and rename to *.rst
  serial: 8250_exar: Adjust IOT2000 matching
  TTY: serial_core, add ->install
  serial: Fix using plain integer instead of Null pointer
  tty:serial_core: Spelling mistake
  tty: Add NULL TTY driver
  tty: vt: keyboard: Allow Unicode compose base char
  Revert "tty: fix NULL pointer issue when tty_port ops is not set"
  serial: Add Milbeaut serial control
  ...
parents 132d68d3 45c054d0
...@@ -12,6 +12,11 @@ Required properties: ...@@ -12,6 +12,11 @@ Required properties:
See ../clocks/clock-bindings.txt for details. See ../clocks/clock-bindings.txt for details.
Optional properties:
- cts-override : Override the CTS modem status signal. This signal will
always be reported as active instead of being obtained from the modem status
register. Define this if your serial port does not use this pin
Example: Example:
uart@e0000000 { uart@e0000000 {
compatible = "cdns,uart-r1p8"; compatible = "cdns,uart-r1p8";
......
...@@ -12,6 +12,8 @@ Required properties: ...@@ -12,6 +12,8 @@ Required properties:
- reg: I2C address of the SC16IS7xx device. - reg: I2C address of the SC16IS7xx device.
- interrupts: Should contain the UART interrupt - interrupts: Should contain the UART interrupt
- clocks: Reference to the IC source clock. - clocks: Reference to the IC source clock.
OR (when there is no clock provider visible to the platform)
- clock-frequency: The source clock frequency for the IC.
Optional properties: Optional properties:
- gpio-controller: Marks the device node as a GPIO controller. - gpio-controller: Marks the device node as a GPIO controller.
......
SiFive asynchronous serial interface (UART)
Required properties:
- compatible: should be something similar to
"sifive,<chip>-uart" for the UART as integrated
on a particular chip, and "sifive,uart<version>" for the
general UART IP block programming model. Supported
compatible strings as of the date of this writing are:
"sifive,fu540-c000-uart" for the SiFive UART v0 as
integrated onto the SiFive FU540 chip, or "sifive,uart0"
for the SiFive UART v0 IP block with no chip integration
tweaks (if any)
- reg: address and length of the register space
- interrupts: Should contain the UART interrupt identifier
- clocks: Should contain a clock identifier for the UART's parent clock
UART HDL that corresponds to the IP block version numbers can be found
here:
https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/uart
Example:
uart0: serial@10010000 {
compatible = "sifive,fu540-c000-uart", "sifive,uart0";
interrupt-parent = <&plic0>;
interrupts = <80>;
reg = <0x0 0x10010000 0x0 0x1000>;
clocks = <&prci PRCI_CLK_TLCLK>;
};
...@@ -7,7 +7,17 @@ Required properties: ...@@ -7,7 +7,17 @@ Required properties:
- reg: offset and length of the register set for the device - reg: offset and length of the register set for the device
- interrupts: exactly one interrupt specifier - interrupts: exactly one interrupt specifier
- clocks: phandles to input clocks. - clock-names: Should contain following entries:
"enable" for UART module enable clock,
"uart" for UART clock,
"source" for UART source (parent) clock.
- clocks: Should contain a clock specifier for each entry in clock-names.
UART clock and source clock are optional properties, but enable clock
is required.
Optional properties:
- dma-names: Should contain "rx" for receive and "tx" for transmit channels.
- dmas: A list of dma specifiers, one for each entry in dma-names.
Example: Example:
uart0: serial@0 { uart0: serial@0 {
...@@ -15,5 +25,8 @@ Example: ...@@ -15,5 +25,8 @@ Example:
"sprd,sc9836-uart"; "sprd,sc9836-uart";
reg = <0x0 0x100>; reg = <0x0 0x100>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ext_26m>; dma-names = "rx", "tx";
dmas = <&ap_dma 19>, <&ap_dma 20>;
clock-names = "enable", "uart", "source";
clocks = <&clk_ap_apb_gates 9>, <&clk_uart0>, <&ext_26m>;
}; };
================
Cyclades-Z notes
================
The Cyclades-Z must have firmware loaded onto the card before it will The Cyclades-Z must have firmware loaded onto the card before it will
operate. This operation should be performed during system startup, operate. This operation should be performed during system startup,
The firmware, loader program and the latest device driver code are The firmware, loader program and the latest device driver code are
available from Cyclades at available from Cyclades at
ftp://ftp.cyclades.com/pub/cyclades/cyclades-z/linux/
ftp://ftp.cyclades.com/pub/cyclades/cyclades-z/linux/
:orphan:
==========================
Support for Serial devices
==========================
.. toctree::
:maxdepth: 1
driver
tty
Serial drivers
==============
.. toctree::
:maxdepth: 1
cyclades_z
moxa-smartio
n_gsm
rocket
serial-iso7816
serial-rs485
.. only:: subproject and html
Indices
=======
* :ref:`genindex`
n_gsm.c GSM 0710 tty multiplexor HOWTO ==============================
=================================================== GSM 0710 tty multiplexor HOWTO
==============================
This line discipline implements the GSM 07.10 multiplexing protocol This line discipline implements the GSM 07.10 multiplexing protocol
detailed in the following 3GPP document : detailed in the following 3GPP document:
http://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
http://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
This document give some hints on how to use this driver with GPRS and 3G This document give some hints on how to use this driver with GPRS and 3G
modems connected to a physical serial port. modems connected to a physical serial port.
How to use it How to use it
------------- -------------
1- initialize the modem in 0710 mux mode (usually AT+CMUX= command) through 1. initialize the modem in 0710 mux mode (usually AT+CMUX= command) through
its serial port. Depending on the modem used, you can pass more or less its serial port. Depending on the modem used, you can pass more or less
parameters to this command, parameters to this command,
2- switch the serial line to using the n_gsm line discipline by using 2. switch the serial line to using the n_gsm line discipline by using
TIOCSETD ioctl, TIOCSETD ioctl,
3- configure the mux using GSMIOC_GETCONF / GSMIOC_SETCONF ioctl, 3. configure the mux using GSMIOC_GETCONF / GSMIOC_SETCONF ioctl,
Major parts of the initialization program : Major parts of the initialization program :
(a good starting point is util-linux-ng/sys-utils/ldattach.c) (a good starting point is util-linux-ng/sys-utils/ldattach.c)::
#include <linux/gsmmux.h>
#define N_GSM0710 21 /* GSM 0710 Mux */ #include <linux/gsmmux.h>
#define DEFAULT_SPEED B115200 #define N_GSM0710 21 /* GSM 0710 Mux */
#define SERIAL_PORT /dev/ttyS0 #define DEFAULT_SPEED B115200
#define SERIAL_PORT /dev/ttyS0
int ldisc = N_GSM0710; int ldisc = N_GSM0710;
struct gsm_config c; struct gsm_config c;
...@@ -60,37 +63,41 @@ Major parts of the initialization program : ...@@ -60,37 +63,41 @@ Major parts of the initialization program :
daemon(0,0); daemon(0,0);
pause(); pause();
4- create the devices corresponding to the "virtual" serial ports (take care, 4. create the devices corresponding to the "virtual" serial ports (take care,
each modem has its configuration and some DLC have dedicated functions, each modem has its configuration and some DLC have dedicated functions,
for example GPS), starting with minor 1 (DLC0 is reserved for the management for example GPS), starting with minor 1 (DLC0 is reserved for the management
of the mux) of the mux)::
MAJOR=`cat /proc/devices |grep gsmtty | awk '{print $1}` MAJOR=`cat /proc/devices |grep gsmtty | awk '{print $1}`
for i in `seq 1 4`; do for i in `seq 1 4`; do
mknod /dev/ttygsm$i c $MAJOR $i mknod /dev/ttygsm$i c $MAJOR $i
done done
5. use these devices as plain serial ports.
5- use these devices as plain serial ports. for example, it's possible:
for example, it's possible :
- and to use gnokii to send / receive SMS on ttygsm1
- to use ppp to establish a datalink on ttygsm2
6- first close all virtual ports before closing the physical port. - and to use gnokii to send / receive SMS on ttygsm1
- to use ppp to establish a datalink on ttygsm2
Note that after closing the physical port the modem is still in multiplexing 6. first close all virtual ports before closing the physical port.
mode. This may prevent a successful re-opening of the port later. To avoid
this situation either reset the modem if your hardware allows that or send Note that after closing the physical port the modem is still in multiplexing
a disconnect command frame manually before initializing the multiplexing mode mode. This may prevent a successful re-opening of the port later. To avoid
for the second time. The byte sequence for the disconnect command frame is: this situation either reset the modem if your hardware allows that or send
0xf9, 0x03, 0xef, 0x03, 0xc3, 0x16, 0xf9. a disconnect command frame manually before initializing the multiplexing mode
for the second time. The byte sequence for the disconnect command frame is::
0xf9, 0x03, 0xef, 0x03, 0xc3, 0x16, 0xf9.
Additional Documentation Additional Documentation
------------------------ ------------------------
More practical details on the protocol and how it's supported by industrial More practical details on the protocol and how it's supported by industrial
modems can be found in the following documents : modems can be found in the following documents :
http://www.telit.com/module/infopool/download.php?id=616
http://www.u-blox.com/images/downloads/Product_Docs/LEON-G100-G200-MuxImplementation_ApplicationNote_%28GSM%20G1-CS-10002%29.pdf - http://www.telit.com/module/infopool/download.php?id=616
http://www.sierrawireless.com/Support/Downloads/AirPrime/WMP_Series/~/media/Support_Downloads/AirPrime/Application_notes/CMUX_Feature_Application_Note-Rev004.ashx - http://www.u-blox.com/images/downloads/Product_Docs/LEON-G100-G200-MuxImplementation_ApplicationNote_%28GSM%20G1-CS-10002%29.pdf
http://wm.sim.com/sim/News/photo/2010721161442.pdf - http://www.sierrawireless.com/Support/Downloads/AirPrime/WMP_Series/~/media/Support_Downloads/AirPrime/Application_notes/CMUX_Feature_Application_Note-Rev004.ashx
- http://wm.sim.com/sim/News/photo/2010721161442.pdf
11-03-08 - Eric Bénard - <eric@eukrea.com> 11-03-08 - Eric Bénard - <eric@eukrea.com>
Comtrol(tm) RocketPort(R)/RocketModem(TM) Series ================================================
Device Driver for the Linux Operating System Comtrol(tm) RocketPort(R)/RocketModem(TM) Series
================================================
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Device Driver for the Linux Operating System
============================================
PRODUCT OVERVIEW Product overview
---------------- ----------------
This driver provides a loadable kernel driver for the Comtrol RocketPort This driver provides a loadable kernel driver for the Comtrol RocketPort
and RocketModem PCI boards. These boards provide, 2, 4, 8, 16, or 32 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 high-speed serial ports or modems. This driver supports up to a combination
of four RocketPort or RocketModems boards in one machine simultaneously. of four RocketPort or RocketModems boards in one machine simultaneously.
This file assumes that you are using the RocketPort driver which is This file assumes that you are using the RocketPort driver which is
integrated into the kernel sources. integrated into the kernel sources.
The driver can also be installed as an external module using the usual The driver can also be installed as an external module using the usual
"make;make install" routine. This external module driver, obtainable "make;make install" routine. This external module driver, obtainable
from the Comtrol website listed below, is useful for updating the driver from the Comtrol website listed below, is useful for updating the driver
or installing it into kernels which do not have the driver configured or installing it into kernels which do not have the driver configured
into them. Installations instructions for the external module into them. Installations instructions for the external module
...@@ -29,57 +31,59 @@ information on how to set the DIP switches. ...@@ -29,57 +31,59 @@ information on how to set the DIP switches.
You pass the I/O port to the driver using the following module parameters: You pass the I/O port to the driver using the following module parameters:
board1 : I/O port for the first ISA board board1:
board2 : I/O port for the second ISA board I/O port for the first ISA board
board3 : I/O port for the third ISA board board2:
board4 : I/O port for the fourth ISA board 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 There is a set of utilities and scripts provided with the external driver
( downloadable from http://www.comtrol.com ) that ease the configuration and (downloadable from http://www.comtrol.com) that ease the configuration and
setup of the ISA cards. setup of the ISA cards.
The RocketModem II PCI boards require firmware to be loaded into the card 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 before it will function. The driver has only been tested as a module for this
board. board.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Installation Procedures
INSTALLATION PROCEDURES
----------------------- -----------------------
RocketPort/RocketModem PCI cards require no driver configuration, they are RocketPort/RocketModem PCI cards require no driver configuration, they are
automatically detected and configured. automatically detected and configured.
The RocketPort driver can be installed as a module (recommended) or built 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` 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. 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 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 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 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 installed in the system, the mapping of port names to serial ports is displayed
in the system log at /var/log/messages. in the system log at /var/log/messages.
If installed as a module, the module must be loaded. This can be done 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 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 upon system boot, edit a `/etc/modprobe.d/*.conf` file and add the line
"alias char-major-46 rocket". "alias char-major-46 rocket".
In order to use the ports, their device names (nodes) must be created with mknod. 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 This is only required once, the system will retain the names once created. To
create the RocketPort/RocketModem device names, use the command 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/ttyRx c 46 x" where x is the port number starting at zero.
>mknod /dev/ttyR0 c 46 0 For example::
>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) > mknod /dev/ttyR0 c 46 0
for you: > mknod /dev/ttyR1 c 46 1
> mknod /dev/ttyR2 c 46 2
>/dev/MAKEDEV ttyR The Linux script MAKEDEV will create the first 16 ttyRx device names (nodes)
for you::
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- >/dev/MAKEDEV ttyR
ISA Rocketport Boards ISA Rocketport Boards
--------------------- ---------------------
...@@ -89,7 +93,7 @@ card before installing and using it. This is done by setting a set of DIP ...@@ -89,7 +93,7 @@ card before installing and using it. This is done by setting a set of DIP
switches on the Rocketport board. switches on the Rocketport board.
SETTING THE I/O ADDRESS Setting the I/O address
----------------------- -----------------------
Before installing RocketPort(R) or RocketPort RA boards, you must find Before installing RocketPort(R) or RocketPort RA boards, you must find
...@@ -130,40 +134,36 @@ the first 4 bytes of that range are used by the first board. You would ...@@ -130,40 +134,36 @@ 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 need to set the second, third, or fourth board to one of the next available
blocks such as 0x180. blocks such as 0x180.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- RocketPort and RocketPort RA SW1 Settings::
RocketPort and RocketPort RA SW1 Settings: +-------------------------------+
| 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+-------------------------------+ +-------+-------+---------------+
| 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | | Unused| Card | I/O Port Block|
+-------+-------+---------------+ +-------------------------------+
| Unused| Card | I/O Port Block|
+-------------------------------+ DIP Switches DIP Switches
7 8 6 5
DIP Switches DIP Switches =================== ===================
7 8 6 5 On On UNUSED, MUST BE ON. On On First Card <==== Default
=================== =================== On Off Second Card
On On UNUSED, MUST BE ON. On On First Card <==== Default Off On Third Card
On Off Second Card Off Off Fourth Card
Off On Third Card
Off Off Fourth Card DIP Switches I/O Address Range
4 3 2 1 Used by the First 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 On Off 100-143 On Off Off Off 180-1C3 <==== Default
On Off Off On 140-183 Off On On Off 200-243
On Off Off Off 180-1C3 <==== Default Off On Off On 240-283
Off On On Off 200-243 Off On Off Off 280-2C3
Off On Off On 240-283 Off Off On Off 300-343
Off On Off Off 280-2C3 Off Off Off On 340-383
Off Off On Off 300-343 Off Off Off Off 380-3C3
Off Off Off On 340-383
Off Off Off Off 380-3C3 Reporting Bugs
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
REPORTING BUGS
-------------- --------------
For technical support, please provide the following For technical support, please provide the following
...@@ -171,19 +171,15 @@ information: Driver version, kernel release, distribution of ...@@ -171,19 +171,15 @@ information: Driver version, kernel release, distribution of
kernel, and type of board you are using. Error messages and log kernel, and type of board you are using. Error messages and log
printouts port configuration details are especially helpful. printouts port configuration details are especially helpful.
USA USA:
Phone: (612) 494-4100 :Phone: (612) 494-4100
FAX: (612) 494-4199 :FAX: (612) 494-4199
email: support@comtrol.com :email: support@comtrol.com
Comtrol Europe Comtrol Europe:
Phone: +44 (0) 1 869 323-220 :Phone: +44 (0) 1 869 323-220
FAX: +44 (0) 1 869 323-211 :FAX: +44 (0) 1 869 323-211
email: support@comtrol.co.uk :email: support@comtrol.co.uk
Web: http://www.comtrol.com Web: http://www.comtrol.com
FTP: ftp.comtrol.com FTP: ftp.comtrol.com
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
ISO7816 SERIAL COMMUNICATIONS =============================
ISO7816 Serial Communications
=============================
1. INTRODUCTION 1. Introduction
===============
ISO/IEC7816 is a series of standards specifying integrated circuit cards (ICC) ISO/IEC7816 is a series of standards specifying integrated circuit cards (ICC)
also known as smart cards. also known as smart cards.
2. HARDWARE-RELATED CONSIDERATIONS 2. Hardware-related considerations
==================================
Some CPUs/UARTs (e.g., Microchip AT91) contain a built-in mode capable of Some CPUs/UARTs (e.g., Microchip AT91) contain a built-in mode capable of
handling communication with a smart card. handling communication with a smart card.
...@@ -15,7 +19,8 @@ ...@@ -15,7 +19,8 @@
available at user-level to allow switching from one mode to the other, and available at user-level to allow switching from one mode to the other, and
vice versa. vice versa.
3. DATA STRUCTURES ALREADY AVAILABLE IN THE KERNEL 3. Data Structures Already Available in the Kernel
==================================================
The Linux kernel provides the serial_iso7816 structure (see [1]) to handle The Linux kernel provides the serial_iso7816 structure (see [1]) to handle
ISO7816 communications. This data structure is used to set and configure ISO7816 communications. This data structure is used to set and configure
...@@ -27,10 +32,11 @@ ...@@ -27,10 +32,11 @@
to TIOCGISO7816 and TIOCSISO7816 ioctls (see below). The iso7816_config to TIOCGISO7816 and TIOCSISO7816 ioctls (see below). The iso7816_config
callback receives a pointer to struct serial_iso7816. callback receives a pointer to struct serial_iso7816.
4. USAGE FROM USER-LEVEL 4. Usage from user-level
========================
From user-level, ISO7816 configuration can be get/set using the previous From user-level, ISO7816 configuration can be get/set using the previous
ioctls. For instance, to set ISO7816 you can use the following code: ioctls. For instance, to set ISO7816 you can use the following code::
#include <linux/serial.h> #include <linux/serial.h>
...@@ -78,6 +84,7 @@ ...@@ -78,6 +84,7 @@
/* Error handling. See errno. */ /* Error handling. See errno. */
} }
5. REFERENCES 5. References
=============
[1] include/uapi/linux/serial.h [1] include/uapi/linux/serial.h
RS485 SERIAL COMMUNICATIONS ===========================
RS485 Serial Communications
===========================
1. INTRODUCTION 1. Introduction
===============
EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the
electrical characteristics of drivers and receivers for use in balanced electrical characteristics of drivers and receivers for use in balanced
...@@ -9,7 +12,8 @@ ...@@ -9,7 +12,8 @@
because it can be used effectively over long distances and in electrically because it can be used effectively over long distances and in electrically
noisy environments. noisy environments.
2. HARDWARE-RELATED CONSIDERATIONS 2. Hardware-related Considerations
==================================
Some CPUs/UARTs (e.g., Atmel AT91 or 16C950 UART) contain a built-in Some CPUs/UARTs (e.g., Atmel AT91 or 16C950 UART) contain a built-in
half-duplex mode capable of automatically controlling line direction by half-duplex mode capable of automatically controlling line direction by
...@@ -22,7 +26,8 @@ ...@@ -22,7 +26,8 @@
available at user-level to allow switching from one mode to the other, and available at user-level to allow switching from one mode to the other, and
vice versa. vice versa.
3. DATA STRUCTURES ALREADY AVAILABLE IN THE KERNEL 3. Data Structures Already Available in the Kernel
==================================================
The Linux kernel provides the serial_rs485 structure (see [1]) to handle The Linux kernel provides the serial_rs485 structure (see [1]) to handle
RS485 communications. This data structure is used to set and configure RS485 RS485 communications. This data structure is used to set and configure RS485
...@@ -38,10 +43,11 @@ ...@@ -38,10 +43,11 @@
to TIOCSRS485 and TIOCGRS485 ioctls (see below). The rs485_config callback to TIOCSRS485 and TIOCGRS485 ioctls (see below). The rs485_config callback
receives a pointer to struct serial_rs485. receives a pointer to struct serial_rs485.
4. USAGE FROM USER-LEVEL 4. Usage from user-level
========================
From user-level, RS485 configuration can be get/set using the previous From user-level, RS485 configuration can be get/set using the previous
ioctls. For instance, to set RS485 you can use the following code: ioctls. For instance, to set RS485 you can use the following code::
#include <linux/serial.h> #include <linux/serial.h>
...@@ -89,7 +95,9 @@ ...@@ -89,7 +95,9 @@
/* Error handling. See errno. */ /* Error handling. See errno. */
} }
5. REFERENCES 5. References
=============
[1] include/uapi/linux/serial.h [1] include/uapi/linux/serial.h
[2] Documentation/devicetree/bindings/serial/rs485.txt [2] Documentation/devicetree/bindings/serial/rs485.txt
...@@ -10466,7 +10466,7 @@ F: include/uapi/linux/meye.h ...@@ -10466,7 +10466,7 @@ F: include/uapi/linux/meye.h
MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD
M: Jiri Slaby <jirislaby@gmail.com> M: Jiri Slaby <jirislaby@gmail.com>
S: Maintained S: Maintained
F: Documentation/serial/moxa-smartio F: Documentation/serial/moxa-smartio.rst
F: drivers/tty/mxser.* F: drivers/tty/mxser.*
MR800 AVERMEDIA USB FM RADIO DRIVER MR800 AVERMEDIA USB FM RADIO DRIVER
...@@ -13376,7 +13376,7 @@ ROCKETPORT DRIVER ...@@ -13376,7 +13376,7 @@ ROCKETPORT DRIVER
P: Comtrol Corp. P: Comtrol Corp.
W: http://www.comtrol.com W: http://www.comtrol.com
S: Maintained S: Maintained
F: Documentation/serial/rocket.txt F: Documentation/serial/rocket.rst
F: drivers/tty/rocket* F: drivers/tty/rocket*
ROCKETPORT EXPRESS/INFINITY DRIVER ROCKETPORT EXPRESS/INFINITY DRIVER
......
...@@ -75,7 +75,7 @@ struct ports_driver_data { ...@@ -75,7 +75,7 @@ struct ports_driver_data {
/* All the console devices handled by this driver */ /* All the console devices handled by this driver */
struct list_head consoles; struct list_head consoles;
}; };
static struct ports_driver_data pdrvdata; static struct ports_driver_data pdrvdata = { .next_vtermno = 1};
static DEFINE_SPINLOCK(pdrvdata_lock); static DEFINE_SPINLOCK(pdrvdata_lock);
static DECLARE_COMPLETION(early_console_added); static DECLARE_COMPLETION(early_console_added);
...@@ -1394,6 +1394,7 @@ static int add_port(struct ports_device *portdev, u32 id) ...@@ -1394,6 +1394,7 @@ static int add_port(struct ports_device *portdev, u32 id)
port->async_queue = NULL; port->async_queue = NULL;
port->cons.ws.ws_row = port->cons.ws.ws_col = 0; port->cons.ws.ws_row = port->cons.ws.ws_col = 0;
port->cons.vtermno = 0;
port->host_connected = port->guest_connected = false; port->host_connected = port->guest_connected = false;
port->stats = (struct port_stats) { 0 }; port->stats = (struct port_stats) { 0 };
......
# SPDX-License-Identifier: GPL-2.0
config TTY config TTY
bool "Enable TTY" if EXPERT bool "Enable TTY" if EXPERT
default y default y
...@@ -83,7 +84,6 @@ config HW_CONSOLE ...@@ -83,7 +84,6 @@ config HW_CONSOLE
config VT_HW_CONSOLE_BINDING config VT_HW_CONSOLE_BINDING
bool "Support for binding and unbinding console drivers" bool "Support for binding and unbinding console drivers"
depends on HW_CONSOLE depends on HW_CONSOLE
default n
---help--- ---help---
The virtual terminal is the device that interacts with the physical The virtual terminal is the device that interacts with the physical
terminal through console drivers. On these systems, at least one terminal through console drivers. On these systems, at least one
...@@ -175,7 +175,7 @@ config ROCKETPORT ...@@ -175,7 +175,7 @@ config ROCKETPORT
This driver supports Comtrol RocketPort and RocketModem PCI boards. This driver supports Comtrol RocketPort and RocketModem PCI boards.
These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or
modems. For information about the RocketPort/RocketModem boards modems. For information about the RocketPort/RocketModem boards
and this driver read <file:Documentation/serial/rocket.txt>. and this driver read <file:Documentation/serial/rocket.rst>.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called rocket. module will be called rocket.
...@@ -193,7 +193,7 @@ config CYCLADES ...@@ -193,7 +193,7 @@ config CYCLADES
your Linux box, for instance in order to become a dial-in server. your Linux box, for instance in order to become a dial-in server.
For information about the Cyclades-Z card, read For information about the Cyclades-Z card, read
<file:Documentation/serial/README.cycladesZ>. <file:Documentation/serial/cyclades_z.rst>.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called cyclades. module will be called cyclades.
...@@ -312,7 +312,6 @@ config N_GSM ...@@ -312,7 +312,6 @@ config N_GSM
config TRACE_ROUTER config TRACE_ROUTER
tristate "Trace data router for MIPI P1149.7 cJTAG standard" tristate "Trace data router for MIPI P1149.7 cJTAG standard"
depends on TRACE_SINK depends on TRACE_SINK
default n
help help
The trace router uses the Linux tty line discipline framework to The trace router uses the Linux tty line discipline framework to
route trace data coming from a tty port (say UART for example) to route trace data coming from a tty port (say UART for example) to
...@@ -328,7 +327,6 @@ config TRACE_ROUTER ...@@ -328,7 +327,6 @@ config TRACE_ROUTER
config TRACE_SINK config TRACE_SINK
tristate "Trace data sink for MIPI P1149.7 cJTAG standard" tristate "Trace data sink for MIPI P1149.7 cJTAG standard"
default n
help help
The trace sink uses the Linux line discipline framework to receive The trace sink uses the Linux line discipline framework to receive
trace data coming from the trace router line discipline driver trace data coming from the trace router line discipline driver
...@@ -376,6 +374,20 @@ config PPC_EARLY_DEBUG_EHV_BC_HANDLE ...@@ -376,6 +374,20 @@ config PPC_EARLY_DEBUG_EHV_BC_HANDLE
there simply will be no early console output. This is true also there simply will be no early console output. This is true also
if you don't boot under a hypervisor at all. if you don't boot under a hypervisor at all.
config NULL_TTY
tristate "NULL TTY driver"
help
Say Y here if you want a NULL TTY which simply discards messages.
This is useful to allow userspace applications which expect a console
device to work without modifications even when no console is
available or desired.
In order to use this driver, you should redirect the console to this
TTY, or boot the kernel with console=ttynull.
If unsure, say N.
config GOLDFISH_TTY config GOLDFISH_TTY
tristate "Goldfish TTY Driver" tristate "Goldfish TTY Driver"
depends on GOLDFISH depends on GOLDFISH
......
...@@ -25,6 +25,7 @@ obj-$(CONFIG_ISI) += isicom.o ...@@ -25,6 +25,7 @@ obj-$(CONFIG_ISI) += isicom.o
obj-$(CONFIG_MOXA_INTELLIO) += moxa.o obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
obj-$(CONFIG_MOXA_SMARTIO) += mxser.o obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
obj-$(CONFIG_NOZOMI) += nozomi.o obj-$(CONFIG_NOZOMI) += nozomi.o
obj-$(CONFIG_NULL_TTY) += ttynull.o
obj-$(CONFIG_ROCKETPORT) += rocket.o obj-$(CONFIG_ROCKETPORT) += rocket.o
obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o
......
# SPDX-License-Identifier: GPL-2.0
if TTY if TTY
config HVC_DRIVER config HVC_DRIVER
...@@ -24,7 +25,6 @@ config HVC_CONSOLE ...@@ -24,7 +25,6 @@ config HVC_CONSOLE
config HVC_OLD_HVSI config HVC_OLD_HVSI
bool "Old driver for pSeries serial port (/dev/hvsi*)" bool "Old driver for pSeries serial port (/dev/hvsi*)"
depends on HVC_CONSOLE depends on HVC_CONSOLE
default n
config HVC_OPAL config HVC_OPAL
bool "OPAL Console support" bool "OPAL Console support"
...@@ -73,7 +73,6 @@ config HVC_UDBG ...@@ -73,7 +73,6 @@ config HVC_UDBG
bool "udbg based fake hypervisor console" bool "udbg based fake hypervisor console"
depends on PPC depends on PPC
select HVC_DRIVER select HVC_DRIVER
default n
help help
This is meant to be used during HW bring up or debugging when This is meant to be used during HW bring up or debugging when
no other console mechanism exist but udbg, to get you a quick no other console mechanism exist but udbg, to get you a quick
......
# SPDX-License-Identifier: GPL-2.0
# #
# Makefile for the IPWireless driver # Makefile for the IPWireless driver
# #
......
...@@ -114,6 +114,10 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) ...@@ -114,6 +114,10 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
ipw->common_memory = ioremap(p_dev->resource[2]->start, ipw->common_memory = ioremap(p_dev->resource[2]->start,
resource_size(p_dev->resource[2])); resource_size(p_dev->resource[2]));
if (!ipw->common_memory) {
ret = -ENOMEM;
goto exit1;
}
if (!request_mem_region(p_dev->resource[2]->start, if (!request_mem_region(p_dev->resource[2]->start,
resource_size(p_dev->resource[2]), resource_size(p_dev->resource[2]),
IPWIRELESS_PCCARD_NAME)) { IPWIRELESS_PCCARD_NAME)) {
...@@ -134,6 +138,10 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) ...@@ -134,6 +138,10 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
ipw->attr_memory = ioremap(p_dev->resource[3]->start, ipw->attr_memory = ioremap(p_dev->resource[3]->start,
resource_size(p_dev->resource[3])); resource_size(p_dev->resource[3]));
if (!ipw->attr_memory) {
ret = -ENOMEM;
goto exit3;
}
if (!request_mem_region(p_dev->resource[3]->start, if (!request_mem_region(p_dev->resource[3]->start,
resource_size(p_dev->resource[3]), resource_size(p_dev->resource[3]),
IPWIRELESS_PCCARD_NAME)) { IPWIRELESS_PCCARD_NAME)) {
......
...@@ -550,9 +550,9 @@ static ssize_t process_output_block(struct tty_struct *tty, ...@@ -550,9 +550,9 @@ static ssize_t process_output_block(struct tty_struct *tty,
mutex_lock(&ldata->output_lock); mutex_lock(&ldata->output_lock);
space = tty_write_room(tty); space = tty_write_room(tty);
if (!space) { if (space <= 0) {
mutex_unlock(&ldata->output_lock); mutex_unlock(&ldata->output_lock);
return 0; return space;
} }
if (nr > space) if (nr > space)
nr = space; nr = space;
......
...@@ -1283,23 +1283,29 @@ static int rp_ioctl(struct tty_struct *tty, ...@@ -1283,23 +1283,29 @@ static int rp_ioctl(struct tty_struct *tty,
return -ENXIO; return -ENXIO;
switch (cmd) { switch (cmd) {
case RCKP_GET_STRUCT:
if (copy_to_user(argp, info, sizeof (struct r_port)))
ret = -EFAULT;
break;
case RCKP_GET_CONFIG: case RCKP_GET_CONFIG:
dev_warn_ratelimited(tty->dev,
"RCKP_GET_CONFIG option is deprecated\n");
ret = get_config(info, argp); ret = get_config(info, argp);
break; break;
case RCKP_SET_CONFIG: case RCKP_SET_CONFIG:
dev_warn_ratelimited(tty->dev,
"RCKP_SET_CONFIG option is deprecated\n");
ret = set_config(tty, info, argp); ret = set_config(tty, info, argp);
break; break;
case RCKP_GET_PORTS: case RCKP_GET_PORTS:
dev_warn_ratelimited(tty->dev,
"RCKP_GET_PORTS option is deprecated\n");
ret = get_ports(info, argp); ret = get_ports(info, argp);
break; break;
case RCKP_RESET_RM2: case RCKP_RESET_RM2:
dev_warn_ratelimited(tty->dev,
"RCKP_RESET_RM2 option is deprecated\n");
ret = reset_rm2(info, argp); ret = reset_rm2(info, argp);
break; break;
case RCKP_GET_VERSION: case RCKP_GET_VERSION:
dev_warn_ratelimited(tty->dev,
"RCKP_GET_VERSION option is deprecated\n");
ret = get_version(info, argp); ret = get_version(info, argp);
break; break;
default: default:
......
...@@ -71,7 +71,6 @@ struct rocket_version { ...@@ -71,7 +71,6 @@ struct rocket_version {
/* /*
* Rocketport ioctls -- "RP" * Rocketport ioctls -- "RP"
*/ */
#define RCKP_GET_STRUCT 0x00525001
#define RCKP_GET_CONFIG 0x00525002 #define RCKP_GET_CONFIG 0x00525002
#define RCKP_SET_CONFIG 0x00525003 #define RCKP_SET_CONFIG 0x00525003
#define RCKP_GET_PORTS 0x00525004 #define RCKP_GET_PORTS 0x00525004
......
# SPDX-License-Identifier: GPL-2.0
# #
# Serial bus device driver configuration # Serial bus device driver configuration
# #
......
# SPDX-License-Identifier: GPL-2.0
serdev-objs := core.o serdev-objs := core.o
obj-$(CONFIG_SERIAL_DEV_BUS) += serdev.o obj-$(CONFIG_SERIAL_DEV_BUS) += serdev.o
......
...@@ -361,12 +361,15 @@ static const struct exar8250_platform iot2040_platform = { ...@@ -361,12 +361,15 @@ static const struct exar8250_platform iot2040_platform = {
.register_gpio = iot2040_register_gpio, .register_gpio = iot2040_register_gpio,
}; };
/*
* For SIMATIC IOT2000, only IOT2040 and its variants have the Exar device,
* IOT2020 doesn't have. Therefore it is sufficient to match on the common
* board name after the device was found.
*/
static const struct dmi_system_id exar_platforms[] = { static const struct dmi_system_id exar_platforms[] = {
{ {
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
"6ES7647-0AA00-1YA2"),
}, },
.driver_data = (void *)&iot2040_platform, .driver_data = (void *)&iot2040_platform,
}, },
......
...@@ -303,8 +303,9 @@ static void fintek_8250_goto_highspeed(struct uart_8250_port *uart, ...@@ -303,8 +303,9 @@ static void fintek_8250_goto_highspeed(struct uart_8250_port *uart,
} }
} }
void fintek_8250_set_termios(struct uart_port *port, struct ktermios *termios, static void fintek_8250_set_termios(struct uart_port *port,
struct ktermios *old) struct ktermios *termios,
struct ktermios *old)
{ {
struct fintek_8250 *pdata = port->private_data; struct fintek_8250 *pdata = port->private_data;
unsigned int baud = tty_termios_baud_rate(termios); unsigned int baud = tty_termios_baud_rate(termios);
......
// SPDX-License-Identifier: GPL-2.0
#include <linux/device.h> #include <linux/device.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
......
...@@ -21,15 +21,32 @@ ...@@ -21,15 +21,32 @@
#include "8250.h" #include "8250.h"
#define UART_MTK_HIGHS 0x09 /* Highspeed register */ #define MTK_UART_HIGHS 0x09 /* Highspeed register */
#define UART_MTK_SAMPLE_COUNT 0x0a /* Sample count register */ #define MTK_UART_SAMPLE_COUNT 0x0a /* Sample count register */
#define UART_MTK_SAMPLE_POINT 0x0b /* Sample point register */ #define MTK_UART_SAMPLE_POINT 0x0b /* Sample point register */
#define MTK_UART_RATE_FIX 0x0d /* UART Rate Fix Register */ #define MTK_UART_RATE_FIX 0x0d /* UART Rate Fix Register */
#define MTK_UART_ESCAPE_DAT 0x10 /* Escape Character register */
#define MTK_UART_ESCAPE_EN 0x11 /* Escape Enable register */
#define MTK_UART_DMA_EN 0x13 /* DMA Enable register */ #define MTK_UART_DMA_EN 0x13 /* DMA Enable register */
#define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */
#define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */
#define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */
#define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */
#define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */
#define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */
#define MTK_UART_EFR_EN 0x10 /* Enable enhancement feature */
#define MTK_UART_EFR_RTS 0x40 /* Enable hardware rx flow control */
#define MTK_UART_EFR_CTS 0x80 /* Enable hardware tx flow control */
#define MTK_UART_EFR_NO_SW_FC 0x0 /* no sw flow control */
#define MTK_UART_EFR_XON1_XOFF1 0xa /* XON1/XOFF1 as sw flow control */
#define MTK_UART_EFR_XON2_XOFF2 0x5 /* XON2/XOFF2 as sw flow control */
#define MTK_UART_EFR_SW_FC_MASK 0xf /* Enable CTS Modem status interrupt */
#define MTK_UART_EFR_HW_FC (MTK_UART_EFR_RTS | MTK_UART_EFR_CTS)
#define MTK_UART_DMA_EN_TX 0x2 #define MTK_UART_DMA_EN_TX 0x2
#define MTK_UART_DMA_EN_RX 0x5 #define MTK_UART_DMA_EN_RX 0x5
#define MTK_UART_ESCAPE_CHAR 0x77 /* Escape char added under sw fc */
#define MTK_UART_TX_SIZE UART_XMIT_SIZE #define MTK_UART_TX_SIZE UART_XMIT_SIZE
#define MTK_UART_RX_SIZE 0x8000 #define MTK_UART_RX_SIZE 0x8000
#define MTK_UART_TX_TRIGGER 1 #define MTK_UART_TX_TRIGGER 1
...@@ -46,6 +63,7 @@ enum dma_rx_status { ...@@ -46,6 +63,7 @@ enum dma_rx_status {
struct mtk8250_data { struct mtk8250_data {
int line; int line;
unsigned int rx_pos; unsigned int rx_pos;
unsigned int clk_count;
struct clk *uart_clk; struct clk *uart_clk;
struct clk *bus_clk; struct clk *bus_clk;
struct uart_8250_dma *dma; struct uart_8250_dma *dma;
...@@ -54,6 +72,13 @@ struct mtk8250_data { ...@@ -54,6 +72,13 @@ struct mtk8250_data {
#endif #endif
}; };
/* flow control mode */
enum {
MTK_UART_FC_NONE,
MTK_UART_FC_SW,
MTK_UART_FC_HW,
};
#ifdef CONFIG_SERIAL_8250_DMA #ifdef CONFIG_SERIAL_8250_DMA
static void mtk8250_rx_dma(struct uart_8250_port *up); static void mtk8250_rx_dma(struct uart_8250_port *up);
...@@ -192,13 +217,89 @@ static void mtk8250_shutdown(struct uart_port *port) ...@@ -192,13 +217,89 @@ static void mtk8250_shutdown(struct uart_port *port)
return serial8250_do_shutdown(port); return serial8250_do_shutdown(port);
} }
static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask)
{
serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask));
}
static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask)
{
serial_out(up, UART_IER, serial_in(up, UART_IER) | mask);
}
static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
{
struct uart_port *port = &up->port;
int lcr = serial_in(up, UART_LCR);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, UART_EFR_ECB);
serial_out(up, UART_LCR, lcr);
lcr = serial_in(up, UART_LCR);
switch (mode) {
case MTK_UART_FC_NONE:
serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);
serial_out(up, MTK_UART_ESCAPE_EN, 0x00);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, serial_in(up, UART_EFR) &
(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)));
serial_out(up, UART_LCR, lcr);
mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI |
MTK_UART_IER_RTSI | MTK_UART_IER_CTSI);
break;
case MTK_UART_FC_HW:
serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);
serial_out(up, MTK_UART_ESCAPE_EN, 0x00);
serial_out(up, UART_MCR, UART_MCR_RTS);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
/*enable hw flow control*/
serial_out(up, UART_EFR, MTK_UART_EFR_HW_FC |
(serial_in(up, UART_EFR) &
(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))));
serial_out(up, UART_LCR, lcr);
mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI);
mtk8250_enable_intrs(up, MTK_UART_IER_CTSI | MTK_UART_IER_RTSI);
break;
case MTK_UART_FC_SW: /*MTK software flow control */
serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);
serial_out(up, MTK_UART_ESCAPE_EN, 0x01);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
/*enable sw flow control */
serial_out(up, UART_EFR, MTK_UART_EFR_XON1_XOFF1 |
(serial_in(up, UART_EFR) &
(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))));
serial_out(up, UART_XON1, START_CHAR(port->state->port.tty));
serial_out(up, UART_XOFF1, STOP_CHAR(port->state->port.tty));
serial_out(up, UART_LCR, lcr);
mtk8250_disable_intrs(up, MTK_UART_IER_CTSI|MTK_UART_IER_RTSI);
mtk8250_enable_intrs(up, MTK_UART_IER_XOFFI);
break;
default:
break;
}
}
static void static void
mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old) struct ktermios *old)
{ {
unsigned short fraction_L_mapping[] = {
0, 1, 0x5, 0x15, 0x55, 0x57, 0x57, 0x77, 0x7F, 0xFF, 0xFF
};
unsigned short fraction_M_mapping[] = {
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3
};
struct uart_8250_port *up = up_to_u8250p(port); struct uart_8250_port *up = up_to_u8250p(port);
unsigned int baud, quot, fraction;
unsigned long flags; unsigned long flags;
unsigned int baud, quot; int mode;
#ifdef CONFIG_SERIAL_8250_DMA #ifdef CONFIG_SERIAL_8250_DMA
if (up->dma) { if (up->dma) {
...@@ -214,7 +315,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -214,7 +315,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
serial8250_do_set_termios(port, termios, old); serial8250_do_set_termios(port, termios, old);
/* /*
* Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS) * Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS)
* *
* We need to recalcualte the quot register, as the claculation depends * We need to recalcualte the quot register, as the claculation depends
* on the vaule in the highspeed register. * on the vaule in the highspeed register.
...@@ -230,18 +331,11 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -230,18 +331,11 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
port->uartclk / 16 / UART_DIV_MAX, port->uartclk / 16 / UART_DIV_MAX,
port->uartclk); port->uartclk);
if (baud <= 115200) { if (baud < 115200) {
serial_port_out(port, UART_MTK_HIGHS, 0x0); serial_port_out(port, MTK_UART_HIGHS, 0x0);
quot = uart_get_divisor(port, baud); quot = uart_get_divisor(port, baud);
} else if (baud <= 576000) {
serial_port_out(port, UART_MTK_HIGHS, 0x2);
/* Set to next lower baudrate supported */
if ((baud == 500000) || (baud == 576000))
baud = 460800;
quot = DIV_ROUND_UP(port->uartclk, 4 * baud);
} else { } else {
serial_port_out(port, UART_MTK_HIGHS, 0x3); serial_port_out(port, MTK_UART_HIGHS, 0x3);
quot = DIV_ROUND_UP(port->uartclk, 256 * baud); quot = DIV_ROUND_UP(port->uartclk, 256 * baud);
} }
...@@ -258,18 +352,40 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -258,18 +352,40 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
/* reset DLAB */ /* reset DLAB */
serial_port_out(port, UART_LCR, up->lcr); serial_port_out(port, UART_LCR, up->lcr);
if (baud > 460800) { if (baud >= 115200) {
unsigned int tmp; unsigned int tmp;
tmp = DIV_ROUND_CLOSEST(port->uartclk, quot * baud); tmp = (port->uartclk / (baud * quot)) - 1;
serial_port_out(port, UART_MTK_SAMPLE_COUNT, tmp - 1); serial_port_out(port, MTK_UART_SAMPLE_COUNT, tmp);
serial_port_out(port, UART_MTK_SAMPLE_POINT, serial_port_out(port, MTK_UART_SAMPLE_POINT,
(tmp - 2) >> 1); (tmp >> 1) - 1);
/*count fraction to set fractoin register */
fraction = ((port->uartclk * 100) / baud / quot) % 100;
fraction = DIV_ROUND_CLOSEST(fraction, 10);
serial_port_out(port, MTK_UART_FRACDIV_L,
fraction_L_mapping[fraction]);
serial_port_out(port, MTK_UART_FRACDIV_M,
fraction_M_mapping[fraction]);
} else { } else {
serial_port_out(port, UART_MTK_SAMPLE_COUNT, 0x00); serial_port_out(port, MTK_UART_SAMPLE_COUNT, 0x00);
serial_port_out(port, UART_MTK_SAMPLE_POINT, 0xff); serial_port_out(port, MTK_UART_SAMPLE_POINT, 0xff);
serial_port_out(port, MTK_UART_FRACDIV_L, 0x00);
serial_port_out(port, MTK_UART_FRACDIV_M, 0x00);
} }
if ((termios->c_cflag & CRTSCTS) && (!(termios->c_iflag & CRTSCTS)))
mode = MTK_UART_FC_HW;
else if (termios->c_iflag & CRTSCTS)
mode = MTK_UART_FC_SW;
else
mode = MTK_UART_FC_NONE;
mtk8250_set_flow_ctrl(up, mode);
if (uart_console(port))
up->port.cons->cflag = termios->c_cflag;
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
/* Don't rewrite B0 */ /* Don't rewrite B0 */
if (tty_termios_baud_rate(termios)) if (tty_termios_baud_rate(termios))
......
# SPDX-License-Identifier: GPL-2.0
# #
# The 8250/16550 serial drivers. You shouldn't be in this list unless # The 8250/16550 serial drivers. You shouldn't be in this list unless
# you somehow have an implicit or explicit dependency on SERIAL_8250. # you somehow have an implicit or explicit dependency on SERIAL_8250.
......
# SPDX-License-Identifier: GPL-2.0
# #
# Serial device configuration # Serial device configuration
# #
...@@ -369,7 +370,6 @@ config SERIAL_MAX310X ...@@ -369,7 +370,6 @@ config SERIAL_MAX310X
depends on SPI_MASTER depends on SPI_MASTER
select SERIAL_CORE select SERIAL_CORE
select REGMAP_SPI if SPI_MASTER select REGMAP_SPI if SPI_MASTER
default n
help help
This selects support for an advanced UART from Maxim (Dallas). This selects support for an advanced UART from Maxim (Dallas).
Supported ICs are MAX3107, MAX3108, MAX3109, MAX14830. Supported ICs are MAX3107, MAX3108, MAX3109, MAX14830.
...@@ -652,7 +652,6 @@ config SERIAL_MUX_CONSOLE ...@@ -652,7 +652,6 @@ config SERIAL_MUX_CONSOLE
config PDC_CONSOLE config PDC_CONSOLE
bool "PDC software console support" bool "PDC software console support"
depends on PARISC && !SERIAL_MUX && VT depends on PARISC && !SERIAL_MUX && VT
default n
help help
Saying Y here will enable the software based PDC console to be Saying Y here will enable the software based PDC console to be
used as the system console. This is useful for machines in used as the system console. This is useful for machines in
...@@ -1095,6 +1094,30 @@ config SERIAL_OMAP_CONSOLE ...@@ -1095,6 +1094,30 @@ config SERIAL_OMAP_CONSOLE
your boot loader about how to pass options to the kernel at your boot loader about how to pass options to the kernel at
boot time.) boot time.)
config SERIAL_SIFIVE
tristate "SiFive UART support"
depends on OF
select SERIAL_CORE
help
Select this option if you are building a kernel for a device that
contains a SiFive UART IP block. This type of UART is present on
SiFive FU540 SoCs, among others.
config SERIAL_SIFIVE_CONSOLE
bool "Console on SiFive UART"
depends on SERIAL_SIFIVE=y
select SERIAL_CORE_CONSOLE
help
Select this option if you would like to use a SiFive UART as the
system console.
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttySIFx". (Try "man bootparam" or see the documentation of
your boot loader about how to pass options to the kernel at
boot time.)
config SERIAL_LANTIQ config SERIAL_LANTIQ
bool "Lantiq serial driver" bool "Lantiq serial driver"
depends on LANTIQ depends on LANTIQ
...@@ -1109,7 +1132,6 @@ config SERIAL_QE ...@@ -1109,7 +1132,6 @@ config SERIAL_QE
depends on QUICC_ENGINE depends on QUICC_ENGINE
select SERIAL_CORE select SERIAL_CORE
select FW_LOADER select FW_LOADER
default n
help help
This driver supports the QE serial ports on Freescale embedded This driver supports the QE serial ports on Freescale embedded
PowerPC that contain a QUICC Engine. PowerPC that contain a QUICC Engine.
...@@ -1582,6 +1604,32 @@ config SERIAL_RDA_CONSOLE ...@@ -1582,6 +1604,32 @@ config SERIAL_RDA_CONSOLE
Say 'Y' here if you wish to use the RDA8810PL UART as the system Say 'Y' here if you wish to use the RDA8810PL UART as the system
console. Only earlycon is implemented currently. console. Only earlycon is implemented currently.
config SERIAL_MILBEAUT_USIO
tristate "Milbeaut USIO/UART serial port support"
depends on ARCH_MILBEAUT || (COMPILE_TEST && OF)
default ARCH_MILBEAUT
select SERIAL_CORE
help
This selects the USIO/UART IP found in Socionext Milbeaut SoCs.
config SERIAL_MILBEAUT_USIO_PORTS
int "Maximum number of CSIO/UART ports (1-8)"
range 1 8
depends on SERIAL_MILBEAUT_USIO
default "4"
config SERIAL_MILBEAUT_USIO_CONSOLE
bool "Support for console on MILBEAUT USIO/UART serial port"
depends on SERIAL_MILBEAUT_USIO=y
default y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
help
Say 'Y' here if you wish to use a USIO/UART of Socionext Milbeaut
SoCs as the system console (the system console is the device which
receives all kernel messages and warnings and which allows logins in
single user mode).
endmenu endmenu
config SERIAL_MCTRL_GPIO config SERIAL_MCTRL_GPIO
......
...@@ -92,6 +92,8 @@ obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o ...@@ -92,6 +92,8 @@ obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o
obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o
obj-$(CONFIG_SERIAL_OWL) += owl-uart.o obj-$(CONFIG_SERIAL_OWL) += owl-uart.o
obj-$(CONFIG_SERIAL_RDA) += rda-uart.o obj-$(CONFIG_SERIAL_RDA) += rda-uart.o
obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += milbeaut_usio.o
obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o
# GPIOLIB helpers for modem control lines # GPIOLIB helpers for modem control lines
obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
......
# SPDX-License-Identifier: GPL-2.0
# #
# Makefile for the Motorola 8xx FEC ethernet controller # Makefile for the Motorola 8xx FEC ethernet controller
# #
......
# SPDX-License-Identifier: GPL-2.0
# #
# Makefile for Jasmine adapter # Makefile for Jasmine adapter
# #
......
This diff is collapsed.
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/property.h>
#include <linux/of_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/serial.h> #include <linux/serial.h>
...@@ -1179,7 +1179,8 @@ static int sc16is7xx_probe(struct device *dev, ...@@ -1179,7 +1179,8 @@ static int sc16is7xx_probe(struct device *dev,
struct regmap *regmap, int irq, unsigned long flags) struct regmap *regmap, int irq, unsigned long flags)
{ {
struct sched_param sched_param = { .sched_priority = MAX_RT_PRIO / 2 }; struct sched_param sched_param = { .sched_priority = MAX_RT_PRIO / 2 };
unsigned long freq, *pfreq = dev_get_platdata(dev); unsigned long freq = 0, *pfreq = dev_get_platdata(dev);
u32 uartclk = 0;
int i, ret; int i, ret;
struct sc16is7xx_port *s; struct sc16is7xx_port *s;
...@@ -1193,10 +1194,17 @@ static int sc16is7xx_probe(struct device *dev, ...@@ -1193,10 +1194,17 @@ static int sc16is7xx_probe(struct device *dev,
return -ENOMEM; return -ENOMEM;
} }
/* Always ask for fixed clock rate from a property. */
device_property_read_u32(dev, "clock-frequency", &uartclk);
s->clk = devm_clk_get(dev, NULL); s->clk = devm_clk_get(dev, NULL);
if (IS_ERR(s->clk)) { if (IS_ERR(s->clk)) {
if (uartclk)
freq = uartclk;
if (pfreq) if (pfreq)
freq = *pfreq; freq = *pfreq;
if (freq)
dev_dbg(dev, "Clock frequency: %luHz\n", freq);
else else
return PTR_ERR(s->clk); return PTR_ERR(s->clk);
} else { } else {
...@@ -1384,13 +1392,9 @@ static int sc16is7xx_spi_probe(struct spi_device *spi) ...@@ -1384,13 +1392,9 @@ static int sc16is7xx_spi_probe(struct spi_device *spi)
return ret; return ret;
if (spi->dev.of_node) { if (spi->dev.of_node) {
const struct of_device_id *of_id = devtype = device_get_match_data(&spi->dev);
of_match_device(sc16is7xx_dt_ids, &spi->dev); if (!devtype)
if (!of_id)
return -ENODEV; return -ENODEV;
devtype = (struct sc16is7xx_devtype *)of_id->data;
} else { } else {
const struct spi_device_id *id_entry = spi_get_device_id(spi); const struct spi_device_id *id_entry = spi_get_device_id(spi);
...@@ -1426,7 +1430,7 @@ MODULE_DEVICE_TABLE(spi, sc16is7xx_spi_id_table); ...@@ -1426,7 +1430,7 @@ MODULE_DEVICE_TABLE(spi, sc16is7xx_spi_id_table);
static struct spi_driver sc16is7xx_spi_uart_driver = { static struct spi_driver sc16is7xx_spi_uart_driver = {
.driver = { .driver = {
.name = SC16IS7XX_NAME, .name = SC16IS7XX_NAME,
.of_match_table = of_match_ptr(sc16is7xx_dt_ids), .of_match_table = sc16is7xx_dt_ids,
}, },
.probe = sc16is7xx_spi_probe, .probe = sc16is7xx_spi_probe,
.remove = sc16is7xx_spi_remove, .remove = sc16is7xx_spi_remove,
...@@ -1445,13 +1449,9 @@ static int sc16is7xx_i2c_probe(struct i2c_client *i2c, ...@@ -1445,13 +1449,9 @@ static int sc16is7xx_i2c_probe(struct i2c_client *i2c,
struct regmap *regmap; struct regmap *regmap;
if (i2c->dev.of_node) { if (i2c->dev.of_node) {
const struct of_device_id *of_id = devtype = device_get_match_data(&i2c->dev);
of_match_device(sc16is7xx_dt_ids, &i2c->dev); if (!devtype)
if (!of_id)
return -ENODEV; return -ENODEV;
devtype = (struct sc16is7xx_devtype *)of_id->data;
} else { } else {
devtype = (struct sc16is7xx_devtype *)id->driver_data; devtype = (struct sc16is7xx_devtype *)id->driver_data;
flags = IRQF_TRIGGER_FALLING; flags = IRQF_TRIGGER_FALLING;
...@@ -1484,7 +1484,7 @@ MODULE_DEVICE_TABLE(i2c, sc16is7xx_i2c_id_table); ...@@ -1484,7 +1484,7 @@ MODULE_DEVICE_TABLE(i2c, sc16is7xx_i2c_id_table);
static struct i2c_driver sc16is7xx_i2c_uart_driver = { static struct i2c_driver sc16is7xx_i2c_uart_driver = {
.driver = { .driver = {
.name = SC16IS7XX_NAME, .name = SC16IS7XX_NAME,
.of_match_table = of_match_ptr(sc16is7xx_dt_ids), .of_match_table = sc16is7xx_dt_ids,
}, },
.probe = sc16is7xx_i2c_probe, .probe = sc16is7xx_i2c_probe,
.remove = sc16is7xx_i2c_remove, .remove = sc16is7xx_i2c_remove,
......
...@@ -130,9 +130,6 @@ static void uart_start(struct tty_struct *tty) ...@@ -130,9 +130,6 @@ static void uart_start(struct tty_struct *tty)
struct uart_port *port; struct uart_port *port;
unsigned long flags; unsigned long flags;
if (!state)
return;
port = uart_port_lock(state, flags); port = uart_port_lock(state, flags);
__uart_start(tty); __uart_start(tty);
uart_port_unlock(port, flags); uart_port_unlock(port, flags);
...@@ -730,9 +727,6 @@ static void uart_unthrottle(struct tty_struct *tty) ...@@ -730,9 +727,6 @@ static void uart_unthrottle(struct tty_struct *tty)
upstat_t mask = UPSTAT_SYNC_FIFO; upstat_t mask = UPSTAT_SYNC_FIFO;
struct uart_port *port; struct uart_port *port;
if (!state)
return;
port = uart_port_ref(state); port = uart_port_ref(state);
if (!port) if (!port)
return; return;
...@@ -1514,7 +1508,7 @@ static void uart_set_termios(struct tty_struct *tty, ...@@ -1514,7 +1508,7 @@ static void uart_set_termios(struct tty_struct *tty,
} }
uart_change_speed(tty, state, old_termios); uart_change_speed(tty, state, old_termios);
/* reload cflag from termios; port driver may have overriden flags */ /* reload cflag from termios; port driver may have overridden flags */
cflag = tty->termios.c_cflag; cflag = tty->termios.c_cflag;
/* Handle transition to B0 status */ /* Handle transition to B0 status */
...@@ -1747,6 +1741,16 @@ static void uart_dtr_rts(struct tty_port *port, int raise) ...@@ -1747,6 +1741,16 @@ static void uart_dtr_rts(struct tty_port *port, int raise)
uart_port_deref(uport); uart_port_deref(uport);
} }
static int uart_install(struct tty_driver *driver, struct tty_struct *tty)
{
struct uart_driver *drv = driver->driver_state;
struct uart_state *state = drv->state + tty->index;
tty->driver_data = state;
return tty_standard_install(driver, tty);
}
/* /*
* Calls to uart_open are serialised by the tty_lock in * Calls to uart_open are serialised by the tty_lock in
* drivers/tty/tty_io.c:tty_open() * drivers/tty/tty_io.c:tty_open()
...@@ -1759,11 +1763,8 @@ static void uart_dtr_rts(struct tty_port *port, int raise) ...@@ -1759,11 +1763,8 @@ static void uart_dtr_rts(struct tty_port *port, int raise)
*/ */
static int uart_open(struct tty_struct *tty, struct file *filp) static int uart_open(struct tty_struct *tty, struct file *filp)
{ {
struct uart_driver *drv = tty->driver->driver_state; struct uart_state *state = tty->driver_data;
int retval, line = tty->index; int retval;
struct uart_state *state = drv->state + line;
tty->driver_data = state;
retval = tty_port_open(&state->port, tty, filp); retval = tty_port_open(&state->port, tty, filp);
if (retval > 0) if (retval > 0)
...@@ -2448,6 +2449,7 @@ static void uart_poll_put_char(struct tty_driver *driver, int line, char ch) ...@@ -2448,6 +2449,7 @@ static void uart_poll_put_char(struct tty_driver *driver, int line, char ch)
#endif #endif
static const struct tty_operations uart_ops = { static const struct tty_operations uart_ops = {
.install = uart_install,
.open = uart_open, .open = uart_open,
.close = uart_close, .close = uart_close,
.write = uart_write, .write = uart_write,
...@@ -2505,7 +2507,7 @@ static const struct tty_port_operations uart_port_ops = { ...@@ -2505,7 +2507,7 @@ static const struct tty_port_operations uart_port_ops = {
int uart_register_driver(struct uart_driver *drv) int uart_register_driver(struct uart_driver *drv)
{ {
struct tty_driver *normal; struct tty_driver *normal;
int i, retval; int i, retval = -ENOMEM;
BUG_ON(drv->state); BUG_ON(drv->state);
...@@ -2557,7 +2559,7 @@ int uart_register_driver(struct uart_driver *drv) ...@@ -2557,7 +2559,7 @@ int uart_register_driver(struct uart_driver *drv)
out_kfree: out_kfree:
kfree(drv->state); kfree(drv->state);
out: out:
return -ENOMEM; return retval;
} }
/** /**
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/* /*
* C-Brick Serial Port (and console) driver for SGI Altix machines. * C-Brick Serial Port (and console) driver for SGI Altix machines.
* *
......
This diff is collapsed.
...@@ -1081,7 +1081,7 @@ static int qe_uart_verify_port(struct uart_port *port, ...@@ -1081,7 +1081,7 @@ static int qe_uart_verify_port(struct uart_port *port,
} }
/* UART operations /* UART operations
* *
* Details on these functions can be found in Documentation/serial/driver * Details on these functions can be found in Documentation/serial/driver.rst
*/ */
static const struct uart_ops qe_uart_pops = { static const struct uart_ops qe_uart_pops = {
.tx_empty = qe_uart_tx_empty, .tx_empty = qe_uart_tx_empty,
......
...@@ -193,6 +193,7 @@ struct cdns_uart { ...@@ -193,6 +193,7 @@ struct cdns_uart {
int id; int id;
struct notifier_block clk_rate_change_nb; struct notifier_block clk_rate_change_nb;
u32 quirks; u32 quirks;
bool cts_override;
}; };
struct cdns_platform_data { struct cdns_platform_data {
u32 quirks; u32 quirks;
...@@ -1000,6 +1001,11 @@ static void cdns_uart_config_port(struct uart_port *port, int flags) ...@@ -1000,6 +1001,11 @@ static void cdns_uart_config_port(struct uart_port *port, int flags)
*/ */
static unsigned int cdns_uart_get_mctrl(struct uart_port *port) static unsigned int cdns_uart_get_mctrl(struct uart_port *port)
{ {
struct cdns_uart *cdns_uart_data = port->private_data;
if (cdns_uart_data->cts_override)
return 0;
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
} }
...@@ -1007,6 +1013,10 @@ static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) ...@@ -1007,6 +1013,10 @@ static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{ {
u32 val; u32 val;
u32 mode_reg; u32 mode_reg;
struct cdns_uart *cdns_uart_data = port->private_data;
if (cdns_uart_data->cts_override)
return;
val = readl(port->membase + CDNS_UART_MODEMCR); val = readl(port->membase + CDNS_UART_MODEMCR);
mode_reg = readl(port->membase + CDNS_UART_MR); mode_reg = readl(port->membase + CDNS_UART_MR);
...@@ -1665,6 +1675,8 @@ static int cdns_uart_probe(struct platform_device *pdev) ...@@ -1665,6 +1675,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
console_port = NULL; console_port = NULL;
#endif #endif
cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node,
"cts-override");
return 0; return 0;
err_out_pm_disable: err_out_pm_disable:
......
...@@ -208,7 +208,7 @@ static struct sysrq_key_op sysrq_showlocks_op = { ...@@ -208,7 +208,7 @@ static struct sysrq_key_op sysrq_showlocks_op = {
#endif #endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static DEFINE_SPINLOCK(show_lock); static DEFINE_RAW_SPINLOCK(show_lock);
static void showacpu(void *dummy) static void showacpu(void *dummy)
{ {
...@@ -218,10 +218,10 @@ static void showacpu(void *dummy) ...@@ -218,10 +218,10 @@ static void showacpu(void *dummy)
if (idle_cpu(smp_processor_id())) if (idle_cpu(smp_processor_id()))
return; return;
spin_lock_irqsave(&show_lock, flags); raw_spin_lock_irqsave(&show_lock, flags);
pr_info("CPU%d:\n", smp_processor_id()); pr_info("CPU%d:\n", smp_processor_id());
show_stack(NULL, NULL); show_stack(NULL, NULL);
spin_unlock_irqrestore(&show_lock, flags); raw_spin_unlock_irqrestore(&show_lock, flags);
} }
static void sysrq_showregs_othercpus(struct work_struct *dummy) static void sysrq_showregs_othercpus(struct work_struct *dummy)
......
...@@ -1173,7 +1173,7 @@ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, ...@@ -1173,7 +1173,7 @@ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
* tty_init_termios - helper for termios setup * tty_init_termios - helper for termios setup
* @tty: the tty to set up * @tty: the tty to set up
* *
* Initialise the termios structures for this tty. Thus runs under * Initialise the termios structure for this tty. This runs under
* the tty_mutex currently so we can be relaxed about ordering. * the tty_mutex currently so we can be relaxed about ordering.
*/ */
......
...@@ -44,7 +44,7 @@ int __tty_check_change(struct tty_struct *tty, int sig) ...@@ -44,7 +44,7 @@ int __tty_check_change(struct tty_struct *tty, int sig)
tty_pgrp = tty->pgrp; tty_pgrp = tty->pgrp;
spin_unlock_irqrestore(&tty->ctrl_lock, flags); spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty_pgrp && pgrp != tty->pgrp) { if (tty_pgrp && pgrp != tty_pgrp) {
if (is_ignored(sig)) { if (is_ignored(sig)) {
if (sig == SIGTTIN) if (sig == SIGTTIN)
ret = -EIO; ret = -EIO;
...@@ -313,7 +313,7 @@ void disassociate_ctty(int on_exit) ...@@ -313,7 +313,7 @@ void disassociate_ctty(int on_exit)
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
} }
/** /*
* *
* no_tty - Ensure the current process does not have a controlling tty * no_tty - Ensure the current process does not have a controlling tty
*/ */
......
...@@ -325,7 +325,7 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty) ...@@ -325,7 +325,7 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
if (tty && C_HUPCL(tty)) if (tty && C_HUPCL(tty))
tty_port_lower_dtr_rts(port); tty_port_lower_dtr_rts(port);
if (port->ops && port->ops->shutdown) if (port->ops->shutdown)
port->ops->shutdown(port); port->ops->shutdown(port);
} }
out: out:
...@@ -398,7 +398,7 @@ EXPORT_SYMBOL_GPL(tty_port_tty_wakeup); ...@@ -398,7 +398,7 @@ EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
*/ */
int tty_port_carrier_raised(struct tty_port *port) int tty_port_carrier_raised(struct tty_port *port)
{ {
if (!port->ops || !port->ops->carrier_raised) if (port->ops->carrier_raised == NULL)
return 1; return 1;
return port->ops->carrier_raised(port); return port->ops->carrier_raised(port);
} }
...@@ -414,7 +414,7 @@ EXPORT_SYMBOL(tty_port_carrier_raised); ...@@ -414,7 +414,7 @@ EXPORT_SYMBOL(tty_port_carrier_raised);
*/ */
void tty_port_raise_dtr_rts(struct tty_port *port) void tty_port_raise_dtr_rts(struct tty_port *port)
{ {
if (port->ops && port->ops->dtr_rts) if (port->ops->dtr_rts)
port->ops->dtr_rts(port, 1); port->ops->dtr_rts(port, 1);
} }
EXPORT_SYMBOL(tty_port_raise_dtr_rts); EXPORT_SYMBOL(tty_port_raise_dtr_rts);
...@@ -429,7 +429,7 @@ EXPORT_SYMBOL(tty_port_raise_dtr_rts); ...@@ -429,7 +429,7 @@ EXPORT_SYMBOL(tty_port_raise_dtr_rts);
*/ */
void tty_port_lower_dtr_rts(struct tty_port *port) void tty_port_lower_dtr_rts(struct tty_port *port)
{ {
if (port->ops && port->ops->dtr_rts) if (port->ops->dtr_rts)
port->ops->dtr_rts(port, 0); port->ops->dtr_rts(port, 0);
} }
EXPORT_SYMBOL(tty_port_lower_dtr_rts); EXPORT_SYMBOL(tty_port_lower_dtr_rts);
...@@ -684,7 +684,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty, ...@@ -684,7 +684,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
if (!tty_port_initialized(port)) { if (!tty_port_initialized(port)) {
clear_bit(TTY_IO_ERROR, &tty->flags); clear_bit(TTY_IO_ERROR, &tty->flags);
if (port->ops && port->ops->activate) { if (port->ops->activate) {
int retval = port->ops->activate(port, tty); int retval = port->ops->activate(port, tty);
if (retval) { if (retval) {
mutex_unlock(&port->mutex); mutex_unlock(&port->mutex);
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Axis Communications AB
*
* Based on ttyprintk.c:
* Copyright (C) 2010 Samo Pogacnik
*/
#include <linux/console.h>
#include <linux/module.h>
#include <linux/tty.h>
static const struct tty_port_operations ttynull_port_ops;
static struct tty_driver *ttynull_driver;
static struct tty_port ttynull_port;
static int ttynull_open(struct tty_struct *tty, struct file *filp)
{
return tty_port_open(&ttynull_port, tty, filp);
}
static void ttynull_close(struct tty_struct *tty, struct file *filp)
{
tty_port_close(&ttynull_port, tty, filp);
}
static void ttynull_hangup(struct tty_struct *tty)
{
tty_port_hangup(&ttynull_port);
}
static int ttynull_write(struct tty_struct *tty, const unsigned char *buf,
int count)
{
return count;
}
static int ttynull_write_room(struct tty_struct *tty)
{
return 65536;
}
static const struct tty_operations ttynull_ops = {
.open = ttynull_open,
.close = ttynull_close,
.hangup = ttynull_hangup,
.write = ttynull_write,
.write_room = ttynull_write_room,
};
static struct tty_driver *ttynull_device(struct console *c, int *index)
{
*index = 0;
return ttynull_driver;
}
static struct console ttynull_console = {
.name = "ttynull",
.device = ttynull_device,
};
static int __init ttynull_init(void)
{
struct tty_driver *driver;
int ret;
driver = tty_alloc_driver(1,
TTY_DRIVER_RESET_TERMIOS |
TTY_DRIVER_REAL_RAW |
TTY_DRIVER_UNNUMBERED_NODE);
if (IS_ERR(driver))
return PTR_ERR(driver);
tty_port_init(&ttynull_port);
ttynull_port.ops = &ttynull_port_ops;
driver->driver_name = "ttynull";
driver->name = "ttynull";
driver->type = TTY_DRIVER_TYPE_CONSOLE;
driver->init_termios = tty_std_termios;
driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET;
tty_set_operations(driver, &ttynull_ops);
tty_port_link_device(&ttynull_port, driver, 0);
ret = tty_register_driver(driver);
if (ret < 0) {
put_tty_driver(driver);
tty_port_destroy(&ttynull_port);
return ret;
}
ttynull_driver = driver;
register_console(&ttynull_console);
return 0;
}
static void __exit ttynull_exit(void)
{
unregister_console(&ttynull_console);
tty_unregister_driver(ttynull_driver);
put_tty_driver(ttynull_driver);
tty_port_destroy(&ttynull_port);
}
module_init(ttynull_init);
module_exit(ttynull_exit);
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
/* vcc.c: sun4v virtual channel concentrator /* vcc.c: sun4v virtual channel concentrator
* *
* Copyright (C) 2017 Oracle. All rights reserved. * Copyright (C) 2017 Oracle. All rights reserved.
......
# SPDX-License-Identifier: GPL-2.0
consolemap_deftbl.c consolemap_deftbl.c
defkeymap.c defkeymap.c
...@@ -542,7 +542,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) ...@@ -542,7 +542,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
if (!ct) if (!ct)
return 0; return 0;
unilist = memdup_user(list, ct * sizeof(struct unipair)); unilist = vmemdup_user(list, ct * sizeof(struct unipair));
if (IS_ERR(unilist)) if (IS_ERR(unilist))
return PTR_ERR(unilist); return PTR_ERR(unilist);
...@@ -641,7 +641,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) ...@@ -641,7 +641,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
out_unlock: out_unlock:
console_unlock(); console_unlock();
kfree(unilist); kvfree(unilist);
return err; return err;
} }
...@@ -743,7 +743,7 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni ...@@ -743,7 +743,7 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni
struct uni_pagedir *p; struct uni_pagedir *p;
struct unipair *unilist; struct unipair *unilist;
unilist = kmalloc_array(ct, sizeof(struct unipair), GFP_KERNEL); unilist = kvmalloc_array(ct, sizeof(struct unipair), GFP_KERNEL);
if (!unilist) if (!unilist)
return -ENOMEM; return -ENOMEM;
...@@ -775,7 +775,7 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni ...@@ -775,7 +775,7 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni
if (copy_to_user(list, unilist, min(ect, ct) * sizeof(struct unipair))) if (copy_to_user(list, unilist, min(ect, ct) * sizeof(struct unipair)))
ret = -EFAULT; ret = -EFAULT;
put_user(ect, uct); put_user(ect, uct);
kfree(unilist); kvfree(unilist);
return ret ? ret : (ect <= ct) ? 0 : -ENOMEM; return ret ? ret : (ect <= ct) ? 0 : -ENOMEM;
} }
......
# SPDX-License-Identifier: GPL-2.0
# #
# Unicode table for IBM Codepage 437. Note that there are many more # Unicode table for IBM Codepage 437. Note that there are many more
# substitutions that could be conceived (for example, thick-line # substitutions that could be conceived (for example, thick-line
......
// SPDX-License-Identifier: GPL-2.0
/* Do not edit this file! It was automatically generated by */ /* Do not edit this file! It was automatically generated by */
/* loadkeys --mktable defkeymap.map > defkeymap.c */ /* loadkeys --mktable defkeymap.map > defkeymap.c */
......
# SPDX-License-Identifier: GPL-2.0
# Default kernel keymap. This uses 7 modifier combinations. # Default kernel keymap. This uses 7 modifier combinations.
keymaps 0-2,4-5,8,12 keymaps 0-2,4-5,8,12
# Change the above line into # Change the above line into
......
...@@ -123,6 +123,7 @@ static const int NR_TYPES = ARRAY_SIZE(max_vals); ...@@ -123,6 +123,7 @@ static const int NR_TYPES = ARRAY_SIZE(max_vals);
static struct input_handler kbd_handler; static struct input_handler kbd_handler;
static DEFINE_SPINLOCK(kbd_event_lock); static DEFINE_SPINLOCK(kbd_event_lock);
static DEFINE_SPINLOCK(led_lock); static DEFINE_SPINLOCK(led_lock);
static DEFINE_SPINLOCK(func_buf_lock); /* guard 'func_buf' and friends */
static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
static bool dead_key_next; static bool dead_key_next;
...@@ -1449,7 +1450,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) ...@@ -1449,7 +1450,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
KBD_UNICODE, &param); KBD_UNICODE, &param);
if (rc != NOTIFY_STOP) if (rc != NOTIFY_STOP)
if (down && !raw_mode) if (down && !raw_mode)
to_utf8(vc, keysym); k_unicode(vc, keysym, !down);
return; return;
} }
...@@ -1990,11 +1991,12 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) ...@@ -1990,11 +1991,12 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
char *p; char *p;
u_char *q; u_char *q;
u_char __user *up; u_char __user *up;
int sz; int sz, fnw_sz;
int delta; int delta;
char *first_free, *fj, *fnw; char *first_free, *fj, *fnw;
int i, j, k; int i, j, k;
int ret; int ret;
unsigned long flags;
if (!capable(CAP_SYS_TTY_CONFIG)) if (!capable(CAP_SYS_TTY_CONFIG))
perm = 0; perm = 0;
...@@ -2037,7 +2039,14 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) ...@@ -2037,7 +2039,14 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
goto reterr; goto reterr;
} }
fnw = NULL;
fnw_sz = 0;
/* race aginst other writers */
again:
spin_lock_irqsave(&func_buf_lock, flags);
q = func_table[i]; q = func_table[i];
/* fj pointer to next entry after 'q' */
first_free = funcbufptr + (funcbufsize - funcbufleft); first_free = funcbufptr + (funcbufsize - funcbufleft);
for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
; ;
...@@ -2045,10 +2054,12 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) ...@@ -2045,10 +2054,12 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
fj = func_table[j]; fj = func_table[j];
else else
fj = first_free; fj = first_free;
/* buffer usage increase by new entry */
delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string); delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
if (delta <= funcbufleft) { /* it fits in current buf */ if (delta <= funcbufleft) { /* it fits in current buf */
if (j < MAX_NR_FUNC) { if (j < MAX_NR_FUNC) {
/* make enough space for new entry at 'fj' */
memmove(fj + delta, fj, first_free - fj); memmove(fj + delta, fj, first_free - fj);
for (k = j; k < MAX_NR_FUNC; k++) for (k = j; k < MAX_NR_FUNC; k++)
if (func_table[k]) if (func_table[k])
...@@ -2061,20 +2072,28 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) ...@@ -2061,20 +2072,28 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
sz = 256; sz = 256;
while (sz < funcbufsize - funcbufleft + delta) while (sz < funcbufsize - funcbufleft + delta)
sz <<= 1; sz <<= 1;
fnw = kmalloc(sz, GFP_KERNEL); if (fnw_sz != sz) {
if(!fnw) { spin_unlock_irqrestore(&func_buf_lock, flags);
ret = -ENOMEM; kfree(fnw);
goto reterr; fnw = kmalloc(sz, GFP_KERNEL);
fnw_sz = sz;
if (!fnw) {
ret = -ENOMEM;
goto reterr;
}
goto again;
} }
if (!q) if (!q)
func_table[i] = fj; func_table[i] = fj;
/* copy data before insertion point to new location */
if (fj > funcbufptr) if (fj > funcbufptr)
memmove(fnw, funcbufptr, fj - funcbufptr); memmove(fnw, funcbufptr, fj - funcbufptr);
for (k = 0; k < j; k++) for (k = 0; k < j; k++)
if (func_table[k]) if (func_table[k])
func_table[k] = fnw + (func_table[k] - funcbufptr); func_table[k] = fnw + (func_table[k] - funcbufptr);
/* copy data after insertion point to new location */
if (first_free > fj) { if (first_free > fj) {
memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj); memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
for (k = j; k < MAX_NR_FUNC; k++) for (k = j; k < MAX_NR_FUNC; k++)
...@@ -2087,7 +2106,9 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) ...@@ -2087,7 +2106,9 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
funcbufleft = funcbufleft - delta + sz - funcbufsize; funcbufleft = funcbufleft - delta + sz - funcbufsize;
funcbufsize = sz; funcbufsize = sz;
} }
/* finally insert item itself */
strcpy(func_table[i], kbs->kb_string); strcpy(func_table[i], kbs->kb_string);
spin_unlock_irqrestore(&func_buf_lock, flags);
break; break;
} }
ret = 0; ret = 0;
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* /*
* Provide access to virtual console memory. * Provide access to virtual console memory.
* /dev/vcs0: the screen as it is being viewed right now (possibly scrolled) * /dev/vcs: the screen as it is being viewed right now (possibly scrolled)
* /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63) * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)
* [minor: N] * [minor: N]
* *
......
...@@ -4180,8 +4180,6 @@ void do_blank_screen(int entering_gfx) ...@@ -4180,8 +4180,6 @@ void do_blank_screen(int entering_gfx)
return; return;
} }
if (blank_state != blank_normal_wait)
return;
blank_state = blank_off; blank_state = blank_off;
/* don't blank graphics */ /* don't blank graphics */
......
...@@ -45,7 +45,7 @@ struct device; ...@@ -45,7 +45,7 @@ struct device;
/* /*
* This structure describes all the operations that can be done on the * This structure describes all the operations that can be done on the
* physical hardware. See Documentation/serial/driver for details. * physical hardware. See Documentation/serial/driver.rst for details.
*/ */
struct uart_ops { struct uart_ops {
unsigned int (*tx_empty)(struct uart_port *); unsigned int (*tx_empty)(struct uart_port *);
......
...@@ -287,4 +287,10 @@ ...@@ -287,4 +287,10 @@
/* RDA UART */ /* RDA UART */
#define PORT_RDA 118 #define PORT_RDA 118
/* Socionext Milbeaut UART */
#define PORT_MLB_USIO 119
/* SiFive UART */
#define PORT_SIFIVE_V0 120
#endif /* _UAPILINUX_SERIAL_CORE_H */ #endif /* _UAPILINUX_SERIAL_CORE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment