TTY/Serial driver patches for 4.11-rc1

Here is the big tty/serial driver patchset for 4.11-rc1.
 
 Not much here, but a lot of little fixes and individual serial driver
 updates all over the subsystem.  Majority are for the sh-sci driver and
 platform (the arch-specific changes have acks from the maintainer).
 
 The start of the "serial bus" code is here as well, but nothing is
 converted to use it yet.  That work is still ongoing, hopefully will
 start to show up across different subsystems for 4.12 (bluetooth is one
 major place that will be used.)
 
 All of these have been in linux-next for a while with no reported
 issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWK2lDg8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ylwfwCgyExa4x8Lur2nZyu8cgcaVRU68VAAoNQh0WJt
 EZdEhEkRMt4d64j+ApYI
 =iv7x
 -----END PGP SIGNATURE-----

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

Pull tty/serial driver updates from Greg KH:
 "Here is the big tty/serial driver patchset for 4.11-rc1.

  Not much here, but a lot of little fixes and individual serial driver
  updates all over the subsystem. Majority are for the sh-sci driver and
  platform (the arch-specific changes have acks from the maintainer).

  The start of the "serial bus" code is here as well, but nothing is
  converted to use it yet. That work is still ongoing, hopefully will
  start to show up across different subsystems for 4.12 (bluetooth is
  one major place that will be used.)

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

* tag 'tty-4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (109 commits)
  tty: pl011: Work around QDF2400 E44 stuck BUSY bit
  atmel_serial: Use the fractional divider when possible
  tty: Remove extra include in HVC console tty framework
  serial: exar: Enable MSI support
  serial: exar: Move register defines from uapi header to consumer site
  serial: pci: Remove unused pci_boards entries
  serial: exar: Move Commtech adapters to 8250_exar as well
  serial: exar: Fix feature control register constants
  serial: exar: Fix initialization of EXAR registers for ports > 0
  serial: exar: Fix mapping of port I/O resources
  serial: sh-sci: fix hardware RX trigger level setting
  tty/serial: atmel: ensure state is restored after suspending
  serial: 8250_dw: Avoid "too much work" from bogus rx timeout interrupt
  serdev: ttyport: check whether tty_init_dev() fails
  serial: 8250_pci: make pciserial_detach_ports() static
  ARM: dts: STiH410-b2260: Enable HW flow-control
  ARM: dts: STiH407-family: Use new Pinctrl groups
  ARM: dts: STiH407-pinctrl: Add Pinctrl group for HW flow-control
  ARM: dts: STiH410-b2260: Identify the UART RTS line
  dt-bindings: serial: Update 'uart-has-rtscts' description
  ...
This commit is contained in:
Linus Torvalds 2017-02-22 12:17:25 -08:00
commit 37c85961c3
116 changed files with 3059 additions and 1642 deletions

View File

@ -957,6 +957,12 @@
serial port must already be setup and configured.
Options are not yet supported.
lantiq,<addr>
Start an early, polled-mode console on a lantiq serial
(lqasc) port at the specified address. The serial port
must already be setup and configured. Options are not
yet supported.
lpuart,<addr>
lpuart32,<addr>
Use early console provided by Freescale LP UART driver

View File

@ -19,6 +19,7 @@ Required properties:
- "altr,16550-FIFO128"
- "fsl,16550-FIFO64"
- "fsl,ns16550"
- "ti,da830-uart"
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.

View File

@ -23,7 +23,8 @@ Optional properties:
they are available for use (wired and enabled by pinmux configuration).
This depends on both the UART hardware and the board wiring.
Note that this property is mutually-exclusive with "cts-gpios" and
"rts-gpios" above.
"rts-gpios" above, unless support is provided to switch between modes
dynamically.
Examples:

View File

@ -0,0 +1,36 @@
Serial Slave Device DT binding
This documents the binding structure and common properties for serial
attached devices. Common examples include Bluetooth, WiFi, NFC and GPS
devices.
Serial attached devices shall be a child node of the host UART device the
slave device is attached to. It is expected that the attached device is
the only child node of the UART device. The slave device node name shall
reflect the generic type of device for the node.
Required Properties:
- compatible : A string reflecting the vendor and specific device the node
represents.
Optional Properties:
- max-speed : The maximum baud rate the device operates at. This should
only be present if the maximum is less than the slave device
can support. For example, a particular board has some signal
quality issue or the host processor can't support higher
baud rates.
Example:
serial@1234 {
compatible = "ns16550a";
interrupts = <1>;
bluetooth {
compatible = "brcm,bcm43341-bt";
interrupt-parent = <&gpio>;
interrupts = <10>;
};
};

View File

@ -10927,6 +10927,14 @@ S: Maintained
F: Documentation/devicetree/bindings/serial/
F: drivers/tty/serial/
SERIAL DEVICE BUS
M: Rob Herring <robh@kernel.org>
L: linux-serial@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/serial/slave-device.txt
F: drivers/tty/serdev/
F: include/linux/serdev.h
SERIAL IR RECEIVER
M: Sean Young <sean@mess.org>
L: linux-media@vger.kernel.org

View File

@ -222,9 +222,8 @@
compatible = "st,asc";
reg = <0x9830000 0x2c>;
interrupts = <GIC_SPI 122 IRQ_TYPE_NONE>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_serial0>;
clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
/* Pinctrl moved out to a per-board configuration */
status = "disabled";
};

View File

@ -465,8 +465,16 @@
serial0 {
pinctrl_serial0: serial0-0 {
st,pins {
tx = <&pio17 0 ALT1 OUT>;
rx = <&pio17 1 ALT1 IN>;
tx = <&pio17 0 ALT1 OUT>;
rx = <&pio17 1 ALT1 IN>;
};
};
pinctrl_serial0_hw_flowctrl: serial0-0_hw_flowctrl {
st,pins {
tx = <&pio17 0 ALT1 OUT>;
rx = <&pio17 1 ALT1 IN>;
cts = <&pio17 2 ALT1 IN>;
rts = <&pio17 3 ALT1 OUT>;
};
};
};

View File

@ -62,6 +62,11 @@
/* Low speed expansion connector */
uart0: serial@9830000 {
label = "LS-UART0";
pinctrl-names = "default", "no-hw-flowctrl";
pinctrl-0 = <&pinctrl_serial0_hw_flowctrl>;
pinctrl-1 = <&pinctrl_serial0>;
rts-gpios = <&pio17 3 GPIO_ACTIVE_LOW>;
uart-has-rtscts;
status = "okay";
};

View File

@ -61,8 +61,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL,
NULL, prio_registers, NULL);
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -82,8 +81,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -103,8 +101,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -129,8 +129,7 @@ static struct platform_device mtu2_device = {
};
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -178,8 +178,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups,
mask_registers, prio_registers, NULL);
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -199,8 +198,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -220,8 +218,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -241,8 +238,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -262,8 +258,7 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -283,8 +278,7 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -304,8 +298,7 @@ static struct platform_device scif5_device = {
};
static struct plat_sci_port scif6_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -325,8 +318,7 @@ static struct platform_device scif6_device = {
};
static struct plat_sci_port scif7_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -174,9 +174,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups,
mask_registers, prio_registers, NULL);
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -197,9 +195,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -220,9 +216,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -243,9 +237,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};

View File

@ -134,8 +134,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups,
mask_registers, prio_registers, NULL);
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -155,8 +154,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -176,8 +174,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -197,8 +194,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -226,9 +226,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7264", vectors, groups,
mask_registers, prio_registers, NULL);
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -252,9 +250,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -278,9 +274,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -304,9 +298,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -330,9 +322,7 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -356,9 +346,7 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -382,9 +370,7 @@ static struct platform_device scif5_device = {
};
static struct plat_sci_port scif6_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -408,9 +394,7 @@ static struct platform_device scif6_device = {
};
static struct plat_sci_port scif7_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};

View File

@ -248,9 +248,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7269", vectors, groups,
mask_registers, prio_registers, NULL);
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -274,9 +272,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -300,9 +296,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -326,9 +320,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -352,9 +344,7 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -378,9 +368,7 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -404,9 +392,7 @@ static struct platform_device scif5_device = {
};
static struct plat_sci_port scif6_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};
@ -430,9 +416,7 @@ static struct platform_device scif6_device = {
};
static struct plat_sci_port scif7_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
};

View File

@ -70,9 +70,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL,
NULL, prio_registers, NULL);
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE |
SCSCR_RE | SCSCR_CKE1 | SCSCR_CKE0,
.scscr = SCSCR_CKE1,
.type = PORT_SCIF,
.ops = &sh770x_sci_port_ops,
.regtype = SCIx_SH7705_SCIF_REGTYPE,
@ -94,8 +92,6 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | SCSCR_RE,
.type = PORT_SCIF,
.ops = &sh770x_sci_port_ops,
.regtype = SCIx_SH7705_SCIF_REGTYPE,

View File

@ -109,12 +109,8 @@ static struct platform_device rtc_device = {
};
static struct plat_sci_port scif0_platform_data = {
.port_reg = 0xa4000136,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TE | SCSCR_RE,
.type = PORT_SCI,
.ops = &sh770x_sci_port_ops,
.regshift = 1,
};
static struct resource scif0_resources[] = {
@ -135,8 +131,6 @@ static struct platform_device scif0_device = {
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
defined(CONFIG_CPU_SUBTYPE_SH7709)
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TE | SCSCR_RE,
.type = PORT_SCIF,
.ops = &sh770x_sci_port_ops,
.regtype = SCIx_SH3_SCIF_REGTYPE,
@ -160,12 +154,8 @@ static struct platform_device scif1_device = {
#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
defined(CONFIG_CPU_SUBTYPE_SH7709)
static struct plat_sci_port scif2_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TE | SCSCR_RE,
.type = PORT_IRDA,
.ops = &sh770x_sci_port_ops,
.regshift = 1,
};
static struct resource scif2_resources[] = {

View File

@ -98,9 +98,7 @@ static struct platform_device rtc_device = {
};
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE |
SCSCR_CKE1 | SCSCR_CKE0,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
};
@ -120,9 +118,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE |
SCSCR_CKE1 | SCSCR_CKE0,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
};

View File

@ -52,8 +52,6 @@ static struct platform_device rtc_device = {
};
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.type = PORT_SCIF,
.ops = &sh7720_sci_port_ops,
.regtype = SCIx_SH7705_SCIF_REGTYPE,
@ -75,8 +73,6 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.type = PORT_SCIF,
.ops = &sh7720_sci_port_ops,
.regtype = SCIx_SH7705_SCIF_REGTYPE,

View File

@ -17,8 +17,7 @@
#include <linux/io.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -38,15 +38,11 @@ static struct platform_device rtc_device = {
};
static struct plat_sci_port sci_platform_data = {
.port_reg = 0xffe0001C,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TE | SCSCR_RE,
.type = PORT_SCI,
.regshift = 2,
};
static struct resource sci_resources[] = {
DEFINE_RES_MEM(0xffe00000, 0x100),
DEFINE_RES_MEM(0xffe00000, 0x20),
DEFINE_RES_IRQ(evt2irq(0x4e0)),
};
@ -61,8 +57,7 @@ static struct platform_device sci_device = {
};
static struct plat_sci_port scif_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -128,8 +128,7 @@ static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups,
mask_registers, prio_registers, NULL);
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -153,9 +152,8 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -178,8 +176,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -203,14 +200,18 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
/*
* This is actually a SIM card module serial port, based on an SCI with
* additional registers. The sh-sci driver doesn't support the SIM port
* type, declare it as a SCI. Don't declare the additional registers in
* the memory resource or the driver will compute an incorrect regshift
* value.
*/
.type = PORT_SCI,
.regshift = 2,
};
static struct resource scif3_resources[] = {
DEFINE_RES_MEM(0xfe480000, 0x100),
DEFINE_RES_MEM(0xfe480000, 0x10),
DEFINE_RES_IRQ(evt2irq(0xc00)),
DEFINE_RES_IRQ(evt2irq(0xc20)),
DEFINE_RES_IRQ(evt2irq(0xc40)),

View File

@ -18,8 +18,7 @@
/* Serial */
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
.scscr = SCSCR_CKE1,
.type = PORT_SCIF,
};
@ -39,8 +38,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
.scscr = SCSCR_CKE1,
.type = PORT_SCIF,
};
@ -60,8 +58,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
.scscr = SCSCR_CKE1,
.type = PORT_SCIF,
};
@ -81,8 +78,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
.scscr = SCSCR_CKE1,
.type = PORT_SCIF,
};

View File

@ -20,9 +20,7 @@
#include <asm/clock.h>
static struct plat_sci_port scif0_platform_data = {
.port_reg = 0xa405013e,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -179,8 +179,7 @@ struct platform_device dma_device = {
/* Serial */
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.ops = &sh7722_sci_port_ops,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
@ -202,8 +201,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.ops = &sh7722_sci_port_ops,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
@ -225,8 +223,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.ops = &sh7722_sci_port_ops,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,

View File

@ -23,9 +23,7 @@
/* Serial */
static struct plat_sci_port scif0_platform_data = {
.port_reg = 0xa4050160,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
@ -46,9 +44,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
@ -69,9 +65,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
@ -92,9 +86,6 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.port_reg = SCIx_NOT_SUPPORTED,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};
@ -115,9 +106,6 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};
@ -138,9 +126,6 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};

View File

@ -290,9 +290,7 @@ static struct platform_device dma1_device = {
/* Serial */
static struct plat_sci_port scif0_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
@ -313,9 +311,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
@ -336,9 +332,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
@ -359,9 +353,6 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};
@ -382,9 +373,6 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};
@ -405,9 +393,6 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};

View File

@ -25,8 +25,7 @@
/* SCIF */
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
@ -47,8 +46,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
@ -69,8 +67,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
@ -91,8 +88,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
@ -113,8 +109,7 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};
@ -135,8 +130,7 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_BRG_REGTYPE,
};

View File

@ -24,8 +24,7 @@
#include <cpu/sh7757.h>
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -45,8 +44,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -66,8 +64,7 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -19,8 +19,7 @@
#include <linux/usb/ohci_pdriver.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -41,8 +40,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -63,8 +61,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};

View File

@ -16,8 +16,7 @@
#include <linux/io.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -37,8 +36,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -58,8 +56,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -79,8 +76,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -100,8 +96,7 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -121,8 +116,7 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -142,8 +136,7 @@ static struct platform_device scif5_device = {
};
static struct plat_sci_port scif6_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -163,8 +156,7 @@ static struct platform_device scif6_device = {
};
static struct plat_sci_port scif7_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -184,8 +176,7 @@ static struct platform_device scif7_device = {
};
static struct plat_sci_port scif8_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
@ -205,8 +196,7 @@ static struct platform_device scif8_device = {
};
static struct plat_sci_port scif9_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.scscr = SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};

View File

@ -18,8 +18,7 @@
#include <cpu/dma-register.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -40,8 +39,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};

View File

@ -20,8 +20,7 @@
#include <cpu/dma-register.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -42,8 +41,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -64,8 +62,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -86,8 +83,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -108,8 +104,7 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -130,8 +125,7 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};

View File

@ -28,8 +28,7 @@
#include <asm/mmzone.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -56,8 +55,7 @@ static struct platform_device scif0_device = {
* The rest of these all have multiplexed IRQs
*/
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -87,8 +85,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -109,8 +106,7 @@ static struct platform_device scif2_device = {
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -131,8 +127,7 @@ static struct platform_device scif3_device = {
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
@ -153,8 +148,7 @@ static struct platform_device scif4_device = {
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.scscr = SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};

View File

@ -28,8 +28,7 @@
* all rather than adding infrastructure to hack around it.
*/
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -52,8 +51,7 @@ static struct platform_device scif0_device = {
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};
@ -76,8 +74,7 @@ static struct platform_device scif1_device = {
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -17,8 +17,8 @@
#include <asm/addrspace.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.flags = UPF_IOREMAP,
.scscr = SCSCR_REIE,
.type = PORT_SCIF,
};

View File

@ -16,6 +16,26 @@
#include <linux/kernel.h>
#include <linux/serial_core.h>
/*
* Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
* Detect them by examining the OEM fields in the SPCR header, similiar to PCI
* quirk detection in pci_mcfg.c.
*/
static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
{
if (memcmp(h->oem_id, "QCOM ", ACPI_OEM_ID_SIZE))
return false;
if (!memcmp(h->oem_table_id, "QDF2432 ", ACPI_OEM_TABLE_ID_SIZE))
return true;
if (!memcmp(h->oem_table_id, "QDF2400 ", ACPI_OEM_TABLE_ID_SIZE) &&
h->oem_revision == 0)
return true;
return false;
}
/**
* parse_spcr() - parse ACPI SPCR table and add preferred console
*
@ -93,6 +113,9 @@ int __init parse_spcr(bool earlycon)
goto done;
}
if (qdf2400_erratum_44_present(&table->header))
uart = "qdf2400_e44";
snprintf(opts, sizeof(opts), "%s,%s,0x%llx,%d", uart, iotype,
table->serial_port.address, baud_rate);

View File

@ -46,6 +46,7 @@ config SGI_MBCS
say Y or M here, otherwise say N.
source "drivers/tty/serial/Kconfig"
source "drivers/tty/serdev/Kconfig"
config TTY_PRINTK
tristate "TTY driver to output user messages via printk"

View File

@ -23,15 +23,28 @@
#define HSU_PCI_CHAN_OFFSET 0x100
#define PCI_DEVICE_ID_INTEL_MFLD_HSU_DMA 0x081e
#define PCI_DEVICE_ID_INTEL_MRFLD_HSU_DMA 0x1192
static irqreturn_t hsu_pci_irq(int irq, void *dev)
{
struct hsu_dma_chip *chip = dev;
struct pci_dev *pdev = to_pci_dev(chip->dev);
u32 dmaisr;
u32 status;
unsigned short i;
int ret = 0;
int err;
/*
* On Intel Tangier B0 and Anniedale the interrupt line, disregarding
* to have different numbers, is shared between HSU DMA and UART IPs.
* Thus on such SoCs we are expecting that IRQ handler is called in
* UART driver only.
*/
if (pdev->device == PCI_DEVICE_ID_INTEL_MRFLD_HSU_DMA)
return IRQ_HANDLED;
dmaisr = readl(chip->regs + HSU_PCI_DMAISR);
for (i = 0; i < chip->hsu->nr_channels; i++) {
if (dmaisr & 0x1) {
@ -113,8 +126,8 @@ static void hsu_pci_remove(struct pci_dev *pdev)
}
static const struct pci_device_id hsu_pci_id_table[] = {
{ PCI_VDEVICE(INTEL, 0x081e), 0 },
{ PCI_VDEVICE(INTEL, 0x1192), 0 },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MFLD_HSU_DMA), 0 },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD_HSU_DMA), 0 },
{ }
};
MODULE_DEVICE_TABLE(pci, hsu_pci_id_table);

View File

@ -13,6 +13,7 @@ obj-$(CONFIG_R3964) += n_r3964.o
obj-y += vt/
obj-$(CONFIG_HVC_DRIVER) += hvc/
obj-y += serial/
obj-$(CONFIG_SERIAL_DEV_BUS) += serdev/
# tty drivers
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o

View File

@ -300,7 +300,7 @@ static int goldfish_tty_probe(struct platform_device *pdev)
return 0;
err_tty_register_device_failed:
free_irq(irq, pdev);
free_irq(irq, qtty);
err_request_irq_failed:
goldfish_tty_current_line_count--;
if (goldfish_tty_current_line_count == 0)

View File

@ -29,7 +29,6 @@
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/atomic.h>
#include <linux/sysrq.h>

View File

@ -0,0 +1,16 @@
#
# Serial bus device driver configuration
#
menuconfig SERIAL_DEV_BUS
tristate "Serial device bus"
help
Core support for devices connected via a serial port.
if SERIAL_DEV_BUS
config SERIAL_DEV_CTRL_TTYPORT
bool "Serial device TTY port controller"
depends on TTY
depends on SERIAL_DEV_BUS != m
endif

View File

@ -0,0 +1,5 @@
serdev-objs := core.o
obj-$(CONFIG_SERIAL_DEV_BUS) += serdev.o
obj-$(CONFIG_SERIAL_DEV_CTRL_TTYPORT) += serdev-ttyport.o

421
drivers/tty/serdev/core.c Normal file
View File

@ -0,0 +1,421 @@
/*
* Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <robh@kernel.org>
*
* Based on drivers/spmi/spmi.c:
* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/errno.h>
#include <linux/idr.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/serdev.h>
#include <linux/slab.h>
static bool is_registered;
static DEFINE_IDA(ctrl_ida);
static void serdev_device_release(struct device *dev)
{
struct serdev_device *serdev = to_serdev_device(dev);
kfree(serdev);
}
static const struct device_type serdev_device_type = {
.release = serdev_device_release,
};
static void serdev_ctrl_release(struct device *dev)
{
struct serdev_controller *ctrl = to_serdev_controller(dev);
ida_simple_remove(&ctrl_ida, ctrl->nr);
kfree(ctrl);
}
static const struct device_type serdev_ctrl_type = {
.release = serdev_ctrl_release,
};
static int serdev_device_match(struct device *dev, struct device_driver *drv)
{
/* TODO: ACPI and platform matching */
return of_driver_match_device(dev, drv);
}
static int serdev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
/* TODO: ACPI and platform modalias */
return of_device_uevent_modalias(dev, env);
}
/**
* serdev_device_add() - add a device previously constructed via serdev_device_alloc()
* @serdev: serdev_device to be added
*/
int serdev_device_add(struct serdev_device *serdev)
{
struct device *parent = serdev->dev.parent;
int err;
dev_set_name(&serdev->dev, "%s-%d", dev_name(parent), serdev->nr);
err = device_add(&serdev->dev);
if (err < 0) {
dev_err(&serdev->dev, "Can't add %s, status %d\n",
dev_name(&serdev->dev), err);
goto err_device_add;
}
dev_dbg(&serdev->dev, "device %s registered\n", dev_name(&serdev->dev));
err_device_add:
return err;
}
EXPORT_SYMBOL_GPL(serdev_device_add);
/**
* serdev_device_remove(): remove an serdev device
* @serdev: serdev_device to be removed
*/
void serdev_device_remove(struct serdev_device *serdev)
{
device_unregister(&serdev->dev);
}
EXPORT_SYMBOL_GPL(serdev_device_remove);
int serdev_device_open(struct serdev_device *serdev)
{
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->open)
return -EINVAL;
return ctrl->ops->open(ctrl);
}
EXPORT_SYMBOL_GPL(serdev_device_open);
void serdev_device_close(struct serdev_device *serdev)
{
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->close)
return;
ctrl->ops->close(ctrl);
}
EXPORT_SYMBOL_GPL(serdev_device_close);
int serdev_device_write_buf(struct serdev_device *serdev,
const unsigned char *buf, size_t count)
{
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->write_buf)
return -EINVAL;
return ctrl->ops->write_buf(ctrl, buf, count);
}
EXPORT_SYMBOL_GPL(serdev_device_write_buf);
void serdev_device_write_flush(struct serdev_device *serdev)
{
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->write_flush)
return;
ctrl->ops->write_flush(ctrl);
}
EXPORT_SYMBOL_GPL(serdev_device_write_flush);
int serdev_device_write_room(struct serdev_device *serdev)
{
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->write_room)
return 0;
return serdev->ctrl->ops->write_room(ctrl);
}
EXPORT_SYMBOL_GPL(serdev_device_write_room);
unsigned int serdev_device_set_baudrate(struct serdev_device *serdev, unsigned int speed)
{
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->set_baudrate)
return 0;
return ctrl->ops->set_baudrate(ctrl, speed);
}
EXPORT_SYMBOL_GPL(serdev_device_set_baudrate);
void serdev_device_set_flow_control(struct serdev_device *serdev, bool enable)
{
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->set_flow_control)
return;
ctrl->ops->set_flow_control(ctrl, enable);
}
EXPORT_SYMBOL_GPL(serdev_device_set_flow_control);
static int serdev_drv_probe(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
return sdrv->probe(to_serdev_device(dev));
}
static int serdev_drv_remove(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
sdrv->remove(to_serdev_device(dev));
return 0;
}
static ssize_t modalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2);
buf[len] = '\n';
buf[len+1] = 0;
return len+1;
}
static struct device_attribute serdev_device_attrs[] = {
__ATTR_RO(modalias),
__ATTR_NULL
};
static struct bus_type serdev_bus_type = {
.name = "serial",
.match = serdev_device_match,
.probe = serdev_drv_probe,
.remove = serdev_drv_remove,
.uevent = serdev_uevent,
.dev_attrs = serdev_device_attrs,
};
/**
* serdev_controller_alloc() - Allocate a new serdev device
* @ctrl: associated controller
*
* Caller is responsible for either calling serdev_device_add() to add the
* newly allocated controller, or calling serdev_device_put() to discard it.
*/
struct serdev_device *serdev_device_alloc(struct serdev_controller *ctrl)
{
struct serdev_device *serdev;
serdev = kzalloc(sizeof(*serdev), GFP_KERNEL);
if (!serdev)
return NULL;
serdev->ctrl = ctrl;
ctrl->serdev = serdev;
device_initialize(&serdev->dev);
serdev->dev.parent = &ctrl->dev;
serdev->dev.bus = &serdev_bus_type;
serdev->dev.type = &serdev_device_type;
return serdev;
}
EXPORT_SYMBOL_GPL(serdev_device_alloc);
/**
* serdev_controller_alloc() - Allocate a new serdev controller
* @parent: parent device
* @size: size of private data
*
* Caller is responsible for either calling serdev_controller_add() to add the
* newly allocated controller, or calling serdev_controller_put() to discard it.
* The allocated private data region may be accessed via
* serdev_controller_get_drvdata()
*/
struct serdev_controller *serdev_controller_alloc(struct device *parent,
size_t size)
{
struct serdev_controller *ctrl;
int id;
if (WARN_ON(!parent))
return NULL;
ctrl = kzalloc(sizeof(*ctrl) + size, GFP_KERNEL);
if (!ctrl)
return NULL;
device_initialize(&ctrl->dev);
ctrl->dev.type = &serdev_ctrl_type;
ctrl->dev.bus = &serdev_bus_type;
ctrl->dev.parent = parent;
ctrl->dev.of_node = parent->of_node;
serdev_controller_set_drvdata(ctrl, &ctrl[1]);
id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
dev_err(parent,
"unable to allocate serdev controller identifier.\n");
serdev_controller_put(ctrl);
return NULL;
}
ctrl->nr = id;
dev_set_name(&ctrl->dev, "serial%d", id);
dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id);
return ctrl;
}
EXPORT_SYMBOL_GPL(serdev_controller_alloc);
static int of_serdev_register_devices(struct serdev_controller *ctrl)
{
struct device_node *node;
struct serdev_device *serdev = NULL;
int err;
bool found = false;
for_each_available_child_of_node(ctrl->dev.of_node, node) {
if (!of_get_property(node, "compatible", NULL))
continue;
dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name);
serdev = serdev_device_alloc(ctrl);
if (!serdev)
continue;
serdev->dev.of_node = node;
err = serdev_device_add(serdev);
if (err) {
dev_err(&serdev->dev,
"failure adding device. status %d\n", err);
serdev_device_put(serdev);
} else
found = true;
}
if (!found)
return -ENODEV;
return 0;
}
/**
* serdev_controller_add() - Add an serdev controller
* @ctrl: controller to be registered.
*
* Register a controller previously allocated via serdev_controller_alloc() with
* the serdev core.
*/
int serdev_controller_add(struct serdev_controller *ctrl)
{
int ret;
/* Can't register until after driver model init */
if (WARN_ON(!is_registered))
return -EAGAIN;
ret = device_add(&ctrl->dev);
if (ret)
return ret;
ret = of_serdev_register_devices(ctrl);
if (ret)
goto out_dev_del;
dev_dbg(&ctrl->dev, "serdev%d registered: dev:%p\n",
ctrl->nr, &ctrl->dev);
return 0;
out_dev_del:
device_del(&ctrl->dev);
return ret;
};
EXPORT_SYMBOL_GPL(serdev_controller_add);
/* Remove a device associated with a controller */
static int serdev_remove_device(struct device *dev, void *data)
{
struct serdev_device *serdev = to_serdev_device(dev);
if (dev->type == &serdev_device_type)
serdev_device_remove(serdev);
return 0;
}
/**
* serdev_controller_remove(): remove an serdev controller
* @ctrl: controller to remove
*
* Remove a serdev controller. Caller is responsible for calling
* serdev_controller_put() to discard the allocated controller.
*/
void serdev_controller_remove(struct serdev_controller *ctrl)
{
int dummy;
if (!ctrl)
return;
dummy = device_for_each_child(&ctrl->dev, NULL,
serdev_remove_device);
device_del(&ctrl->dev);
}
EXPORT_SYMBOL_GPL(serdev_controller_remove);
/**
* serdev_driver_register() - Register client driver with serdev core
* @sdrv: client driver to be associated with client-device.
*
* This API will register the client driver with the serdev framework.
* It is typically called from the driver's module-init function.
*/
int __serdev_device_driver_register(struct serdev_device_driver *sdrv, struct module *owner)
{
sdrv->driver.bus = &serdev_bus_type;
sdrv->driver.owner = owner;
/* force drivers to async probe so I/O is possible in probe */
sdrv->driver.probe_type = PROBE_PREFER_ASYNCHRONOUS;
return driver_register(&sdrv->driver);
}
EXPORT_SYMBOL_GPL(__serdev_device_driver_register);
static void __exit serdev_exit(void)
{
bus_unregister(&serdev_bus_type);
}
module_exit(serdev_exit);
static int __init serdev_init(void)
{
int ret;
ret = bus_register(&serdev_bus_type);
if (ret)
return ret;
is_registered = true;
return 0;
}
/* Must be before serial drivers register */
postcore_initcall(serdev_init);
MODULE_AUTHOR("Rob Herring <robh@kernel.org>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Serial attached device bus");

View File

@ -0,0 +1,226 @@
/*
* Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <robh@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/serdev.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#define SERPORT_ACTIVE 1
struct serport {
struct tty_port *port;
struct tty_struct *tty;
struct tty_driver *tty_drv;
int tty_idx;
unsigned long flags;
};
/*
* Callback functions from the tty port.
*/
static int ttyport_receive_buf(struct tty_port *port, const unsigned char *cp,
const unsigned char *fp, size_t count)
{
struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl);
if (!test_bit(SERPORT_ACTIVE, &serport->flags))
return 0;
return serdev_controller_receive_buf(ctrl, cp, count);
}
static void ttyport_write_wakeup(struct tty_port *port)
{
struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl);
if (!test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags))
return;
if (test_bit(SERPORT_ACTIVE, &serport->flags))
serdev_controller_write_wakeup(ctrl);
}
static const struct tty_port_client_operations client_ops = {
.receive_buf = ttyport_receive_buf,
.write_wakeup = ttyport_write_wakeup,
};
/*
* Callback functions from the serdev core.
*/
static int ttyport_write_buf(struct serdev_controller *ctrl, const unsigned char *data, size_t len)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
struct tty_struct *tty = serport->tty;
if (!test_bit(SERPORT_ACTIVE, &serport->flags))
return 0;
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
return tty->ops->write(serport->tty, data, len);
}
static void ttyport_write_flush(struct serdev_controller *ctrl)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
struct tty_struct *tty = serport->tty;
tty_driver_flush_buffer(tty);
}
static int ttyport_write_room(struct serdev_controller *ctrl)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
struct tty_struct *tty = serport->tty;
return tty_write_room(tty);
}
static int ttyport_open(struct serdev_controller *ctrl)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
struct tty_struct *tty;
struct ktermios ktermios;
tty = tty_init_dev(serport->tty_drv, serport->tty_idx);
if (IS_ERR(tty))
return PTR_ERR(tty);
serport->tty = tty;
serport->port->client_ops = &client_ops;
serport->port->client_data = ctrl;
if (tty->ops->open)
tty->ops->open(serport->tty, NULL);
else
tty_port_open(serport->port, tty, NULL);
/* Bring the UART into a known 8 bits no parity hw fc state */
ktermios = tty->termios;
ktermios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |
INLCR | IGNCR | ICRNL | IXON);
ktermios.c_oflag &= ~OPOST;
ktermios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
ktermios.c_cflag &= ~(CSIZE | PARENB);
ktermios.c_cflag |= CS8;
ktermios.c_cflag |= CRTSCTS;
tty_set_termios(tty, &ktermios);
set_bit(SERPORT_ACTIVE, &serport->flags);
tty_unlock(serport->tty);
return 0;
}
static void ttyport_close(struct serdev_controller *ctrl)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
struct tty_struct *tty = serport->tty;
clear_bit(SERPORT_ACTIVE, &serport->flags);
if (tty->ops->close)
tty->ops->close(tty, NULL);
tty_release_struct(tty, serport->tty_idx);
}
static unsigned int ttyport_set_baudrate(struct serdev_controller *ctrl, unsigned int speed)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
struct tty_struct *tty = serport->tty;
struct ktermios ktermios = tty->termios;
ktermios.c_cflag &= ~CBAUD;
tty_termios_encode_baud_rate(&ktermios, speed, speed);
/* tty_set_termios() return not checked as it is always 0 */
tty_set_termios(tty, &ktermios);
return speed;
}
static void ttyport_set_flow_control(struct serdev_controller *ctrl, bool enable)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
struct tty_struct *tty = serport->tty;
struct ktermios ktermios = tty->termios;
if (enable)
ktermios.c_cflag |= CRTSCTS;
else
ktermios.c_cflag &= ~CRTSCTS;
tty_set_termios(tty, &ktermios);
}
static const struct serdev_controller_ops ctrl_ops = {
.write_buf = ttyport_write_buf,
.write_flush = ttyport_write_flush,
.write_room = ttyport_write_room,
.open = ttyport_open,
.close = ttyport_close,
.set_flow_control = ttyport_set_flow_control,
.set_baudrate = ttyport_set_baudrate,
};
struct device *serdev_tty_port_register(struct tty_port *port,
struct device *parent,
struct tty_driver *drv, int idx)
{
struct serdev_controller *ctrl;
struct serport *serport;
int ret;
if (!port || !drv || !parent)
return ERR_PTR(-ENODEV);
ctrl = serdev_controller_alloc(parent, sizeof(struct serport));
if (!ctrl)
return ERR_PTR(-ENOMEM);
serport = serdev_controller_get_drvdata(ctrl);
serport->port = port;
serport->tty_idx = idx;
serport->tty_drv = drv;
ctrl->ops = &ctrl_ops;
ret = serdev_controller_add(ctrl);
if (ret)
goto err_controller_put;
dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx);
return &ctrl->dev;
err_controller_put:
serdev_controller_put(ctrl);
return ERR_PTR(ret);
}
void serdev_tty_port_unregister(struct tty_port *port)
{
struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl);
if (!serport)
return;
serdev_controller_remove(ctrl);
port->client_ops = NULL;
port->client_data = NULL;
serdev_controller_put(ctrl);
}

View File

@ -201,8 +201,31 @@ static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset)
static int dw8250_handle_irq(struct uart_port *p)
{
struct uart_8250_port *up = up_to_u8250p(p);
struct dw8250_data *d = p->private_data;
unsigned int iir = p->serial_in(p, UART_IIR);
unsigned int status;
unsigned long flags;
/*
* There are ways to get Designware-based UARTs into a state where
* they are asserting UART_IIR_RX_TIMEOUT but there is no actual
* data available. If we see such a case then we'll do a bogus
* read. If we don't do this then the "RX TIMEOUT" interrupt will
* fire forever.
*
* This problem has only been observed so far when not in DMA mode
* so we limit the workaround only to non-DMA mode.
*/
if (!up->dma && ((iir & 0x3f) == UART_IIR_RX_TIMEOUT)) {
spin_lock_irqsave(&p->lock, flags);
status = p->serial_in(p, UART_LSR);
if (!(status & (UART_LSR_DR | UART_LSR_BI)))
(void) p->serial_in(p, UART_RX);
spin_unlock_irqrestore(&p->lock, flags);
}
if (serial8250_handle_irq(p, iir))
return 1;
@ -248,11 +271,11 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
if (!ret)
p->uartclk = rate;
out:
p->status &= ~UPSTAT_AUTOCTS;
if (termios->c_cflag & CRTSCTS)
p->status |= UPSTAT_AUTOCTS;
out:
serial8250_do_set_termios(p, termios, old);
}
@ -326,13 +349,11 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
p->serial_in = dw8250_serial_in32;
data->uart_16550_compatible = true;
}
p->set_termios = dw8250_set_termios;
}
/* Platforms with iDMA */
if (platform_get_resource_byname(to_platform_device(p->dev),
IORESOURCE_MEM, "lpss_priv")) {
p->set_termios = dw8250_set_termios;
data->dma.rx_param = p->dev->parent;
data->dma.tx_param = p->dev->parent;
data->dma.fn = dw8250_idma_filter;
@ -414,6 +435,7 @@ static int dw8250_probe(struct platform_device *pdev)
p->serial_in = dw8250_serial_in;
p->serial_out = dw8250_serial_out;
p->set_ldisc = dw8250_set_ldisc;
p->set_termios = dw8250_set_termios;
p->membase = devm_ioremap(dev, regs->start, resource_size(regs));
if (!p->membase)

View File

@ -0,0 +1,487 @@
/*
* Probe module for 8250/16550-type Exar chips PCI serial ports.
*
* Based on drivers/tty/serial/8250/8250_pci.c,
*
* Copyright (C) 2017 Sudip Mukherjee, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*/
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/tty.h>
#include <linux/8250_pci.h>
#include <asm/byteorder.h>
#include "8250.h"
#define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002
#define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004
#define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a
#define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b
#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020
#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021
#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022
#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358
#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358
#define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */
#define UART_EXAR_FCTR 0x08 /* Feature Control Register */
#define UART_FCTR_EXAR_IRDA 0x10 /* IrDa data encode select */
#define UART_FCTR_EXAR_485 0x20 /* Auto 485 half duplex dir ctl */
#define UART_FCTR_EXAR_TRGA 0x00 /* FIFO trigger table A */
#define UART_FCTR_EXAR_TRGB 0x60 /* FIFO trigger table B */
#define UART_FCTR_EXAR_TRGC 0x80 /* FIFO trigger table C */
#define UART_FCTR_EXAR_TRGD 0xc0 /* FIFO trigger table D programmable */
#define UART_EXAR_TXTRG 0x0a /* Tx FIFO trigger level write-only */
#define UART_EXAR_RXTRG 0x0b /* Rx FIFO trigger level write-only */
#define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */
#define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */
#define UART_EXAR_MPIO3T_7_0 0x91 /* MPIO3T[7:0] */
#define UART_EXAR_MPIOINV_7_0 0x92 /* MPIOINV[7:0] */
#define UART_EXAR_MPIOSEL_7_0 0x93 /* MPIOSEL[7:0] */
#define UART_EXAR_MPIOOD_7_0 0x94 /* MPIOOD[7:0] */
#define UART_EXAR_MPIOINT_15_8 0x95 /* MPIOINT[15:8] */
#define UART_EXAR_MPIOLVL_15_8 0x96 /* MPIOLVL[15:8] */
#define UART_EXAR_MPIO3T_15_8 0x97 /* MPIO3T[15:8] */
#define UART_EXAR_MPIOINV_15_8 0x98 /* MPIOINV[15:8] */
#define UART_EXAR_MPIOSEL_15_8 0x99 /* MPIOSEL[15:8] */
#define UART_EXAR_MPIOOD_15_8 0x9a /* MPIOOD[15:8] */
struct exar8250;
/**
* struct exar8250_board - board information
* @num_ports: number of serial ports
* @reg_shift: describes UART register mapping in PCI memory
*/
struct exar8250_board {
unsigned int num_ports;
unsigned int reg_shift;
bool has_slave;
int (*setup)(struct exar8250 *, struct pci_dev *,
struct uart_8250_port *, int);
void (*exit)(struct pci_dev *pcidev);
};
struct exar8250 {
unsigned int nr;
struct exar8250_board *board;
int line[0];
};
static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
int idx, unsigned int offset,
struct uart_8250_port *port)
{
const struct exar8250_board *board = priv->board;
unsigned int bar = 0;
if (!pcim_iomap_table(pcidev)[bar] && !pcim_iomap(pcidev, bar, 0))
return -ENOMEM;
port->port.iotype = UPIO_MEM;
port->port.mapbase = pci_resource_start(pcidev, bar) + offset;
port->port.membase = pcim_iomap_table(pcidev)[bar] + offset;
port->port.regshift = board->reg_shift;
return 0;
}
static int
pci_fastcom335_setup(struct exar8250 *priv, struct pci_dev *pcidev,
struct uart_8250_port *port, int idx)
{
unsigned int offset = idx * 0x200;
unsigned int baud = 1843200;
u8 __iomem *p;
int err;
port->port.flags |= UPF_EXAR_EFR;
port->port.uartclk = baud * 16;
err = default_setup(priv, pcidev, idx, offset, port);
if (err)
return err;
p = port->port.membase;
writeb(0x00, p + UART_EXAR_8XMODE);
writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
writeb(32, p + UART_EXAR_TXTRG);
writeb(32, p + UART_EXAR_RXTRG);
/*
* Setup Multipurpose Input/Output pins.
*/
if (idx == 0) {
switch (pcidev->device) {
case PCI_DEVICE_ID_COMMTECH_4222PCI335:
case PCI_DEVICE_ID_COMMTECH_4224PCI335:
writeb(0x78, p + UART_EXAR_MPIOLVL_7_0);
writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
break;
case PCI_DEVICE_ID_COMMTECH_2324PCI335:
case PCI_DEVICE_ID_COMMTECH_2328PCI335:
writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
writeb(0xc0, p + UART_EXAR_MPIOINV_7_0);
writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0);
break;
}
writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
}
return 0;
}
static int
pci_connect_tech_setup(struct exar8250 *priv, struct pci_dev *pcidev,
struct uart_8250_port *port, int idx)
{
unsigned int offset = idx * 0x200;
unsigned int baud = 1843200;
port->port.uartclk = baud * 16;
return default_setup(priv, pcidev, idx, offset, port);
}
static int
pci_xr17c154_setup(struct exar8250 *priv, struct pci_dev *pcidev,
struct uart_8250_port *port, int idx)
{
unsigned int offset = idx * 0x200;
unsigned int baud = 921600;
port->port.uartclk = baud * 16;
return default_setup(priv, pcidev, idx, offset, port);
}
static void setup_gpio(u8 __iomem *p)
{
writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
writeb(0x00, p + UART_EXAR_MPIOINT_15_8);
writeb(0x00, p + UART_EXAR_MPIOLVL_15_8);
writeb(0x00, p + UART_EXAR_MPIO3T_15_8);
writeb(0x00, p + UART_EXAR_MPIOINV_15_8);
writeb(0x00, p + UART_EXAR_MPIOSEL_15_8);
writeb(0x00, p + UART_EXAR_MPIOOD_15_8);
}
static void *
xr17v35x_register_gpio(struct pci_dev *pcidev)
{
struct platform_device *pdev;
pdev = platform_device_alloc("gpio_exar", PLATFORM_DEVID_AUTO);
if (!pdev)
return NULL;
platform_set_drvdata(pdev, pcidev);
if (platform_device_add(pdev) < 0) {
platform_device_put(pdev);
return NULL;
}
return pdev;
}
static int
pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev,
struct uart_8250_port *port, int idx)
{
const struct exar8250_board *board = priv->board;
unsigned int offset = idx * 0x400;
unsigned int baud = 7812500;
u8 __iomem *p;
int ret;
port->port.uartclk = baud * 16;
/*
* Setup the uart clock for the devices on expansion slot to
* half the clock speed of the main chip (which is 125MHz)
*/
if (board->has_slave && idx >= 8)
port->port.uartclk /= 2;
ret = default_setup(priv, pcidev, idx, offset, port);
if (ret)
return ret;
p = port->port.membase;
writeb(0x00, p + UART_EXAR_8XMODE);
writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
writeb(128, p + UART_EXAR_TXTRG);
writeb(128, p + UART_EXAR_RXTRG);
if (idx == 0) {
/* Setup Multipurpose Input/Output pins. */
setup_gpio(p);
port->port.private_data = xr17v35x_register_gpio(pcidev);
}
return 0;
}
static void pci_xr17v35x_exit(struct pci_dev *pcidev)
{
struct exar8250 *priv = pci_get_drvdata(pcidev);
struct uart_8250_port *port = serial8250_get_port(priv->line[0]);
struct platform_device *pdev = port->port.private_data;
platform_device_unregister(pdev);
port->port.private_data = NULL;
}
static int
exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
{
unsigned int nr_ports, i, bar = 0, maxnr;
struct exar8250_board *board;
struct uart_8250_port uart;
struct exar8250 *priv;
int rc;
board = (struct exar8250_board *)ent->driver_data;
if (!board)
return -EINVAL;
rc = pcim_enable_device(pcidev);
if (rc)
return rc;
maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3);
nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f;
priv = devm_kzalloc(&pcidev->dev, sizeof(*priv) +
sizeof(unsigned int) * nr_ports,
GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->board = board;
pci_set_master(pcidev);
rc = pci_alloc_irq_vectors(pcidev, 1, 1, PCI_IRQ_ALL_TYPES);
if (rc < 0)
return rc;
memset(&uart, 0, sizeof(uart));
uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ
| UPF_EXAR_EFR;
uart.port.irq = pci_irq_vector(pcidev, 0);
uart.port.dev = &pcidev->dev;
for (i = 0; i < nr_ports && i < maxnr; i++) {
rc = board->setup(priv, pcidev, &uart, i);
if (rc) {
dev_err(&pcidev->dev, "Failed to setup port %u\n", i);
break;
}
dev_dbg(&pcidev->dev, "Setup PCI port: port %lx, irq %d, type %d\n",
uart.port.iobase, uart.port.irq, uart.port.iotype);
priv->line[i] = serial8250_register_8250_port(&uart);
if (priv->line[i] < 0) {
dev_err(&pcidev->dev,
"Couldn't register serial port %lx, irq %d, type %d, error %d\n",
uart.port.iobase, uart.port.irq,
uart.port.iotype, priv->line[i]);
break;
}
}
priv->nr = i;
pci_set_drvdata(pcidev, priv);
return 0;
}
static void exar_pci_remove(struct pci_dev *pcidev)
{
struct exar8250 *priv = pci_get_drvdata(pcidev);
unsigned int i;
for (i = 0; i < priv->nr; i++)
serial8250_unregister_port(priv->line[i]);
if (priv->board->exit)
priv->board->exit(pcidev);
}
static int __maybe_unused exar_suspend(struct device *dev)
{
struct pci_dev *pcidev = to_pci_dev(dev);
struct exar8250 *priv = pci_get_drvdata(pcidev);
unsigned int i;
for (i = 0; i < priv->nr; i++)
if (priv->line[i] >= 0)
serial8250_suspend_port(priv->line[i]);
/* Ensure that every init quirk is properly torn down */
if (priv->board->exit)
priv->board->exit(pcidev);
return 0;
}
static int __maybe_unused exar_resume(struct device *dev)
{
struct pci_dev *pcidev = to_pci_dev(dev);
struct exar8250 *priv = pci_get_drvdata(pcidev);
unsigned int i;
for (i = 0; i < priv->nr; i++)
if (priv->line[i] >= 0)
serial8250_resume_port(priv->line[i]);
return 0;
}
static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume);
static const struct exar8250_board pbn_fastcom335_2 = {
.num_ports = 2,
.setup = pci_fastcom335_setup,
};
static const struct exar8250_board pbn_fastcom335_4 = {
.num_ports = 4,
.setup = pci_fastcom335_setup,
};
static const struct exar8250_board pbn_fastcom335_8 = {
.num_ports = 8,
.setup = pci_fastcom335_setup,
};
static const struct exar8250_board pbn_connect = {
.setup = pci_connect_tech_setup,
};
static const struct exar8250_board pbn_exar_ibm_saturn = {
.num_ports = 1,
.setup = pci_xr17c154_setup,
};
static const struct exar8250_board pbn_exar_XR17C15x = {
.setup = pci_xr17c154_setup,
};
static const struct exar8250_board pbn_exar_XR17V35x = {
.setup = pci_xr17v35x_setup,
.exit = pci_xr17v35x_exit,
};
static const struct exar8250_board pbn_exar_XR17V4358 = {
.num_ports = 12,
.has_slave = true,
.setup = pci_xr17v35x_setup,
.exit = pci_xr17v35x_exit,
};
static const struct exar8250_board pbn_exar_XR17V8358 = {
.num_ports = 16,
.has_slave = true,
.setup = pci_xr17v35x_setup,
.exit = pci_xr17v35x_exit,
};
#define CONNECT_DEVICE(devid, sdevid, bd) { \
PCI_DEVICE_SUB( \
PCI_VENDOR_ID_EXAR, \
PCI_DEVICE_ID_EXAR_##devid, \
PCI_SUBVENDOR_ID_CONNECT_TECH, \
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_##sdevid), 0, 0, \
(kernel_ulong_t)&bd \
}
#define EXAR_DEVICE(vend, devid, bd) { \
PCI_VDEVICE(vend, PCI_DEVICE_ID_##devid), (kernel_ulong_t)&bd \
}
#define IBM_DEVICE(devid, sdevid, bd) { \
PCI_DEVICE_SUB( \
PCI_VENDOR_ID_EXAR, \
PCI_DEVICE_ID_EXAR_##devid, \
PCI_VENDOR_ID_IBM, \
PCI_SUBDEVICE_ID_IBM_##sdevid), 0, 0, \
(kernel_ulong_t)&bd \
}
static struct pci_device_id exar_pci_tbl[] = {
CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect),
CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect),
CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect),
CONNECT_DEVICE(XR17C152, UART_1_1, pbn_connect),
CONNECT_DEVICE(XR17C154, UART_2_2, pbn_connect),
CONNECT_DEVICE(XR17C158, UART_4_4, pbn_connect),
CONNECT_DEVICE(XR17C152, UART_2, pbn_connect),
CONNECT_DEVICE(XR17C154, UART_4, pbn_connect),
CONNECT_DEVICE(XR17C158, UART_8, pbn_connect),
CONNECT_DEVICE(XR17C152, UART_2_485, pbn_connect),
CONNECT_DEVICE(XR17C154, UART_4_485, pbn_connect),
CONNECT_DEVICE(XR17C158, UART_8_485, pbn_connect),
IBM_DEVICE(XR17C152, SATURN_SERIAL_ONE_PORT, pbn_exar_ibm_saturn),
/* Exar Corp. XR17C15[248] Dual/Quad/Octal UART */
EXAR_DEVICE(EXAR, EXAR_XR17C152, pbn_exar_XR17C15x),
EXAR_DEVICE(EXAR, EXAR_XR17C154, pbn_exar_XR17C15x),
EXAR_DEVICE(EXAR, EXAR_XR17C158, pbn_exar_XR17C15x),
/* Exar Corp. XR17V[48]35[248] Dual/Quad/Octal/Hexa PCIe UARTs */
EXAR_DEVICE(EXAR, EXAR_XR17V352, pbn_exar_XR17V35x),
EXAR_DEVICE(EXAR, EXAR_XR17V354, pbn_exar_XR17V35x),
EXAR_DEVICE(EXAR, EXAR_XR17V358, pbn_exar_XR17V35x),
EXAR_DEVICE(EXAR, EXAR_XR17V4358, pbn_exar_XR17V4358),
EXAR_DEVICE(EXAR, EXAR_XR17V8358, pbn_exar_XR17V8358),
EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_exar_XR17V35x),
EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_exar_XR17V35x),
EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_exar_XR17V35x),
EXAR_DEVICE(COMMTECH, COMMTECH_4222PCI335, pbn_fastcom335_2),
EXAR_DEVICE(COMMTECH, COMMTECH_4224PCI335, pbn_fastcom335_4),
EXAR_DEVICE(COMMTECH, COMMTECH_2324PCI335, pbn_fastcom335_4),
EXAR_DEVICE(COMMTECH, COMMTECH_2328PCI335, pbn_fastcom335_8),
{ 0, }
};
MODULE_DEVICE_TABLE(pci, exar_pci_tbl);
static struct pci_driver exar_pci_driver = {
.name = "exar_serial",
.probe = exar_pci_probe,
.remove = exar_pci_remove,
.driver = {
.pm = &exar_pci_pm,
},
.id_table = exar_pci_tbl,
};
module_pci_driver(exar_pci_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Exar Serial Dricer");
MODULE_AUTHOR("Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>");

View File

@ -60,6 +60,10 @@ static int __init serial_init_chip(struct parisc_device *dev)
7272727 : 1843200;
uart.port.mapbase = address;
uart.port.membase = ioremap_nocache(address, 16);
if (!uart.port.membase) {
dev_warn(&dev->dev, "Failed to map memory\n");
return -ENOMEM;
}
uart.port.irq = dev->irq;
uart.port.flags = UPF_BOOT_AUTOCONF;
uart.port.dev = &dev->dev;

View File

@ -19,7 +19,7 @@
#include "8250.h"
#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI)
#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) && !defined(CONFIG_COMPILE_TEST)
#warning CONFIG_SERIAL_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure?
#endif

View File

@ -332,10 +332,10 @@ static void lpss8250_remove(struct pci_dev *pdev)
{
struct lpss8250 *lpss = pci_get_drvdata(pdev);
serial8250_unregister_port(lpss->line);
if (lpss->board->exit)
lpss->board->exit(lpss);
serial8250_unregister_port(lpss->line);
}
static const struct lpss8250_board byt_board = {

View File

@ -75,6 +75,37 @@ static int pnw_setup(struct mid8250 *mid, struct uart_port *p)
return 0;
}
static int tng_handle_irq(struct uart_port *p)
{
struct mid8250 *mid = p->private_data;
struct uart_8250_port *up = up_to_u8250p(p);
struct hsu_dma_chip *chip;
u32 status;
int ret = 0;
int err;
chip = pci_get_drvdata(mid->dma_dev);
/* Rx DMA */
err = hsu_dma_get_status(chip, mid->dma_index * 2 + 1, &status);
if (err > 0) {
serial8250_rx_dma_flush(up);
ret |= 1;
} else if (err == 0)
ret |= hsu_dma_do_irq(chip, mid->dma_index * 2 + 1, status);
/* Tx DMA */
err = hsu_dma_get_status(chip, mid->dma_index * 2, &status);
if (err > 0)
ret |= 1;
else if (err == 0)
ret |= hsu_dma_do_irq(chip, mid->dma_index * 2, status);
/* UART */
ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
return IRQ_RETVAL(ret);
}
static int tng_setup(struct mid8250 *mid, struct uart_port *p)
{
struct pci_dev *pdev = to_pci_dev(p->dev);
@ -90,6 +121,8 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
mid->dma_index = index;
mid->dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(5, 0));
p->handle_irq = tng_handle_irq;
return 0;
}
@ -131,8 +164,16 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p)
unsigned int bar = FL_GET_BASE(mid->board->flags);
int ret;
pci_set_master(pdev);
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
p->irq = pci_irq_vector(pdev, 0);
chip->dev = &pdev->dev;
chip->irq = pdev->irq;
chip->irq = pci_irq_vector(pdev, 0);
chip->regs = p->membase;
chip->length = pci_resource_len(pdev, bar);
chip->offset = DNV_DMA_CHAN_OFFSET;
@ -250,8 +291,6 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret)
return ret;
pci_set_master(pdev);
mid = devm_kzalloc(&pdev->dev, sizeof(*mid), GFP_KERNEL);
if (!mid)
return -ENOMEM;

View File

@ -68,6 +68,7 @@ static int moxa8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sizeof(unsigned int) * nr_ports, GFP_KERNEL);
if (!brd)
return -ENOMEM;
brd->num_ports = nr_ports;
memset(&uart, 0, sizeof(struct uart_8250_port));

View File

@ -172,7 +172,8 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
{
const struct of_device_id *match;
struct of_serial_info *info;
struct uart_port port;
struct uart_8250_port port8250;
u32 tx_threshold;
int port_type;
int ret;
@ -188,41 +189,24 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
return -ENOMEM;
port_type = (unsigned long)match->data;
ret = of_platform_serial_setup(ofdev, port_type, &port, info);
memset(&port8250, 0, sizeof(port8250));
ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info);
if (ret)
goto out;
switch (port_type) {
case PORT_8250 ... PORT_MAX_8250:
{
u32 tx_threshold;
struct uart_8250_port port8250;
memset(&port8250, 0, sizeof(port8250));
port8250.port = port;
if (port8250.port.fifosize)
port8250.capabilities = UART_CAP_FIFO;
if (port.fifosize)
port8250.capabilities = UART_CAP_FIFO;
/* Check for TX FIFO threshold & set tx_loadsz */
if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold",
&tx_threshold) == 0) &&
(tx_threshold < port8250.port.fifosize))
port8250.tx_loadsz = port8250.port.fifosize - tx_threshold;
/* Check for TX FIFO threshold & set tx_loadsz */
if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold",
&tx_threshold) == 0) &&
(tx_threshold < port.fifosize))
port8250.tx_loadsz = port.fifosize - tx_threshold;
if (of_property_read_bool(ofdev->dev.of_node, "auto-flow-control"))
port8250.capabilities |= UART_CAP_AFE;
if (of_property_read_bool(ofdev->dev.of_node,
"auto-flow-control"))
port8250.capabilities |= UART_CAP_AFE;
ret = serial8250_register_8250_port(&port8250);
break;
}
default:
/* need to add code for these */
case PORT_UNKNOWN:
dev_info(&ofdev->dev, "Unknown serial port found, ignored\n");
ret = -ENODEV;
break;
}
ret = serial8250_register_8250_port(&port8250);
if (ret < 0)
goto out;
@ -232,7 +216,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
return 0;
out:
kfree(info);
irq_dispose_mapping(port.irq);
irq_dispose_mapping(port8250.port.irq);
return ret;
}
@ -242,14 +226,8 @@ out:
static int of_platform_serial_remove(struct platform_device *ofdev)
{
struct of_serial_info *info = platform_get_drvdata(ofdev);
switch (info->type) {
case PORT_8250 ... PORT_MAX_8250:
serial8250_unregister_port(info->line);
break;
default:
/* need to add code for these */
break;
}
serial8250_unregister_port(info->line);
if (info->clk)
clk_disable_unprepare(info->clk);
@ -258,38 +236,16 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
}
#ifdef CONFIG_PM_SLEEP
static void of_serial_suspend_8250(struct of_serial_info *info)
static int of_serial_suspend(struct device *dev)
{
struct of_serial_info *info = dev_get_drvdata(dev);
struct uart_8250_port *port8250 = serial8250_get_port(info->line);
struct uart_port *port = &port8250->port;
serial8250_suspend_port(info->line);
if (info->clk && (!uart_console(port) || console_suspend_enabled))
clk_disable_unprepare(info->clk);
}
static void of_serial_resume_8250(struct of_serial_info *info)
{
struct uart_8250_port *port8250 = serial8250_get_port(info->line);
struct uart_port *port = &port8250->port;
if (info->clk && (!uart_console(port) || console_suspend_enabled))
clk_prepare_enable(info->clk);
serial8250_resume_port(info->line);
}
static int of_serial_suspend(struct device *dev)
{
struct of_serial_info *info = dev_get_drvdata(dev);
switch (info->type) {
case PORT_8250 ... PORT_MAX_8250:
of_serial_suspend_8250(info);
break;
default:
break;
}
return 0;
}
@ -297,14 +253,13 @@ static int of_serial_suspend(struct device *dev)
static int of_serial_resume(struct device *dev)
{
struct of_serial_info *info = dev_get_drvdata(dev);
struct uart_8250_port *port8250 = serial8250_get_port(info->line);
struct uart_port *port = &port8250->port;
switch (info->type) {
case PORT_8250 ... PORT_MAX_8250:
of_serial_resume_8250(info);
break;
default:
break;
}
if (info->clk && (!uart_console(port) || console_suspend_enabled))
clk_prepare_enable(info->clk);
serial8250_resume_port(info->line);
return 0;
}
@ -332,6 +287,7 @@ static const struct of_device_id of_platform_serial_table[] = {
.data = (void *)PORT_ALTR_16550_F128, },
{ .compatible = "mrvl,mmp-uart",
.data = (void *)PORT_XSCALE, },
{ .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, },
{ /* end of list */ },
};
MODULE_DEVICE_TABLE(of, of_platform_serial_table);

View File

@ -790,6 +790,7 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
{
struct omap8250_priv *priv = p->port.private_data;
struct uart_8250_dma *dma = p->dma;
struct dma_tx_state state;
unsigned long flags;
int ret;
@ -800,10 +801,12 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
return;
}
ret = dmaengine_pause(dma->rxchan);
if (WARN_ON_ONCE(ret))
priv->rx_dma_broken = true;
ret = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
if (ret == DMA_IN_PROGRESS) {
ret = dmaengine_pause(dma->rxchan);
if (WARN_ON_ONCE(ret))
priv->rx_dma_broken = true;
}
spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
__dma_rx_do_complete(p);
@ -1075,15 +1078,15 @@ static int omap8250_no_handle_irq(struct uart_port *port)
}
static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE;
static const u8 am4372_habit = UART_ERRATA_CLOCK_DISABLE;
static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE;
static const struct of_device_id omap8250_dt_ids[] = {
{ .compatible = "ti,omap2-uart" },
{ .compatible = "ti,omap3-uart" },
{ .compatible = "ti,omap4-uart" },
{ .compatible = "ti,am3352-uart", .data = &am3352_habit, },
{ .compatible = "ti,am4372-uart", .data = &am4372_habit, },
{ .compatible = "ti,dra742-uart", .data = &am4372_habit, },
{ .compatible = "ti,am4372-uart", .data = &am3352_habit, },
{ .compatible = "ti,dra742-uart", .data = &dra742_habit, },
{},
};
MODULE_DEVICE_TABLE(of, omap8250_dt_ids);
@ -1218,14 +1221,6 @@ static int omap8250_probe(struct platform_device *pdev)
priv->omap8250_dma.rx_size = RX_TRIGGER;
priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER;
priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER;
if (of_machine_is_compatible("ti,am33xx"))
priv->habit |= OMAP_DMA_TX_KICK;
/*
* pause is currently not supported atleast on omap-sdma
* and edma on most earlier kernels.
*/
priv->rx_dma_broken = true;
}
}
#endif
@ -1240,7 +1235,8 @@ static int omap8250_probe(struct platform_device *pdev)
pm_runtime_put_autosuspend(&pdev->dev);
return 0;
err:
pm_runtime_put(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return ret;
}
@ -1249,6 +1245,7 @@ static int omap8250_remove(struct platform_device *pdev)
{
struct omap8250_priv *priv = platform_get_drvdata(pdev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
serial8250_unregister_port(priv->line);
@ -1348,6 +1345,10 @@ static int omap8250_runtime_suspend(struct device *dev)
struct omap8250_priv *priv = dev_get_drvdata(dev);
struct uart_8250_port *up;
/* In case runtime-pm tries this before we are setup */
if (!priv)
return 0;
up = serial8250_get_port(priv->line);
/*
* When using 'no_console_suspend', the console UART must not be

View File

@ -1477,11 +1477,16 @@ static int pci_fintek_init(struct pci_dev *dev)
{
unsigned long iobase;
u32 max_port, i;
u32 bar_data[3];
resource_size_t bar_data[3];
u8 config_base;
struct serial_private *priv = pci_get_drvdata(dev);
struct uart_8250_port *port;
if (!(pci_resource_flags(dev, 5) & IORESOURCE_IO) ||
!(pci_resource_flags(dev, 4) & IORESOURCE_IO) ||
!(pci_resource_flags(dev, 3) & IORESOURCE_IO))
return -ENODEV;
switch (dev->device) {
case 0x1104: /* 4 ports */
case 0x1108: /* 8 ports */
@ -1495,9 +1500,9 @@ static int pci_fintek_init(struct pci_dev *dev)
}
/* Get the io address dispatch from the BIOS */
pci_read_config_dword(dev, 0x24, &bar_data[0]);
pci_read_config_dword(dev, 0x20, &bar_data[1]);
pci_read_config_dword(dev, 0x1c, &bar_data[2]);
bar_data[0] = pci_resource_start(dev, 5);
bar_data[1] = pci_resource_start(dev, 4);
bar_data[2] = pci_resource_start(dev, 3);
for (i = 0; i < max_port; ++i) {
/* UART0 configuration offset start from 0x40 */
@ -1605,135 +1610,6 @@ static int pci_eg20t_init(struct pci_dev *dev)
#endif
}
#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358
#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358
#define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */
#define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */
#define UART_EXAR_MPIO3T_7_0 0x91 /* MPIO3T[7:0] */
#define UART_EXAR_MPIOINV_7_0 0x92 /* MPIOINV[7:0] */
#define UART_EXAR_MPIOSEL_7_0 0x93 /* MPIOSEL[7:0] */
#define UART_EXAR_MPIOOD_7_0 0x94 /* MPIOOD[7:0] */
#define UART_EXAR_MPIOINT_15_8 0x95 /* MPIOINT[15:8] */
#define UART_EXAR_MPIOLVL_15_8 0x96 /* MPIOLVL[15:8] */
#define UART_EXAR_MPIO3T_15_8 0x97 /* MPIO3T[15:8] */
#define UART_EXAR_MPIOINV_15_8 0x98 /* MPIOINV[15:8] */
#define UART_EXAR_MPIOSEL_15_8 0x99 /* MPIOSEL[15:8] */
#define UART_EXAR_MPIOOD_15_8 0x9a /* MPIOOD[15:8] */
static int
pci_xr17c154_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
port->port.flags |= UPF_EXAR_EFR;
return pci_default_setup(priv, board, port, idx);
}
static inline int
xr17v35x_has_slave(struct serial_private *priv)
{
const int dev_id = priv->dev->device;
return ((dev_id == PCI_DEVICE_ID_EXAR_XR17V4358) ||
(dev_id == PCI_DEVICE_ID_EXAR_XR17V8358));
}
static int
pci_xr17v35x_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
u8 __iomem *p;
p = pci_ioremap_bar(priv->dev, 0);
if (p == NULL)
return -ENOMEM;
port->port.flags |= UPF_EXAR_EFR;
/*
* Setup the uart clock for the devices on expansion slot to
* half the clock speed of the main chip (which is 125MHz)
*/
if (xr17v35x_has_slave(priv) && idx >= 8)
port->port.uartclk = (7812500 * 16 / 2);
/*
* Setup Multipurpose Input/Output pins.
*/
if (idx == 0) {
writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
writeb(0x00, p + UART_EXAR_MPIOINT_15_8);
writeb(0x00, p + UART_EXAR_MPIOLVL_15_8);
writeb(0x00, p + UART_EXAR_MPIO3T_15_8);
writeb(0x00, p + UART_EXAR_MPIOINV_15_8);
writeb(0x00, p + UART_EXAR_MPIOSEL_15_8);
writeb(0x00, p + UART_EXAR_MPIOOD_15_8);
}
writeb(0x00, p + UART_EXAR_8XMODE);
writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
writeb(128, p + UART_EXAR_TXTRG);
writeb(128, p + UART_EXAR_RXTRG);
iounmap(p);
return pci_default_setup(priv, board, port, idx);
}
#define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004
#define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002
#define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a
#define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b
static int
pci_fastcom335_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
u8 __iomem *p;
p = pci_ioremap_bar(priv->dev, 0);
if (p == NULL)
return -ENOMEM;
port->port.flags |= UPF_EXAR_EFR;
/*
* Setup Multipurpose Input/Output pins.
*/
if (idx == 0) {
switch (priv->dev->device) {
case PCI_DEVICE_ID_COMMTECH_4222PCI335:
case PCI_DEVICE_ID_COMMTECH_4224PCI335:
writeb(0x78, p + UART_EXAR_MPIOLVL_7_0);
writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
break;
case PCI_DEVICE_ID_COMMTECH_2324PCI335:
case PCI_DEVICE_ID_COMMTECH_2328PCI335:
writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
writeb(0xc0, p + UART_EXAR_MPIOINV_7_0);
writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0);
break;
}
writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
}
writeb(0x00, p + UART_EXAR_8XMODE);
writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
writeb(32, p + UART_EXAR_TXTRG);
writeb(32, p + UART_EXAR_RXTRG);
iounmap(p);
return pci_default_setup(priv, board, port, idx);
}
static int
pci_wch_ch353_setup(struct serial_private *priv,
const struct pciserial_board *board,
@ -1809,9 +1685,6 @@ pci_wch_ch38x_setup(struct serial_private *priv,
#define PCI_VENDOR_ID_AGESTAR 0x5372
#define PCI_DEVICE_ID_AGESTAR_9375 0x6872
#define PCI_VENDOR_ID_ASIX 0x9710
#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020
#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021
#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022
#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a
#define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e
@ -2272,65 +2145,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.init = pci_timedia_init,
.setup = pci_timedia_setup,
},
/*
* Exar cards
*/
{
.vendor = PCI_VENDOR_ID_EXAR,
.device = PCI_DEVICE_ID_EXAR_XR17C152,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17c154_setup,
},
{
.vendor = PCI_VENDOR_ID_EXAR,
.device = PCI_DEVICE_ID_EXAR_XR17C154,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17c154_setup,
},
{
.vendor = PCI_VENDOR_ID_EXAR,
.device = PCI_DEVICE_ID_EXAR_XR17C158,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17c154_setup,
},
{
.vendor = PCI_VENDOR_ID_EXAR,
.device = PCI_DEVICE_ID_EXAR_XR17V352,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup,
},
{
.vendor = PCI_VENDOR_ID_EXAR,
.device = PCI_DEVICE_ID_EXAR_XR17V354,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup,
},
{
.vendor = PCI_VENDOR_ID_EXAR,
.device = PCI_DEVICE_ID_EXAR_XR17V358,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup,
},
{
.vendor = PCI_VENDOR_ID_EXAR,
.device = PCI_DEVICE_ID_EXAR_XR17V4358,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup,
},
{
.vendor = PCI_VENDOR_ID_EXAR,
.device = PCI_DEVICE_ID_EXAR_XR17V8358,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup,
},
/*
* Xircom cards
*/
@ -2555,59 +2369,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subdevice = PCI_ANY_ID,
.setup = pci_asix_setup,
},
/*
* Commtech, Inc. Fastcom adapters
*
*/
{
.vendor = PCI_VENDOR_ID_COMMTECH,
.device = PCI_DEVICE_ID_COMMTECH_4222PCI335,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_fastcom335_setup,
},
{
.vendor = PCI_VENDOR_ID_COMMTECH,
.device = PCI_DEVICE_ID_COMMTECH_4224PCI335,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_fastcom335_setup,
},
{
.vendor = PCI_VENDOR_ID_COMMTECH,
.device = PCI_DEVICE_ID_COMMTECH_2324PCI335,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_fastcom335_setup,
},
{
.vendor = PCI_VENDOR_ID_COMMTECH,
.device = PCI_DEVICE_ID_COMMTECH_2328PCI335,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_fastcom335_setup,
},
{
.vendor = PCI_VENDOR_ID_COMMTECH,
.device = PCI_DEVICE_ID_COMMTECH_4222PCIE,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup,
},
{
.vendor = PCI_VENDOR_ID_COMMTECH,
.device = PCI_DEVICE_ID_COMMTECH_4224PCIE,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup,
},
{
.vendor = PCI_VENDOR_ID_COMMTECH,
.device = PCI_DEVICE_ID_COMMTECH_4228PCIE,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_xr17v35x_setup,
},
/*
* Broadcom TruManage (NetXtreme)
*/
@ -2719,17 +2480,11 @@ enum pci_board_num_t {
pbn_b0_4_1152000,
pbn_b0_2_1152000_200,
pbn_b0_4_1152000_200,
pbn_b0_8_1152000_200,
pbn_b0_4_1250000,
pbn_b0_2_1843200,
pbn_b0_4_1843200,
pbn_b0_2_1843200_200,
pbn_b0_4_1843200_200,
pbn_b0_8_1843200_200,
pbn_b0_1_4000000,
pbn_b0_bt_1_115200,
@ -2820,15 +2575,6 @@ enum pci_board_num_t {
pbn_computone_6,
pbn_computone_8,
pbn_sbsxrsio,
pbn_exar_XR17C152,
pbn_exar_XR17C154,
pbn_exar_XR17C158,
pbn_exar_XR17V352,
pbn_exar_XR17V354,
pbn_exar_XR17V358,
pbn_exar_XR17V4358,
pbn_exar_XR17V8358,
pbn_exar_ibm_saturn,
pbn_pasemi_1682M,
pbn_ni8430_2,
pbn_ni8430_4,
@ -2933,25 +2679,11 @@ static struct pciserial_board pci_boards[] = {
.uart_offset = 8,
},
[pbn_b0_2_1152000_200] = {
.flags = FL_BASE0,
.num_ports = 2,
.base_baud = 1152000,
.uart_offset = 0x200,
},
[pbn_b0_4_1152000_200] = {
[pbn_b0_4_1250000] = {
.flags = FL_BASE0,
.num_ports = 4,
.base_baud = 1152000,
.uart_offset = 0x200,
},
[pbn_b0_8_1152000_200] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 1152000,
.uart_offset = 0x200,
.base_baud = 1250000,
.uart_offset = 8,
},
[pbn_b0_2_1843200] = {
@ -2967,24 +2699,6 @@ static struct pciserial_board pci_boards[] = {
.uart_offset = 8,
},
[pbn_b0_2_1843200_200] = {
.flags = FL_BASE0,
.num_ports = 2,
.base_baud = 1843200,
.uart_offset = 0x200,
},
[pbn_b0_4_1843200_200] = {
.flags = FL_BASE0,
.num_ports = 4,
.base_baud = 1843200,
.uart_offset = 0x200,
},
[pbn_b0_8_1843200_200] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 1843200,
.uart_offset = 0x200,
},
[pbn_b0_1_4000000] = {
.flags = FL_BASE0,
.num_ports = 1,
@ -3468,76 +3182,6 @@ static struct pciserial_board pci_boards[] = {
.uart_offset = 256,
.reg_shift = 4,
},
/*
* Exar Corp. XR17C15[248] Dual/Quad/Octal UART
* Only basic 16550A support.
* XR17C15[24] are not tested, but they should work.
*/
[pbn_exar_XR17C152] = {
.flags = FL_BASE0,
.num_ports = 2,
.base_baud = 921600,
.uart_offset = 0x200,
},
[pbn_exar_XR17C154] = {
.flags = FL_BASE0,
.num_ports = 4,
.base_baud = 921600,
.uart_offset = 0x200,
},
[pbn_exar_XR17C158] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 921600,
.uart_offset = 0x200,
},
[pbn_exar_XR17V352] = {
.flags = FL_BASE0,
.num_ports = 2,
.base_baud = 7812500,
.uart_offset = 0x400,
.reg_shift = 0,
.first_offset = 0,
},
[pbn_exar_XR17V354] = {
.flags = FL_BASE0,
.num_ports = 4,
.base_baud = 7812500,
.uart_offset = 0x400,
.reg_shift = 0,
.first_offset = 0,
},
[pbn_exar_XR17V358] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 7812500,
.uart_offset = 0x400,
.reg_shift = 0,
.first_offset = 0,
},
[pbn_exar_XR17V4358] = {
.flags = FL_BASE0,
.num_ports = 12,
.base_baud = 7812500,
.uart_offset = 0x400,
.reg_shift = 0,
.first_offset = 0,
},
[pbn_exar_XR17V8358] = {
.flags = FL_BASE0,
.num_ports = 16,
.base_baud = 7812500,
.uart_offset = 0x400,
.reg_shift = 0,
.first_offset = 0,
},
[pbn_exar_ibm_saturn] = {
.flags = FL_BASE0,
.num_ports = 1,
.base_baud = 921600,
.uart_offset = 0x200,
},
/*
* PA Semi PWRficient PA6T-1682M on-chip UART
*/
@ -3734,6 +3378,10 @@ static const struct pci_device_id blacklist[] = {
{ PCI_VDEVICE(INTEL, 0x228c), },
{ PCI_VDEVICE(INTEL, 0x9ce3), },
{ PCI_VDEVICE(INTEL, 0x9ce4), },
/* Exar devices */
{ PCI_VDEVICE(EXAR, PCI_ANY_ID), },
{ PCI_VDEVICE(COMMTECH, PCI_ANY_ID), },
};
/*
@ -3908,7 +3556,7 @@ err_out:
}
EXPORT_SYMBOL_GPL(pciserial_init_ports);
void pciserial_detach_ports(struct serial_private *priv)
static void pciserial_detach_ports(struct serial_private *priv)
{
struct pci_serial_quirk *quirk;
int i;
@ -4159,58 +3807,6 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_VENDOR_ID_AFAVLAB,
PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0,
pbn_b0_4_1152000 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0,
pbn_b0_2_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232, 0, 0,
pbn_b0_4_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232, 0, 0,
pbn_b0_8_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0,
pbn_b0_2_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2, 0, 0,
pbn_b0_4_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4, 0, 0,
pbn_b0_8_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0,
pbn_b0_2_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4, 0, 0,
pbn_b0_4_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8, 0, 0,
pbn_b0_8_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0,
pbn_b0_2_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485, 0, 0,
pbn_b0_4_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0,
pbn_b0_8_1843200_200 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT,
0, 0, pbn_exar_ibm_saturn },
{ PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b2_bt_1_115200 },
@ -4938,45 +4534,6 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b3_8_115200 },
/*
* Exar Corp. XR17C15[248] Dual/Quad/Octal UART
*/
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17C152 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17C154 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17C158 },
/*
* Exar Corp. XR17V[48]35[248] Dual/Quad/Octal/Hexa PCIe UARTs
*/
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17V352 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17V354 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17V358 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V4358,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17V4358 },
{ PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V8358,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17V8358 },
/*
* Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART
*/
@ -5552,43 +5109,15 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0, 0, pbn_wch384_4 },
/*
* Commtech, Inc. Fastcom adapters
*/
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCI335,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_b0_2_1152000_200 },
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCI335,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_b0_4_1152000_200 },
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2324PCI335,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_b0_4_1152000_200 },
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2328PCI335,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_b0_8_1152000_200 },
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCIE,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17V352 },
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCIE,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17V354 },
{ PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4228PCIE,
PCI_ANY_ID, PCI_ANY_ID,
0,
0, pbn_exar_XR17V358 },
/* Fintek PCI serial cards */
{ PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 },
{ PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 },
{ PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 },
/* MKS Tenta SCOM-080x serial cards */
{ PCI_DEVICE(0x1601, 0x0800), .driver_data = pbn_b0_4_1250000 },
{ PCI_DEVICE(0x1601, 0xa801), .driver_data = pbn_b0_4_1250000 },
/*
* These entries match devices with class COMMUNICATION_SERIAL,
* COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL

View File

@ -44,6 +44,12 @@
#include "8250.h"
/*
* These are definitions for the Exar XR17V35X and XR17(C|D)15X
*/
#define UART_EXAR_SLEEP 0x8b /* Sleep mode */
#define UART_EXAR_DVID 0x8d /* Device identification */
/*
* Debugging.
*/
@ -273,6 +279,15 @@ static const struct serial8250_config uart_config[] = {
.rxtrig_bytes = {1, 4, 8, 14},
.flags = UART_CAP_FIFO,
},
[PORT_DA830] = {
.name = "TI DA8xx/66AK2x",
.fifo_size = 16,
.tx_loadsz = 16,
.fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO |
UART_FCR_R_TRIG_10,
.rxtrig_bytes = {1, 4, 8, 14},
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
};
/* Uart divisor latch read */
@ -1753,8 +1768,6 @@ void serial8250_tx_chars(struct uart_8250_port *up)
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
pr_debug("%s: THRE\n", __func__);
/*
* With RPM enabled, we have to wait until the FIFO is empty before the
* HW can go idle. So we get here once again with empty FIFO and disable
@ -1819,8 +1832,6 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
status = serial_port_in(port, UART_LSR);
pr_debug("%s: status = %x\n", __func__, status);
if (status & (UART_LSR_DR | UART_LSR_BI)) {
if (!up->dma || handle_rx_dma(up, iir))
status = serial8250_rx_chars(up, status);
@ -2118,6 +2129,19 @@ int serial8250_do_startup(struct uart_port *port)
serial_port_out(port, UART_LCR, 0);
}
if (port->type == PORT_DA830) {
/* Reset the port */
serial_port_out(port, UART_IER, 0);
serial_port_out(port, UART_DA830_PWREMU_MGMT, 0);
mdelay(10);
/* Enable Tx, Rx and free run mode */
serial_port_out(port, UART_DA830_PWREMU_MGMT,
UART_DA830_PWREMU_MGMT_UTRST |
UART_DA830_PWREMU_MGMT_URRST |
UART_DA830_PWREMU_MGMT_FREE);
}
#ifdef CONFIG_SERIAL_8250_RSA
/*
* If this is an RSA port, see if we can kick it up to the

View File

@ -117,7 +117,7 @@ config SERIAL_8250_DMA
compatible UART controllers that support DMA signaling.
config SERIAL_8250_PCI
tristate "8250/16550 PCI device support" if EXPERT
tristate "8250/16550 PCI device support"
depends on SERIAL_8250 && PCI
default SERIAL_8250
help
@ -127,6 +127,11 @@ config SERIAL_8250_PCI
Note that serial ports on NetMos 9835 Multi-I/O cards are handled
by the parport_serial driver, enabled with CONFIG_PARPORT_SERIAL.
config SERIAL_8250_EXAR
tristate "8250/16550 PCI device support"
depends on SERIAL_8250_PCI
default SERIAL_8250
config SERIAL_8250_HP300
tristate
depends on SERIAL_8250 && HP300
@ -402,7 +407,7 @@ config SERIAL_8250_INGENIC
its UARTs, say Y to this option. If unsure, say N.
config SERIAL_8250_LPSS
tristate "Support for serial ports on Intel LPSS platforms" if EXPERT
tristate "Support for serial ports on Intel LPSS platforms"
default SERIAL_8250
depends on SERIAL_8250 && PCI
depends on X86 || COMPILE_TEST
@ -417,7 +422,7 @@ config SERIAL_8250_LPSS
- Intel Quark X1000 SoC
config SERIAL_8250_MID
tristate "Support for serial ports on Intel MID platforms" if EXPERT
tristate "Support for serial ports on Intel MID platforms"
default SERIAL_8250
depends on SERIAL_8250 && PCI
depends on X86 || COMPILE_TEST

View File

@ -10,6 +10,7 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o
8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o
obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
obj-$(CONFIG_SERIAL_8250_EXAR) += 8250_exar.o
obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o

View File

@ -1161,6 +1161,7 @@ config SERIAL_LANTIQ
depends on LANTIQ
select SERIAL_CORE
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
help
Support for console and UART on Lantiq SoCs.

View File

@ -554,7 +554,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
return ret;
}
static struct uart_ops amba_pl010_pops = {
static const struct uart_ops amba_pl010_pops = {
.tx_empty = pl010_tx_empty,
.set_mctrl = pl010_set_mctrl,
.get_mctrl = pl010_get_mctrl,

View File

@ -97,6 +97,7 @@ struct vendor_data {
unsigned int fr_dsr;
unsigned int fr_cts;
unsigned int fr_ri;
unsigned int inv_fr;
bool access_32b;
bool oversampling;
bool dma_threshold;
@ -141,6 +142,30 @@ static struct vendor_data vendor_sbsa = {
.fixed_options = true,
};
/*
* Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
* occasionally getting stuck as 1. To avoid the potential for a hang, check
* TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
* implementations, so only do so if an affected platform is detected in
* parse_spcr().
*/
static bool qdf2400_e44_present = false;
static struct vendor_data vendor_qdt_qdf2400_e44 = {
.reg_offset = pl011_std_offsets,
.fr_busy = UART011_FR_TXFE,
.fr_dsr = UART01x_FR_DSR,
.fr_cts = UART01x_FR_CTS,
.fr_ri = UART011_FR_RI,
.inv_fr = UART011_FR_TXFE,
.access_32b = true,
.oversampling = false,
.dma_threshold = false,
.cts_event_workaround = false,
.always_enabled = true,
.fixed_options = true,
};
static u16 pl011_st_offsets[REG_ARRAY_SIZE] = {
[REG_DR] = UART01x_DR,
[REG_ST_DMAWM] = ST_UART011_DMAWM,
@ -1518,7 +1543,10 @@ static unsigned int pl011_tx_empty(struct uart_port *port)
{
struct uart_amba_port *uap =
container_of(port, struct uart_amba_port, port);
unsigned int status = pl011_read(uap, REG_FR);
/* Allow feature register bits to be inverted to work around errata */
unsigned int status = pl011_read(uap, REG_FR) ^ uap->vendor->inv_fr;
return status & (uap->vendor->fr_busy | UART01x_FR_TXFF) ?
0 : TIOCSER_TEMT;
}
@ -2114,7 +2142,7 @@ static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser)
return ret;
}
static struct uart_ops amba_pl011_pops = {
static const struct uart_ops amba_pl011_pops = {
.tx_empty = pl011_tx_empty,
.set_mctrl = pl011_set_mctrl,
.get_mctrl = pl011_get_mctrl,
@ -2215,10 +2243,12 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
uart_console_write(&uap->port, s, count, pl011_console_putchar);
/*
* Finally, wait for transmitter to become empty
* and restore the TCR
* Finally, wait for transmitter to become empty and restore the
* TCR. Allow feature register bits to be inverted to work around
* errata.
*/
while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy)
while ((pl011_read(uap, REG_FR) ^ uap->vendor->inv_fr)
& uap->vendor->fr_busy)
cpu_relax();
if (!uap->vendor->always_enabled)
pl011_write(old_cr, uap, REG_CR);
@ -2340,8 +2370,12 @@ static int __init pl011_console_match(struct console *co, char *name, int idx,
resource_size_t addr;
int i;
if (strcmp(name, "pl011") != 0)
if (strcmp(name, "qdf2400_e44") == 0) {
pr_info_once("UART: Working around QDF2400 SoC erratum 44");
qdf2400_e44_present = true;
} else if (strcmp(name, "pl011") != 0 || strcmp(name, "ttyAMA") != 0) {
return -ENODEV;
}
if (uart_parse_earlycon(options, &iotype, &addr, &options))
return -ENODEV;
@ -2376,13 +2410,29 @@ static struct console amba_console = {
.device = uart_console_device,
.setup = pl011_console_setup,
.match = pl011_console_match,
.flags = CON_PRINTBUFFER,
.flags = CON_PRINTBUFFER | CON_ANYTIME,
.index = -1,
.data = &amba_reg,
};
#define AMBA_CONSOLE (&amba_console)
static void qdf2400_e44_putc(struct uart_port *port, int c)
{
while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
cpu_relax();
writel(c, port->membase + UART01x_DR);
while (!(readl(port->membase + UART01x_FR) & UART011_FR_TXFE))
cpu_relax();
}
static void qdf2400_e44_early_write(struct console *con, const char *s, unsigned n)
{
struct earlycon_device *dev = con->data;
uart_console_write(&dev->port, s, n, qdf2400_e44_putc);
}
static void pl011_putc(struct uart_port *port, int c)
{
while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
@ -2408,7 +2458,8 @@ static int __init pl011_early_console_setup(struct earlycon_device *device,
if (!device->port.membase)
return -ENODEV;
device->con->write = pl011_early_write;
device->con->write = qdf2400_e44_present ?
qdf2400_e44_early_write : pl011_early_write;
return 0;
}
OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup);
@ -2645,7 +2696,8 @@ static int sbsa_uart_probe(struct platform_device *pdev)
uap->port.irq = ret;
uap->reg_offset = vendor_sbsa.reg_offset;
uap->vendor = &vendor_sbsa;
uap->vendor = qdf2400_e44_present ?
&vendor_qdt_qdf2400_e44 : &vendor_sbsa;
uap->fifosize = 32;
uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM;
uap->port.ops = &sbsa_uart_pops;

View File

@ -493,7 +493,7 @@ static int ar933x_uart_verify_port(struct uart_port *port,
return 0;
}
static struct uart_ops ar933x_uart_ops = {
static const struct uart_ops ar933x_uart_ops = {
.tx_empty = ar933x_uart_tx_empty,
.set_mctrl = ar933x_uart_set_mctrl,
.get_mctrl = ar933x_uart_get_mctrl,

View File

@ -175,6 +175,17 @@ struct atmel_uart_port {
unsigned int pending_status;
spinlock_t lock_suspended;
struct {
u32 cr;
u32 mr;
u32 imr;
u32 brgr;
u32 rtor;
u32 ttgr;
u32 fmr;
u32 fimr;
} cache;
int (*prepare_rx)(struct uart_port *port);
int (*prepare_tx)(struct uart_port *port);
void (*schedule_rx)(struct uart_port *port);
@ -1758,7 +1769,9 @@ static void atmel_get_ip_name(struct uart_port *port)
/*
* Only USART devices from at91sam9260 SOC implement fractional
* baudrate.
* baudrate. It is available for all asynchronous modes, with the
* following restriction: the sampling clock's duty cycle is not
* constant.
*/
atmel_port->has_frac_baudrate = false;
atmel_port->has_hw_timer = false;
@ -2202,8 +2215,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
* then
* 8 CD + FP = selected clock / (2 * baudrate)
*/
if (atmel_port->has_frac_baudrate &&
(mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_NORMAL) {
if (atmel_port->has_frac_baudrate) {
div = DIV_ROUND_CLOSEST(port->uartclk, baud * 2);
cd = div >> 3;
fp = div & ATMEL_US_FP_MASK;
@ -2659,6 +2671,20 @@ static int atmel_serial_suspend(struct platform_device *pdev,
cpu_relax();
}
if (atmel_is_console_port(port) && !console_suspend_enabled) {
/* Cache register values as we won't get a full shutdown/startup
* cycle
*/
atmel_port->cache.mr = atmel_uart_readl(port, ATMEL_US_MR);
atmel_port->cache.imr = atmel_uart_readl(port, ATMEL_US_IMR);
atmel_port->cache.brgr = atmel_uart_readl(port, ATMEL_US_BRGR);
atmel_port->cache.rtor = atmel_uart_readl(port,
atmel_port->rtor);
atmel_port->cache.ttgr = atmel_uart_readl(port, ATMEL_US_TTGR);
atmel_port->cache.fmr = atmel_uart_readl(port, ATMEL_US_FMR);
atmel_port->cache.fimr = atmel_uart_readl(port, ATMEL_US_FIMR);
}
/* we can not wake up if we're running on slow clock */
atmel_port->may_wakeup = device_may_wakeup(&pdev->dev);
if (atmel_serial_clk_will_stop()) {
@ -2681,6 +2707,25 @@ static int atmel_serial_resume(struct platform_device *pdev)
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
unsigned long flags;
if (atmel_is_console_port(port) && !console_suspend_enabled) {
atmel_uart_writel(port, ATMEL_US_MR, atmel_port->cache.mr);
atmel_uart_writel(port, ATMEL_US_IER, atmel_port->cache.imr);
atmel_uart_writel(port, ATMEL_US_BRGR, atmel_port->cache.brgr);
atmel_uart_writel(port, atmel_port->rtor,
atmel_port->cache.rtor);
atmel_uart_writel(port, ATMEL_US_TTGR, atmel_port->cache.ttgr);
if (atmel_port->fifo_size) {
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_FIFOEN |
ATMEL_US_RXFCLR | ATMEL_US_TXFLCLR);
atmel_uart_writel(port, ATMEL_US_FMR,
atmel_port->cache.fmr);
atmel_uart_writel(port, ATMEL_US_FIER,
atmel_port->cache.fimr);
}
atmel_start_rx(port);
}
spin_lock_irqsave(&atmel_port->lock_suspended, flags);
if (atmel_port->pending) {
atmel_handle_receive(port, atmel_port->pending);

View File

@ -740,7 +740,7 @@ static int sport_uart_resume(struct device *dev)
return 0;
}
static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = {
static const struct dev_pm_ops bfin_sport_uart_dev_pm_ops = {
.suspend = sport_uart_suspend,
.resume = sport_uart_resume,
};

View File

@ -1302,7 +1302,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
struct uart_cpm_port *pinfo;
struct uart_port *port;
struct device_node *np = NULL;
struct device_node *np;
int i = 0;
if (co->index >= UART_NR) {
@ -1311,17 +1311,19 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
return -ENODEV;
}
do {
np = of_find_node_by_type(np, "serial");
if (!np)
return -ENODEV;
for_each_node_by_type(np, "serial") {
if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") &&
!of_device_is_compatible(np, "fsl,cpm1-scc-uart") &&
!of_device_is_compatible(np, "fsl,cpm2-smc-uart") &&
!of_device_is_compatible(np, "fsl,cpm2-scc-uart"))
i--;
} while (i++ != co->index);
continue;
if (i++ == co->index)
break;
}
if (!np)
return -ENODEV;
pinfo = &cpm_uart_ports[co->index];

View File

@ -739,7 +739,7 @@ static int dz_verify_port(struct uart_port *uport, struct serial_struct *ser)
return ret;
}
static struct uart_ops dz_ops = {
static const struct uart_ops dz_ops = {
.tx_empty = dz_tx_empty,
.get_mctrl = dz_get_mctrl,
.set_mctrl = dz_set_mctrl,

View File

@ -487,7 +487,7 @@ static int efm32_uart_verify_port(struct uart_port *port,
return ret;
}
static struct uart_ops efm32_uart_pops = {
static const struct uart_ops efm32_uart_pops = {
.tx_empty = efm32_uart_tx_empty,
.set_mctrl = efm32_uart_set_mctrl,
.get_mctrl = efm32_uart_get_mctrl,

View File

@ -1407,6 +1407,18 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
/* ask the core to calculate the divisor */
baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
/*
* Need to update the Ring buffer length according to the selected
* baud rate and restart Rx DMA path.
*
* Since timer function acqures sport->port.lock, need to stop before
* acquring same lock because otherwise del_timer_sync() can deadlock.
*/
if (old && sport->lpuart_dma_rx_use) {
del_timer_sync(&sport->lpuart_timer);
lpuart_dma_rx_free(&sport->port);
}
spin_lock_irqsave(&sport->port.lock, flags);
sport->port.read_status_mask = 0;
@ -1456,22 +1468,11 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
/* restore control register */
writeb(old_cr2, sport->port.membase + UARTCR2);
/*
* If new baud rate is set, we will also need to update the Ring buffer
* length according to the selected baud rate and restart Rx DMA path.
*/
if (old) {
if (sport->lpuart_dma_rx_use) {
del_timer_sync(&sport->lpuart_timer);
lpuart_dma_rx_free(&sport->port);
}
if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
sport->lpuart_dma_rx_use = true;
if (old && sport->lpuart_dma_rx_use) {
if (!lpuart_start_rx_dma(sport))
rx_dma_timer_init(sport);
} else {
else
sport->lpuart_dma_rx_use = false;
}
}
spin_unlock_irqrestore(&sport->port.lock, flags);
@ -2131,12 +2132,10 @@ static int lpuart_resume(struct device *dev)
if (sport->lpuart_dma_rx_use) {
if (sport->port.irq_wake) {
if (!lpuart_start_rx_dma(sport)) {
sport->lpuart_dma_rx_use = true;
if (!lpuart_start_rx_dma(sport))
rx_dma_timer_init(sport);
} else {
else
sport->lpuart_dma_rx_use = false;
}
}
}

View File

@ -1286,7 +1286,7 @@ static void icom_config_port(struct uart_port *port, int flags)
port->type = PORT_ICOM;
}
static struct uart_ops icom_ops = {
static const struct uart_ops icom_ops = {
.tx_empty = icom_tx_empty,
.set_mctrl = icom_set_mctrl,
.get_mctrl = icom_get_mctrl,

View File

@ -205,6 +205,7 @@ struct imx_port {
struct timer_list timer;
unsigned int old_status;
unsigned int have_rtscts:1;
unsigned int have_rtsgpio:1;
unsigned int dte_mode:1;
unsigned int irda_inv_rx:1;
unsigned int irda_inv_tx:1;
@ -335,15 +336,15 @@ static void imx_port_ucrs_restore(struct uart_port *port,
static void imx_port_rts_active(struct imx_port *sport, unsigned long *ucr2)
{
*ucr2 &= ~UCR2_CTSC;
*ucr2 |= UCR2_CTS;
*ucr2 &= ~(UCR2_CTSC | UCR2_CTS);
mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS);
}
static void imx_port_rts_inactive(struct imx_port *sport, unsigned long *ucr2)
{
*ucr2 &= ~(UCR2_CTSC | UCR2_CTS);
*ucr2 &= ~UCR2_CTSC;
*ucr2 |= UCR2_CTS;
mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS);
}
@ -376,9 +377,9 @@ static void imx_stop_tx(struct uart_port *port)
readl(port->membase + USR2) & USR2_TXDC) {
temp = readl(port->membase + UCR2);
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
imx_port_rts_inactive(sport, &temp);
else
imx_port_rts_active(sport, &temp);
else
imx_port_rts_inactive(sport, &temp);
temp |= UCR2_RXEN;
writel(temp, port->membase + UCR2);
@ -584,9 +585,9 @@ static void imx_start_tx(struct uart_port *port)
if (port->rs485.flags & SER_RS485_ENABLED) {
temp = readl(port->membase + UCR2);
if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
imx_port_rts_inactive(sport, &temp);
else
imx_port_rts_active(sport, &temp);
else
imx_port_rts_inactive(sport, &temp);
if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
temp &= ~UCR2_RXEN;
writel(temp, port->membase + UCR2);
@ -1476,9 +1477,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
*/
if (port->rs485.flags &
SER_RS485_RTS_AFTER_SEND)
imx_port_rts_inactive(sport, &ucr2);
else
imx_port_rts_active(sport, &ucr2);
else
imx_port_rts_inactive(sport, &ucr2);
} else {
imx_port_rts_auto(sport, &ucr2);
}
@ -1488,9 +1489,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
} else if (port->rs485.flags & SER_RS485_ENABLED) {
/* disable transmitter */
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
imx_port_rts_inactive(sport, &ucr2);
else
imx_port_rts_active(sport, &ucr2);
else
imx_port_rts_inactive(sport, &ucr2);
}
@ -1725,16 +1726,16 @@ static int imx_rs485_config(struct uart_port *port,
rs485conf->delay_rts_after_send = 0;
/* RTS is required to control the transmitter */
if (!sport->have_rtscts)
if (!sport->have_rtscts && !sport->have_rtsgpio)
rs485conf->flags &= ~SER_RS485_ENABLED;
if (rs485conf->flags & SER_RS485_ENABLED) {
/* disable transmitter */
temp = readl(sport->port.membase + UCR2);
if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
imx_port_rts_inactive(sport, &temp);
else
imx_port_rts_active(sport, &temp);
else
imx_port_rts_inactive(sport, &temp);
writel(temp, sport->port.membase + UCR2);
}
@ -2048,6 +2049,9 @@ static int serial_imx_probe_dt(struct imx_port *sport,
if (of_get_property(np, "fsl,dte-mode", NULL))
sport->dte_mode = 1;
if (of_get_property(np, "rts-gpios", NULL))
sport->have_rtsgpio = 1;
return 0;
}
#else

View File

@ -1873,7 +1873,7 @@ static int ic3_request_port(struct uart_port *port)
}
/* Associate the uart functions above - given to serial core */
static struct uart_ops ioc3_ops = {
static const struct uart_ops ioc3_ops = {
.tx_empty = ic3_tx_empty,
.set_mctrl = ic3_set_mctrl,
.get_mctrl = ic3_get_mctrl,

View File

@ -2596,7 +2596,7 @@ static int ic4_request_port(struct uart_port *port)
/* Associate the uart functions above - given to serial core */
static struct uart_ops ioc4_ops = {
static const struct uart_ops ioc4_ops = {
.tx_empty = ic4_tx_empty,
.set_mctrl = ic4_set_mctrl,
.get_mctrl = ic4_get_mctrl,

View File

@ -930,7 +930,7 @@ static int ip22zilog_verify_port(struct uart_port *port, struct serial_struct *s
return -EINVAL;
}
static struct uart_ops ip22zilog_pops = {
static const struct uart_ops ip22zilog_pops = {
.tx_empty = ip22zilog_tx_empty,
.set_mctrl = ip22zilog_set_mctrl,
.get_mctrl = ip22zilog_get_mctrl,

View File

@ -16,7 +16,7 @@
*
* Copyright (C) 2004 Infineon IFAP DC COM CPE
* Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2007 John Crispin <blogic@openwrt.org>
* Copyright (C) 2007 John Crispin <john@phrozen.org>
* Copyright (C) 2010 Thomas Langer, <thomas.langer@lantiq.com>
*/
@ -557,7 +557,7 @@ lqasc_verify_port(struct uart_port *port,
return ret;
}
static struct uart_ops lqasc_pops = {
static const struct uart_ops lqasc_pops = {
.tx_empty = lqasc_tx_empty,
.set_mctrl = lqasc_set_mctrl,
.get_mctrl = lqasc_get_mctrl,
@ -590,13 +590,20 @@ lqasc_console_putchar(struct uart_port *port, int ch)
ltq_w8(ch, port->membase + LTQ_ASC_TBUF);
}
static void lqasc_serial_port_write(struct uart_port *port, const char *s,
u_int count)
{
unsigned long flags;
spin_lock_irqsave(&ltq_asc_lock, flags);
uart_console_write(port, s, count, lqasc_console_putchar);
spin_unlock_irqrestore(&ltq_asc_lock, flags);
}
static void
lqasc_console_write(struct console *co, const char *s, u_int count)
{
struct ltq_uart_port *ltq_port;
struct uart_port *port;
unsigned long flags;
if (co->index >= MAXPORTS)
return;
@ -605,11 +612,7 @@ lqasc_console_write(struct console *co, const char *s, u_int count)
if (!ltq_port)
return;
port = &ltq_port->port;
spin_lock_irqsave(&ltq_asc_lock, flags);
uart_console_write(port, s, count, lqasc_console_putchar);
spin_unlock_irqrestore(&ltq_asc_lock, flags);
lqasc_serial_port_write(&ltq_port->port, s, count);
}
static int __init
@ -659,6 +662,27 @@ lqasc_console_init(void)
}
console_initcall(lqasc_console_init);
static void lqasc_serial_early_console_write(struct console *co,
const char *s,
u_int count)
{
struct earlycon_device *dev = co->data;
lqasc_serial_port_write(&dev->port, s, count);
}
static int __init
lqasc_serial_early_console_setup(struct earlycon_device *device,
const char *opt)
{
if (!device->port.membase)
return -ENODEV;
device->con->write = lqasc_serial_early_console_write;
return 0;
}
OF_EARLYCON_DECLARE(lantiq, DRVNAME, lqasc_serial_early_console_setup);
static struct uart_driver lqasc_reg = {
.owner = THIS_MODULE,
.driver_name = DRVNAME,

View File

@ -645,7 +645,7 @@ static int serial_lpc32xx_verify_port(struct uart_port *port,
return ret;
}
static struct uart_ops serial_lpc32xx_pops = {
static const struct uart_ops serial_lpc32xx_pops = {
.tx_empty = serial_lpc32xx_tx_empty,
.set_mctrl = serial_lpc32xx_set_mctrl,
.get_mctrl = serial_lpc32xx_get_mctrl,

View File

@ -236,7 +236,7 @@
/* Misc definitions */
#define MAX310X_FIFO_SIZE (128)
#define MAX310x_REV_MASK (0xfc)
#define MAX310x_REV_MASK (0xf8)
/* MAX3107 specific */
#define MAX3107_REV_ID (0xa0)

View File

@ -364,7 +364,7 @@ static void meson_uart_set_termios(struct uart_port *port,
writel(val, port->membase + AML_UART_CONTROL);
baud = uart_get_baud_rate(port, termios, old, 9600, 115200);
baud = uart_get_baud_rate(port, termios, old, 9600, 4000000);
meson_uart_change_speed(port, baud);
port->read_status_mask = AML_UART_TX_FIFO_WERR;

View File

@ -1670,7 +1670,7 @@ static void mpsc_put_poll_char(struct uart_port *port,
}
#endif
static struct uart_ops mpsc_pops = {
static const struct uart_ops mpsc_pops = {
.tx_empty = mpsc_tx_empty,
.set_mctrl = mpsc_set_mctrl,
.get_mctrl = mpsc_get_mctrl,

View File

@ -1809,6 +1809,7 @@ static const struct of_device_id msm_match_table[] = {
{ .compatible = "qcom,msm-uartdm" },
{}
};
MODULE_DEVICE_TABLE(of, msm_match_table);
static struct platform_driver msm_platform_driver = {
.remove = msm_serial_remove,

View File

@ -95,6 +95,7 @@
#define AUART_LINECTRL_BAUD_DIVFRAC_SHIFT 8
#define AUART_LINECTRL_BAUD_DIVFRAC_MASK 0x00003f00
#define AUART_LINECTRL_BAUD_DIVFRAC(v) (((v) & 0x3f) << 8)
#define AUART_LINECTRL_SPS (1 << 7)
#define AUART_LINECTRL_WLEN_MASK 0x00000060
#define AUART_LINECTRL_WLEN(v) (((v) & 0x3) << 5)
#define AUART_LINECTRL_FEN (1 << 4)
@ -1014,6 +1015,8 @@ static void mxs_auart_settermios(struct uart_port *u,
ctrl |= AUART_LINECTRL_PEN;
if ((cflag & PARODD) == 0)
ctrl |= AUART_LINECTRL_EPS;
if (cflag & CMSPAR)
ctrl |= AUART_LINECTRL_SPS;
}
u->read_status_mask = AUART_STAT_OERR;

View File

@ -1234,6 +1234,61 @@ out:
#ifdef CONFIG_SERIAL_OMAP_CONSOLE
#ifdef CONFIG_SERIAL_EARLYCON
static unsigned int __init omap_serial_early_in(struct uart_port *port,
int offset)
{
offset <<= port->regshift;
return readw(port->membase + offset);
}
static void __init omap_serial_early_out(struct uart_port *port, int offset,
int value)
{
offset <<= port->regshift;
writew(value, port->membase + offset);
}
static void __init omap_serial_early_putc(struct uart_port *port, int c)
{
unsigned int status;
for (;;) {
status = omap_serial_early_in(port, UART_LSR);
if ((status & BOTH_EMPTY) == BOTH_EMPTY)
break;
cpu_relax();
}
omap_serial_early_out(port, UART_TX, c);
}
static void __init early_omap_serial_write(struct console *console,
const char *s, unsigned int count)
{
struct earlycon_device *device = console->data;
struct uart_port *port = &device->port;
uart_console_write(port, s, count, omap_serial_early_putc);
}
static int __init early_omap_serial_setup(struct earlycon_device *device,
const char *options)
{
struct uart_port *port = &device->port;
if (!(device->port.membase || device->port.iobase))
return -ENODEV;
port->regshift = 2;
device->con->write = early_omap_serial_write;
return 0;
}
OF_EARLYCON_DECLARE(omapserial, "ti,omap2-uart", early_omap_serial_setup);
OF_EARLYCON_DECLARE(omapserial, "ti,omap3-uart", early_omap_serial_setup);
OF_EARLYCON_DECLARE(omapserial, "ti,omap4-uart", early_omap_serial_setup);
#endif /* CONFIG_SERIAL_EARLYCON */
static struct uart_omap_port *serial_omap_console_ports[OMAP_MAX_HSUART_PORTS];
static struct uart_driver serial_omap_reg;
@ -1395,7 +1450,7 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485)
return 0;
}
static struct uart_ops serial_omap_pops = {
static const struct uart_ops serial_omap_pops = {
.tx_empty = serial_omap_tx_empty,
.set_mctrl = serial_omap_set_mctrl,
.get_mctrl = serial_omap_get_mctrl,

View File

@ -495,13 +495,13 @@ static int pic32_uart_startup(struct uart_port *port)
out_t:
kfree(sport->irq_tx_name);
free_irq(sport->irq_tx, sport);
free_irq(sport->irq_tx, port);
out_r:
kfree(sport->irq_rx_name);
free_irq(sport->irq_rx, sport);
free_irq(sport->irq_rx, port);
out_f:
kfree(sport->irq_fault_name);
free_irq(sport->irq_fault, sport);
free_irq(sport->irq_fault, port);
out_done:
return ret;
}

View File

@ -1379,7 +1379,7 @@ static void pmz_poll_put_char(struct uart_port *port, unsigned char c)
#endif /* CONFIG_CONSOLE_POLL */
static struct uart_ops pmz_pops = {
static const struct uart_ops pmz_pops = {
.tx_empty = pmz_tx_empty,
.set_mctrl = pmz_set_mctrl,
.get_mctrl = pmz_get_mctrl,

View File

@ -631,7 +631,7 @@ pnx8xxx_verify_port(struct uart_port *port, struct serial_struct *ser)
return ret;
}
static struct uart_ops pnx8xxx_pops = {
static const struct uart_ops pnx8xxx_pops = {
.tx_empty = pnx8xxx_tx_empty,
.set_mctrl = pnx8xxx_set_mctrl,
.get_mctrl = pnx8xxx_get_mctrl,

View File

@ -762,7 +762,7 @@ static struct console serial_pxa_console = {
#define PXA_CONSOLE NULL
#endif
static struct uart_ops serial_pxa_pops = {
static const struct uart_ops serial_pxa_pops = {
.tx_empty = serial_pxa_tx_empty,
.set_mctrl = serial_pxa_set_mctrl,
.get_mctrl = serial_pxa_get_mctrl,

View File

@ -859,7 +859,6 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
{
struct s3c24xx_uart_dma *dma = p->dma;
dma_cap_mask_t mask;
unsigned long flags;
/* Default slave configuration parameters */
@ -876,21 +875,17 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
else
dma->tx_conf.dst_maxburst = 1;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma->rx_chan = dma_request_chan(p->port.dev, "rx");
dma->rx_chan = dma_request_slave_channel_compat(mask, dma->fn,
dma->rx_param, p->port.dev, "rx");
if (!dma->rx_chan)
return -ENODEV;
if (IS_ERR(dma->rx_chan))
return PTR_ERR(dma->rx_chan);
dmaengine_slave_config(dma->rx_chan, &dma->rx_conf);
dma->tx_chan = dma_request_slave_channel_compat(mask, dma->fn,
dma->tx_param, p->port.dev, "tx");
if (!dma->tx_chan) {
dma->tx_chan = dma_request_chan(p->port.dev, "tx");
if (IS_ERR(dma->tx_chan)) {
dma_release_channel(dma->rx_chan);
return -ENODEV;
return PTR_ERR(dma->tx_chan);
}
dmaengine_slave_config(dma->tx_chan, &dma->tx_conf);
@ -1921,6 +1916,7 @@ static int s3c24xx_serial_resume(struct device *dev)
static int s3c24xx_serial_resume_noirq(struct device *dev)
{
struct uart_port *port = s3c24xx_dev_to_port(dev);
struct s3c24xx_uart_port *ourport = to_ourport(port);
if (port) {
/* restore IRQ mask */
@ -1930,7 +1926,9 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
uintm &= ~S3C64XX_UINTM_TXD_MSK;
if (rx_enabled(port))
uintm &= ~S3C64XX_UINTM_RXD_MSK;
clk_prepare_enable(ourport->clk);
wr_regl(port, S3C64XX_UINTM, uintm);
clk_disable_unprepare(ourport->clk);
}
}

View File

@ -44,10 +44,6 @@ struct s3c24xx_serial_drv_data {
};
struct s3c24xx_uart_dma {
dma_filter_fn fn;
void *rx_param;
void *tx_param;
unsigned int rx_chan_id;
unsigned int tx_chan_id;

View File

@ -1191,7 +1191,7 @@ static const char *tegra_uart_type(struct uart_port *u)
return TEGRA_UART_TYPE;
}
static struct uart_ops tegra_uart_ops = {
static const struct uart_ops tegra_uart_ops = {
.tx_empty = tegra_uart_tx_empty,
.set_mctrl = tegra_uart_set_mctrl,
.get_mctrl = tegra_uart_get_mctrl,

View File

@ -845,7 +845,7 @@ serial_txx9_type(struct uart_port *port)
return "txx9";
}
static struct uart_ops serial_txx9_pops = {
static const struct uart_ops serial_txx9_pops = {
.tx_empty = serial_txx9_tx_empty,
.set_mctrl = serial_txx9_set_mctrl,
.get_mctrl = serial_txx9_get_mctrl,

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,8 @@ enum {
SCPDR, /* Serial Port Data Register */
SCDL, /* BRG Frequency Division Register */
SCCKS, /* BRG Clock Select Register */
HSRTRGR, /* Rx FIFO Data Count Trigger Register */
HSTTRGR, /* Tx FIFO Data Count Trigger Register */
SCIx_NR_REGS,
};
@ -99,6 +101,10 @@ enum {
#define SCIF_BREAK_CLEAR (u32)(~(SCIF_PER | SCIF_FER | SCIF_BRK))
/* SCFCR (FIFO Control Register) */
#define SCFCR_RTRG1 BIT(7) /* Receive FIFO Data Count Trigger */
#define SCFCR_RTRG0 BIT(6)
#define SCFCR_TTRG1 BIT(5) /* Transmit FIFO Data Count Trigger */
#define SCFCR_TTRG0 BIT(4)
#define SCFCR_MCE BIT(3) /* Modem Control Enable */
#define SCFCR_TFRST BIT(2) /* Transmit FIFO Data Register Reset */
#define SCFCR_RFRST BIT(1) /* Receive FIFO Data Register Reset */
@ -145,18 +151,18 @@ enum {
#define SCCKS_XIN BIT(14) /* SC_CLK uses bus clock (1) or SCIF_CLK (0) */
#define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_DR | SCIF_RDF)
#define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE)
#define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER)
#define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER)
#define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
#define SCxSR_ERRORS(port) (to_sci_port(port)->error_mask)
#define SCxSR_ERRORS(port) (to_sci_port(port)->params->error_mask)
#define SCxSR_RDxF_CLEAR(port) \
(((port)->type == PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR)
#define SCxSR_ERROR_CLEAR(port) \
(to_sci_port(port)->error_clear)
(to_sci_port(port)->params->error_clear)
#define SCxSR_TDxE_CLEAR(port) \
(((port)->type == PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR)
#define SCxSR_BREAK_CLEAR(port) \

View File

@ -1061,7 +1061,7 @@ static void sirfsoc_uart_config_port(struct uart_port *port, int flags)
}
}
static struct uart_ops sirfsoc_uart_ops = {
static const struct uart_ops sirfsoc_uart_ops = {
.tx_empty = sirfsoc_uart_tx_empty,
.get_mctrl = sirfsoc_uart_get_mctrl,
.set_mctrl = sirfsoc_uart_set_mctrl,

View File

@ -380,7 +380,7 @@ static void snp_config_port(struct uart_port *port, int flags)
/* Associate the uart functions above - given to serial core */
static struct uart_ops sn_console_ops = {
static const struct uart_ops sn_console_ops = {
.tx_empty = snp_tx_empty,
.set_mctrl = snp_set_mctrl,
.get_mctrl = snp_get_mctrl,

View File

@ -498,7 +498,7 @@ static int sprd_verify_port(struct uart_port *port,
return 0;
}
static struct uart_ops serial_sprd_ops = {
static const struct uart_ops serial_sprd_ops = {
.tx_empty = sprd_tx_empty,
.get_mctrl = sprd_get_mctrl,
.set_mctrl = sprd_set_mctrl,

View File

@ -18,6 +18,7 @@
#include <linux/serial.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/irq.h>
@ -30,15 +31,23 @@
#include <linux/of_platform.h>
#include <linux/serial_core.h>
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
#define DRIVER_NAME "st-asc"
#define ASC_SERIAL_NAME "ttyAS"
#define ASC_FIFO_SIZE 16
#define ASC_MAX_PORTS 8
/* Pinctrl states */
#define DEFAULT 0
#define NO_HW_FLOWCTRL 1
struct asc_port {
struct uart_port port;
struct gpio_desc *rts;
struct clk *clk;
struct pinctrl *pinctrl;
struct pinctrl_state *states[2];
unsigned int hw_flow_control:1;
unsigned int force_m1:1;
};
@ -287,9 +296,19 @@ static void asc_transmit_chars(struct uart_port *port)
static void asc_receive_chars(struct uart_port *port)
{
struct tty_port *tport = &port->state->port;
unsigned long status;
unsigned long status, mode;
unsigned long c = 0;
char flag;
bool ignore_pe = false;
/*
* Datasheet states: If the MODE field selects an 8-bit frame then
* this [parity error] bit is undefined. Software should ignore this
* bit when reading 8-bit frames.
*/
mode = asc_in(port, ASC_CTL) & ASC_CTL_MODE_MSK;
if (mode == ASC_CTL_MODE_8BIT || mode == ASC_CTL_MODE_8BIT_PAR)
ignore_pe = true;
if (port->irq_wake)
pm_wakeup_event(tport->tty->dev, 0);
@ -299,8 +318,8 @@ static void asc_receive_chars(struct uart_port *port)
flag = TTY_NORMAL;
port->icount.rx++;
if ((c & (ASC_RXBUF_FE | ASC_RXBUF_PE)) ||
status & ASC_STA_OE) {
if (status & ASC_STA_OE || c & ASC_RXBUF_FE ||
(c & ASC_RXBUF_PE && !ignore_pe)) {
if (c & ASC_RXBUF_FE) {
if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) {
@ -381,12 +400,27 @@ static unsigned int asc_tx_empty(struct uart_port *port)
static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
struct asc_port *ascport = to_asc_port(port);
/*
* This routine is used for seting signals of: DTR, DCD, CTS/RTS
* We use ASC's hardware for CTS/RTS, so don't need any for that.
* Some boards have DTR and DCD implemented using PIO pins,
* code to do this should be hooked in here.
* This routine is used for seting signals of: DTR, DCD, CTS and RTS.
* We use ASC's hardware for CTS/RTS when hardware flow-control is
* enabled, however if the RTS line is required for another purpose,
* commonly controlled using HUP from userspace, then we need to toggle
* it manually, using GPIO.
*
* Some boards also have DTR and DCD implemented using PIO pins, code to
* do this should be hooked in here.
*/
if (!ascport->rts)
return;
/* If HW flow-control is enabled, we can't fiddle with the RTS line */
if (asc_in(port, ASC_CTL) & ASC_CTL_CTSENABLE)
return;
gpiod_set_value(ascport->rts, mctrl & TIOCM_RTS);
}
static unsigned int asc_get_mctrl(struct uart_port *port)
@ -479,6 +513,8 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct asc_port *ascport = to_asc_port(port);
struct device_node *np = port->dev->of_node;
struct gpio_desc *gpiod;
unsigned int baud;
u32 ctrl_val;
tcflag_t cflag;
@ -522,9 +558,32 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
ctrl_val |= ASC_CTL_PARITYODD;
/* hardware flow control */
if ((cflag & CRTSCTS))
if ((cflag & CRTSCTS)) {
ctrl_val |= ASC_CTL_CTSENABLE;
/* If flow-control selected, stop handling RTS manually */
if (ascport->rts) {
devm_gpiod_put(port->dev, ascport->rts);
ascport->rts = NULL;
pinctrl_select_state(ascport->pinctrl,
ascport->states[DEFAULT]);
}
} else {
/* If flow-control disabled, it's safe to handle RTS manually */
if (!ascport->rts && ascport->states[NO_HW_FLOWCTRL]) {
pinctrl_select_state(ascport->pinctrl,
ascport->states[NO_HW_FLOWCTRL]);
gpiod = devm_get_gpiod_from_child(port->dev, "rts",
&np->fwnode);
if (!IS_ERR(gpiod)) {
gpiod_direction_output(gpiod, 0);
ascport->rts = gpiod;
}
}
}
if ((baud < 19200) && !ascport->force_m1) {
asc_out(port, ASC_BAUDRATE, (port->uartclk / (16 * baud)));
} else {
@ -667,6 +726,7 @@ static int asc_init_port(struct asc_port *ascport,
{
struct uart_port *port = &ascport->port;
struct resource *res;
int ret;
port->iotype = UPIO_MEM;
port->flags = UPF_BOOT_AUTOCONF;
@ -693,6 +753,27 @@ static int asc_init_port(struct asc_port *ascport,
WARN_ON(ascport->port.uartclk == 0);
clk_disable_unprepare(ascport->clk);
ascport->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(ascport->pinctrl)) {
ret = PTR_ERR(ascport->pinctrl);
dev_err(&pdev->dev, "Failed to get Pinctrl: %d\n", ret);
}
ascport->states[DEFAULT] =
pinctrl_lookup_state(ascport->pinctrl, "default");
if (IS_ERR(ascport->states[DEFAULT])) {
ret = PTR_ERR(ascport->states[DEFAULT]);
dev_err(&pdev->dev,
"Failed to look up Pinctrl state 'default': %d\n", ret);
return ret;
}
/* "no-hw-flowctrl" state is optional */
ascport->states[NO_HW_FLOWCTRL] =
pinctrl_lookup_state(ascport->pinctrl, "no-hw-flowctrl");
if (IS_ERR(ascport->states[NO_HW_FLOWCTRL]))
ascport->states[NO_HW_FLOWCTRL] = NULL;
return 0;
}
@ -713,9 +794,11 @@ static struct asc_port *asc_of_get_asc_port(struct platform_device *pdev)
return NULL;
asc_ports[id].hw_flow_control = of_property_read_bool(np,
"st,hw-flow-control");
"uart-has-rtscts");
asc_ports[id].force_m1 = of_property_read_bool(np, "st,force_m1");
asc_ports[id].port.line = id;
asc_ports[id].rts = NULL;
return &asc_ports[id];
}

View File

@ -370,7 +370,7 @@ static int sunhv_verify_port(struct uart_port *port, struct serial_struct *ser)
return -EINVAL;
}
static struct uart_ops sunhv_pops = {
static const struct uart_ops sunhv_pops = {
.tx_empty = sunhv_tx_empty,
.set_mctrl = sunhv_set_mctrl,
.get_mctrl = sunhv_get_mctrl,

View File

@ -1046,7 +1046,7 @@ static void sunzilog_put_poll_char(struct uart_port *port,
}
#endif /* CONFIG_CONSOLE_POLL */
static struct uart_ops sunzilog_pops = {
static const struct uart_ops sunzilog_pops = {
.tx_empty = sunzilog_tx_empty,
.set_mctrl = sunzilog_set_mctrl,
.get_mctrl = sunzilog_get_mctrl,

View File

@ -681,7 +681,7 @@ static int siu_verify_port(struct uart_port *port, struct serial_struct *serial)
return 0;
}
static struct uart_ops siu_uart_ops = {
static const struct uart_ops siu_uart_ops = {
.tx_empty = siu_tx_empty,
.set_mctrl = siu_set_mctrl,
.get_mctrl = siu_get_mctrl,

View File

@ -592,7 +592,7 @@ static void vt8500_put_poll_char(struct uart_port *port, unsigned char c)
}
#endif
static struct uart_ops vt8500_uart_pops = {
static const struct uart_ops vt8500_uart_pops = {
.tx_empty = vt8500_tx_empty,
.set_mctrl = vt8500_set_mctrl,
.get_mctrl = vt8500_get_mctrl,

Some files were not shown because too many files have changed in this diff Show More