TTY/Serial patches for 5.5-rc1

Here is the "big" tty and serial driver patches for 5.5-rc1.  It's a bit
 later in the merge window than normal as I wanted to make sure some
 last-minute patches applied to it were all sane.  They seem to be :)
 
 There's a lot of little stuff in here, for the tty core, and for lots of
 serial drivers:
 	- reverts of uartlite serial driver patches that were wrong
 	- msm-serial driver fixes
 	- serial core updates and fixes
 	- tty core fixes
 	- serial driver dma mapping api changes
 	- lots of other tiny fixes and updates for serial drivers
 
 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-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXebFIQ8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ylnmACgjfMcfQWa7uC9Q6m2DaQaRMaW6QoAnjg+TgBB
 eW9EhvyXL2VbrsuUl+iH
 =Am9O
 -----END PGP SIGNATURE-----

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

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

  It's a bit later in the merge window than normal as I wanted to make
  sure some last-minute patches applied to it were all sane. They seem
  to be :)

  There's a lot of little stuff in here, for the tty core, and for lots
  of serial drivers:

   - reverts of uartlite serial driver patches that were wrong

   - msm-serial driver fixes

   - serial core updates and fixes

   - tty core fixes

   - serial driver dma mapping api changes

   - lots of other tiny fixes and updates for serial drivers

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

* tag 'tty-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (58 commits)
  Revert "serial/8250: Add support for NI-Serial PXI/PXIe+485 devices"
  vcs: prevent write access to vcsu devices
  tty: vt: keyboard: reject invalid keycodes
  tty: don't crash in tty_init_dev when missing tty_port
  serial: stm32: fix clearing interrupt error flags
  tty: Fix Kconfig indentation, continued
  serial: serial_core: Perform NULL checks for break_ctl ops
  tty: remove unused argument from tty_open_by_driver()
  tty: Fix Kconfig indentation
  {tty: serial, nand: onenand}: samsung: rename to fix build warning
  serial: ifx6x60: add missed pm_runtime_disable
  serial: pl011: Fix DMA ->flush_buffer()
  Revert "serial-uartlite: Move the uart register"
  Revert "serial-uartlite: Add get serial id if not provided"
  Revert "serial-uartlite: Do not use static struct uart_driver out of probe()"
  Revert "serial-uartlite: Add runtime support"
  Revert "serial-uartlite: Change logic how console_port is setup"
  Revert "serial-uartlite: Use allocated structure instead of static ones"
  tty: serial: msm_serial: Use dma_request_chan() directly for channel request
  tty: serial: tegra: Use dma_request_chan() directly for channel request
  ...
This commit is contained in:
Linus Torvalds 2019-12-03 14:09:14 -08:00
commit 537bd0a159
49 changed files with 665 additions and 715 deletions

View File

@ -6,10 +6,19 @@ Description: Configures which IO port the host side of the UART
Users: OpenBMC. Proposed changes should be mailed to
openbmc@lists.ozlabs.org
What: /sys/bus/platform/drivers/aspeed-vuart*/sirq
What: /sys/bus/platform/drivers/aspeed-vuart/*/sirq
Date: April 2017
Contact: Jeremy Kerr <jk@ozlabs.org>
Description: Configures which interrupt number the host side of
the UART will appear on the host <-> BMC LPC bus.
Users: OpenBMC. Proposed changes should be mailed to
openbmc@lists.ozlabs.org
What: /sys/bus/platform/drivers/aspeed-vuart/*/sirq_polarity
Date: July 2019
Contact: Oskar Senft <osk@google.com>
Description: Configures the polarity of the serial interrupt to the
host via the BMC LPC bus.
Set to 0 for active-low or 1 for active-high.
Users: OpenBMC. Proposed changes should be mailed to
openbmc@lists.ozlabs.org

View File

@ -1097,7 +1097,7 @@
mapped with the correct attributes.
linflex,<addr>
Use early console provided by Freescale LinFlex UART
Use early console provided by Freescale LINFlexD UART
serial driver for NXP S32V234 SoCs. A valid base
address must be provided, and the serial port must
already be setup and configured.

View File

@ -56,6 +56,11 @@ Optional properties:
- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
line respectively. It will use specified GPIO instead of the peripheral
function pin for the UART feature. If unsure, don't specify this property.
- aspeed,sirq-polarity-sense: Only applicable to aspeed,ast2500-vuart.
phandle to aspeed,ast2500-scu compatible syscon alongside register offset
and bit number to identify how the SIRQ polarity should be configured.
One possible data source is the LPC/eSPI mode bit.
Example: aspeed,sirq-polarity-sense = <&syscon 0x70 25>
Note:
* fsl,ns16550:

View File

@ -21,8 +21,7 @@ Required properties:
Optional properties:
- dmas: A list of two dma specifiers, one for each entry in dma-names.
- dma-names: should contain "tx" and "rx".
- rs485-rts-delay, rs485-rts-active-low, rs485-rx-during-tx,
linux,rs485-enabled-at-boot-time: see rs485.txt
- rs485-rts-active-low, linux,rs485-enabled-at-boot-time: see rs485.txt
Note: Optional properties for DMA support. Write them both or both not.

View File

@ -54,8 +54,10 @@ Required properties:
- "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART.
- "renesas,scif-r8a7795" for R8A7795 (R-Car H3) SCIF compatible UART.
- "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART.
- "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART.
- "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART.
- "renesas,scif-r8a7796" for R8A77960 (R-Car M3-W) SCIF compatible UART.
- "renesas,hscif-r8a7796" for R8A77960 (R-Car M3-W) HSCIF compatible UART.
- "renesas,scif-r8a77961" for R8A77961 (R-Car M3-W+) SCIF compatible UART.
- "renesas,hscif-r8a77961" for R8A77961 (R-Car M3-W+) HSCIF compatible UART.
- "renesas,scif-r8a77965" for R8A77965 (R-Car M3-N) SCIF compatible UART.
- "renesas,hscif-r8a77965" for R8A77965 (R-Car M3-N) HSCIF compatible UART.
- "renesas,scif-r8a77970" for R8A77970 (R-Car V3M) SCIF compatible UART.

View File

@ -81,7 +81,6 @@ FF_MAGIC 0x4646 fc_info ``drivers/net/ip
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
PTY_MAGIC 0x5001 ``drivers/char/pty.c``
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
SERIAL_MAGIC 0x5301 async_struct ``include/linux/serial.h``
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h``
STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c``

View File

@ -87,7 +87,6 @@ FF_MAGIC 0x4646 fc_info ``drivers/net/ip
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
PTY_MAGIC 0x5001 ``drivers/char/pty.c``
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
SERIAL_MAGIC 0x5301 async_struct ``include/linux/serial.h``
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h``
STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c``

View File

@ -70,7 +70,6 @@ FF_MAGIC 0x4646 fc_info ``drivers/net/ip
ISICOM_MAGIC 0x4d54 isi_port ``include/linux/isicom.h``
PTY_MAGIC 0x5001 ``drivers/char/pty.c``
PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h``
SERIAL_MAGIC 0x5301 async_struct ``include/linux/serial.h``
SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h``
SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h``
STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c``

View File

@ -379,6 +379,7 @@ vuart: serial@1e787000 {
interrupts = <8>;
clocks = <&syscon ASPEED_CLK_APB>;
no-loopback-test;
aspeed,sirq-polarity-sense = <&syscon 0x70 25>;
status = "disabled";
};

View File

@ -9,6 +9,6 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o
# Board specific.
obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o
obj-$(CONFIG_MTD_ONENAND_SAMSUNG) += samsung.o
obj-$(CONFIG_MTD_ONENAND_SAMSUNG) += samsung_mtd.o
onenand-objs = onenand_base.o onenand_bbt.o

View File

@ -421,8 +421,6 @@ extern struct z8530_irqhandler z8530_sync, z8530_async, z8530_nop;
* Asynchronous Interfacing
*/
#define SERIAL_MAGIC 0x5301
/*
* The size of the serial xmit buffer is 1 page, or 4096 bytes
*/

View File

@ -82,20 +82,20 @@ config HW_CONSOLE
default y
config VT_HW_CONSOLE_BINDING
bool "Support for binding and unbinding console drivers"
depends on HW_CONSOLE
---help---
The virtual terminal is the device that interacts with the physical
terminal through console drivers. On these systems, at least one
console driver is loaded. In other configurations, additional console
drivers may be enabled, such as the framebuffer console. If more than
1 console driver is enabled, setting this to 'y' will allow you to
select the console driver that will serve as the backend for the
virtual terminals.
bool "Support for binding and unbinding console drivers"
depends on HW_CONSOLE
---help---
The virtual terminal is the device that interacts with the physical
terminal through console drivers. On these systems, at least one
console driver is loaded. In other configurations, additional console
drivers may be enabled, such as the framebuffer console. If more than
1 console driver is enabled, setting this to 'y' will allow you to
select the console driver that will serve as the backend for the
virtual terminals.
See <file:Documentation/driver-api/console.rst> for more
information. For framebuffer console users, please refer to
<file:Documentation/fb/fbcon.rst>.
See <file:Documentation/driver-api/console.rst> for more
information. For framebuffer console users, please refer to
<file:Documentation/fb/fbcon.rst>.
config UNIX98_PTYS
bool "Unix98 PTY support" if EXPERT
@ -173,15 +173,15 @@ config ROCKETPORT
depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
help
This driver supports Comtrol RocketPort and RocketModem PCI boards.
These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or
modems. For information about the RocketPort/RocketModem boards
and this driver read <file:Documentation/driver-api/serial/rocket.rst>.
These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or
modems. For information about the RocketPort/RocketModem boards
and this driver read <file:Documentation/driver-api/serial/rocket.rst>.
To compile this driver as a module, choose M here: the
module will be called rocket.
If you want to compile this driver into the kernel, say Y here. If
you don't have a Comtrol RocketPort/RocketModem card installed, say N.
you don't have a Comtrol RocketPort/RocketModem card installed, say N.
config CYCLADES
tristate "Cyclades async mux support"
@ -437,8 +437,8 @@ config MIPS_EJTAG_FDC_KGDB
depends on MIPS_EJTAG_FDC_TTY && KGDB
default y
help
This enables the use of KGDB over an FDC channel, allowing KGDB to be
used remotely or when a serial port isn't available.
This enables the use of KGDB over an FDC channel, allowing KGDB to be
used remotely or when a serial port isn't available.
config MIPS_EJTAG_FDC_KGDB_CHAN
int "KGDB FDC channel"

View File

@ -22,18 +22,8 @@
*
*/
/*
* Serial driver configuration section. Here are the various options:
*
* SERIAL_PARANOIA_CHECK
* Check the magic number for the async_structure where
* ever possible.
*/
#include <linux/delay.h>
#undef SERIAL_PARANOIA_CHECK
/* Set of debugging defines */
#undef SERIAL_DEBUG_INTR
@ -132,28 +122,6 @@ static struct serial_state rs_table[1];
#define serial_isroot() (capable(CAP_SYS_ADMIN))
static inline int serial_paranoia_check(struct serial_state *info,
char *name, const char *routine)
{
#ifdef SERIAL_PARANOIA_CHECK
static const char *badmagic =
"Warning: bad magic number for serial struct (%s) in %s\n";
static const char *badinfo =
"Warning: null async_struct for (%s) in %s\n";
if (!info) {
printk(badinfo, name, routine);
return 1;
}
if (info->magic != SERIAL_MAGIC) {
printk(badmagic, name, routine);
return 1;
}
#endif
return 0;
}
/* some serial hardware definitions */
#define SDR_OVRUN (1<<15)
#define SDR_RBF (1<<14)
@ -189,9 +157,6 @@ static void rs_stop(struct tty_struct *tty)
struct serial_state *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_stop"))
return;
local_irq_save(flags);
if (info->IER & UART_IER_THRI) {
info->IER &= ~UART_IER_THRI;
@ -209,9 +174,6 @@ static void rs_start(struct tty_struct *tty)
struct serial_state *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_start"))
return;
local_irq_save(flags);
if (info->xmit.head != info->xmit.tail
&& info->xmit.buf
@ -783,9 +745,6 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch)
info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_put_char"))
return 0;
if (!info->xmit.buf)
return 0;
@ -808,9 +767,6 @@ static void rs_flush_chars(struct tty_struct *tty)
struct serial_state *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
return;
if (info->xmit.head == info->xmit.tail
|| tty->stopped
|| tty->hw_stopped
@ -833,9 +789,6 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count
struct serial_state *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_write"))
return 0;
if (!info->xmit.buf)
return 0;
@ -878,8 +831,6 @@ static int rs_write_room(struct tty_struct *tty)
{
struct serial_state *info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_write_room"))
return 0;
return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
}
@ -887,8 +838,6 @@ static int rs_chars_in_buffer(struct tty_struct *tty)
{
struct serial_state *info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
return 0;
return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
}
@ -897,8 +846,6 @@ static void rs_flush_buffer(struct tty_struct *tty)
struct serial_state *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
return;
local_irq_save(flags);
info->xmit.head = info->xmit.tail = 0;
local_irq_restore(flags);
@ -914,9 +861,6 @@ static void rs_send_xchar(struct tty_struct *tty, char ch)
struct serial_state *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_send_xchar"))
return;
info->x_char = ch;
if (ch) {
/* Make sure transmit interrupts are on */
@ -952,9 +896,6 @@ static void rs_throttle(struct tty_struct * tty)
printk("throttle %s ....\n", tty_name(tty));
#endif
if (serial_paranoia_check(info, tty->name, "rs_throttle"))
return;
if (I_IXOFF(tty))
rs_send_xchar(tty, STOP_CHAR(tty));
@ -974,9 +915,6 @@ static void rs_unthrottle(struct tty_struct * tty)
printk("unthrottle %s ....\n", tty_name(tty));
#endif
if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
return;
if (I_IXOFF(tty)) {
if (info->x_char)
info->x_char = 0;
@ -1109,8 +1047,6 @@ static int rs_tiocmget(struct tty_struct *tty)
unsigned char control, status;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
if (tty_io_error(tty))
return -EIO;
@ -1131,8 +1067,6 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
struct serial_state *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
if (tty_io_error(tty))
return -EIO;
@ -1155,12 +1089,8 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
*/
static int rs_break(struct tty_struct *tty, int break_state)
{
struct serial_state *info = tty->driver_data;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "rs_break"))
return -EINVAL;
local_irq_save(flags);
if (break_state == -1)
custom.adkcon = AC_SETCLR | AC_UARTBRK;
@ -1212,9 +1142,6 @@ static int rs_ioctl(struct tty_struct *tty,
DEFINE_WAIT(wait);
int ret;
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
if ((cmd != TIOCSERCONFIG) &&
(cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
if (tty_io_error(tty))
@ -1333,9 +1260,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
struct serial_state *state = tty->driver_data;
struct tty_port *port = &state->tport;
if (serial_paranoia_check(state, tty->name, "rs_close"))
return;
if (tty_port_close_start(port, tty, filp) == 0)
return;
@ -1379,9 +1303,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
unsigned long orig_jiffies, char_time;
int lsr;
if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
return;
if (info->xmit_fifo_size == 0)
return; /* Just in case.... */
@ -1440,9 +1361,6 @@ static void rs_hangup(struct tty_struct *tty)
{
struct serial_state *info = tty->driver_data;
if (serial_paranoia_check(info, tty->name, "rs_hangup"))
return;
rs_flush_buffer(tty);
shutdown(tty, info);
info->tport.count = 0;
@ -1467,8 +1385,6 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
port->tty = tty;
tty->driver_data = info;
tty->port = port;
if (serial_paranoia_check(info, tty->name, "rs_open"))
return -ENODEV;
port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;

View File

@ -70,22 +70,22 @@ config HVC_XEN_FRONTEND
Xen driver for secondary virtual consoles
config HVC_UDBG
bool "udbg based fake hypervisor console"
depends on PPC
select HVC_DRIVER
help
This is meant to be used during HW bring up or debugging when
no other console mechanism exist but udbg, to get you a quick
console for userspace. Do NOT enable in production kernels.
bool "udbg based fake hypervisor console"
depends on PPC
select HVC_DRIVER
help
This is meant to be used during HW bring up or debugging when
no other console mechanism exist but udbg, to get you a quick
console for userspace. Do NOT enable in production kernels.
config HVC_DCC
bool "ARM JTAG DCC console"
depends on ARM || ARM64
select HVC_DRIVER
help
This console uses the JTAG DCC on ARM to create a console under the HVC
driver. This console is used through a JTAG only on ARM. If you don't have
a JTAG then you probably don't want this option.
bool "ARM JTAG DCC console"
depends on ARM || ARM64
select HVC_DRIVER
help
This console uses the JTAG DCC on ARM to create a console under the HVC
driver. This console is used through a JTAG only on ARM. If you don't have
a JTAG then you probably don't want this option.
config HVC_RISCV_SBI
bool "RISC-V SBI console support"

View File

@ -1,7 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved. */
#include <linux/console.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <asm/dcc.h>
#include <asm/processor.h>
@ -12,6 +15,31 @@
#define DCC_STATUS_RX (1 << 30)
#define DCC_STATUS_TX (1 << 29)
static void dcc_uart_console_putchar(struct uart_port *port, int ch)
{
while (__dcc_getstatus() & DCC_STATUS_TX)
cpu_relax();
__dcc_putchar(ch);
}
static void dcc_early_write(struct console *con, const char *s, unsigned n)
{
struct earlycon_device *dev = con->data;
uart_console_write(&dev->port, s, n, dcc_uart_console_putchar);
}
static int __init dcc_early_console_setup(struct earlycon_device *device,
const char *opt)
{
device->con->write = dcc_early_write;
return 0;
}
EARLYCON_DECLARE(dcc, dcc_early_console_setup);
static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
{
int i;

View File

@ -1222,22 +1222,28 @@ static int set_config(struct tty_struct *tty, struct r_port *info,
*/
static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
{
struct rocket_ports tmp;
int board;
struct rocket_ports *tmp;
int board, ret = 0;
memset(&tmp, 0, sizeof (tmp));
tmp.tty_major = rocket_driver->major;
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
tmp->tty_major = rocket_driver->major;
for (board = 0; board < 4; board++) {
tmp.rocketModel[board].model = rocketModel[board].model;
strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString);
tmp.rocketModel[board].numPorts = rocketModel[board].numPorts;
tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber;
tmp->rocketModel[board].model = rocketModel[board].model;
strcpy(tmp->rocketModel[board].modelString,
rocketModel[board].modelString);
tmp->rocketModel[board].numPorts = rocketModel[board].numPorts;
tmp->rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
tmp->rocketModel[board].startingPortNumber =
rocketModel[board].startingPortNumber;
}
if (copy_to_user(retports, &tmp, sizeof (*retports)))
return -EFAULT;
return 0;
if (copy_to_user(retports, tmp, sizeof(*retports)))
ret = -EFAULT;
kfree(tmp);
return ret;
}
static int reset_rm2(struct r_port *info, void __user *arg)

View File

@ -552,15 +552,96 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
}
#ifdef CONFIG_ACPI
static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
struct acpi_device *adev)
{
struct serdev_device *serdev = NULL;
int err;
if (acpi_bus_get_status(adev) || !adev->status.present ||
acpi_device_enumerated(adev))
return AE_OK;
#define SERDEV_ACPI_MAX_SCAN_DEPTH 32
struct acpi_serdev_lookup {
acpi_handle device_handle;
acpi_handle controller_handle;
int n;
int index;
};
static int acpi_serdev_parse_resource(struct acpi_resource *ares, void *data)
{
struct acpi_serdev_lookup *lookup = data;
struct acpi_resource_uart_serialbus *sb;
acpi_status status;
if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
return 1;
if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART)
return 1;
if (lookup->index != -1 && lookup->n++ != lookup->index)
return 1;
sb = &ares->data.uart_serial_bus;
status = acpi_get_handle(lookup->device_handle,
sb->resource_source.string_ptr,
&lookup->controller_handle);
if (ACPI_FAILURE(status))
return 1;
/*
* NOTE: Ideally, we would also want to retreive other properties here,
* once setting them before opening the device is supported by serdev.
*/
return 1;
}
static int acpi_serdev_do_lookup(struct acpi_device *adev,
struct acpi_serdev_lookup *lookup)
{
struct list_head resource_list;
int ret;
lookup->device_handle = acpi_device_handle(adev);
lookup->controller_handle = NULL;
lookup->n = 0;
INIT_LIST_HEAD(&resource_list);
ret = acpi_dev_get_resources(adev, &resource_list,
acpi_serdev_parse_resource, lookup);
acpi_dev_free_resource_list(&resource_list);
if (ret < 0)
return -EINVAL;
return 0;
}
static int acpi_serdev_check_resources(struct serdev_controller *ctrl,
struct acpi_device *adev)
{
struct acpi_serdev_lookup lookup;
int ret;
if (acpi_bus_get_status(adev) || !adev->status.present)
return -EINVAL;
/* Look for UARTSerialBusV2 resource */
lookup.index = -1; // we only care for the last device
ret = acpi_serdev_do_lookup(adev, &lookup);
if (ret)
return ret;
/* Make sure controller and ResourceSource handle match */
if (ACPI_HANDLE(ctrl->dev.parent) != lookup.controller_handle)
return -ENODEV;
return 0;
}
static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
struct acpi_device *adev)
{
struct serdev_device *serdev;
int err;
serdev = serdev_device_alloc(ctrl);
if (!serdev) {
@ -583,7 +664,7 @@ static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
}
static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level,
void *data, void **return_value)
void *data, void **return_value)
{
struct serdev_controller *ctrl = data;
struct acpi_device *adev;
@ -591,22 +672,28 @@ static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level,
if (acpi_bus_get_device(handle, &adev))
return AE_OK;
if (acpi_device_enumerated(adev))
return AE_OK;
if (acpi_serdev_check_resources(ctrl, adev))
return AE_OK;
return acpi_serdev_register_device(ctrl, adev);
}
static int acpi_serdev_register_devices(struct serdev_controller *ctrl)
{
acpi_status status;
acpi_handle handle;
handle = ACPI_HANDLE(ctrl->dev.parent);
if (!handle)
if (!has_acpi_companion(ctrl->dev.parent))
return -ENODEV;
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
SERDEV_ACPI_MAX_SCAN_DEPTH,
acpi_serdev_add_device, NULL, ctrl, NULL);
if (ACPI_FAILURE(status))
dev_dbg(&ctrl->dev, "failed to enumerate serdev slaves\n");
dev_warn(&ctrl->dev, "failed to enumerate serdev slaves\n");
if (!ctrl->serdev)
return -ENODEV;

View File

@ -14,6 +14,8 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/clk.h>
@ -22,6 +24,7 @@
#define ASPEED_VUART_GCRA 0x20
#define ASPEED_VUART_GCRA_VUART_EN BIT(0)
#define ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY BIT(1)
#define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD BIT(5)
#define ASPEED_VUART_GCRB 0x24
#define ASPEED_VUART_GCRB_HOST_SIRQ_MASK GENMASK(7, 4)
@ -131,8 +134,53 @@ static ssize_t sirq_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR_RW(sirq);
static ssize_t sirq_polarity_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct aspeed_vuart *vuart = dev_get_drvdata(dev);
u8 reg;
reg = readb(vuart->regs + ASPEED_VUART_GCRA);
reg &= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg ? 1 : 0);
}
static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart,
bool polarity)
{
u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA);
if (polarity)
reg |= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
else
reg &= ~ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
writeb(reg, vuart->regs + ASPEED_VUART_GCRA);
}
static ssize_t sirq_polarity_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct aspeed_vuart *vuart = dev_get_drvdata(dev);
unsigned long val;
int err;
err = kstrtoul(buf, 0, &val);
if (err)
return err;
aspeed_vuart_set_sirq_polarity(vuart, val != 0);
return count;
}
static DEVICE_ATTR_RW(sirq_polarity);
static struct attribute *aspeed_vuart_attrs[] = {
&dev_attr_sirq.attr,
&dev_attr_sirq_polarity.attr,
&dev_attr_lpc_address.attr,
NULL,
};
@ -302,8 +350,30 @@ static int aspeed_vuart_handle_irq(struct uart_port *port)
return 1;
}
static void aspeed_vuart_auto_configure_sirq_polarity(
struct aspeed_vuart *vuart, struct device_node *syscon_np,
u32 reg_offset, u32 reg_mask)
{
struct regmap *regmap;
u32 value;
regmap = syscon_node_to_regmap(syscon_np);
if (IS_ERR(regmap)) {
dev_warn(vuart->dev,
"could not get regmap for aspeed,sirq-polarity-sense\n");
return;
}
if (regmap_read(regmap, reg_offset, &value)) {
dev_warn(vuart->dev, "could not read hw strap table\n");
return;
}
aspeed_vuart_set_sirq_polarity(vuart, (value & reg_mask) == 0);
}
static int aspeed_vuart_probe(struct platform_device *pdev)
{
struct of_phandle_args sirq_polarity_sense_args;
struct uart_8250_port port;
struct aspeed_vuart *vuart;
struct device_node *np;
@ -402,6 +472,20 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
vuart->line = rc;
rc = of_parse_phandle_with_fixed_args(
np, "aspeed,sirq-polarity-sense", 2, 0,
&sirq_polarity_sense_args);
if (rc < 0) {
dev_dbg(&pdev->dev,
"aspeed,sirq-polarity-sense property not found\n");
} else {
aspeed_vuart_auto_configure_sirq_polarity(
vuart, sirq_polarity_sense_args.np,
sirq_polarity_sense_args.args[0],
BIT(sirq_polarity_sense_args.args[1]));
of_node_put(sirq_polarity_sense_args.np);
}
aspeed_vuart_set_enabled(vuart, true);
aspeed_vuart_set_host_tx_discard(vuart, true);
platform_set_drvdata(pdev, vuart);

View File

@ -280,9 +280,6 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
long rate;
int ret;
if (IS_ERR(d->clk))
goto out;
clk_disable_unprepare(d->clk);
rate = clk_round_rate(d->clk, baud * 16);
if (rate < 0)
@ -293,8 +290,10 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
ret = clk_set_rate(d->clk, rate);
clk_prepare_enable(d->clk);
if (!ret)
p->uartclk = rate;
if (ret)
goto out;
p->uartclk = rate;
out:
p->status &= ~UPSTAT_AUTOCTS;
@ -386,10 +385,10 @@ static int dw8250_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {}, *up = &uart;
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int irq = platform_get_irq(pdev, 0);
struct uart_port *p = &up->port;
struct device *dev = &pdev->dev;
struct dw8250_data *data;
int irq;
int err;
u32 val;
@ -398,11 +397,9 @@ static int dw8250_probe(struct platform_device *pdev)
return -EINVAL;
}
if (irq < 0) {
if (irq != -EPROBE_DEFER)
dev_err(dev, "cannot get irq\n");
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
}
spin_lock_init(&p->lock);
p->mapbase = regs->start;
@ -472,19 +469,18 @@ static int dw8250_probe(struct platform_device *pdev)
device_property_read_u32(dev, "clock-frequency", &p->uartclk);
/* If there is separate baudclk, get the rate from it. */
data->clk = devm_clk_get(dev, "baudclk");
if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER)
data->clk = devm_clk_get(dev, NULL);
if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (!IS_ERR_OR_NULL(data->clk)) {
err = clk_prepare_enable(data->clk);
if (err)
dev_warn(dev, "could not enable optional baudclk: %d\n",
err);
else
p->uartclk = clk_get_rate(data->clk);
}
data->clk = devm_clk_get_optional(dev, "baudclk");
if (data->clk == NULL)
data->clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
err = clk_prepare_enable(data->clk);
if (err)
dev_warn(dev, "could not enable optional baudclk: %d\n", err);
if (data->clk)
p->uartclk = clk_get_rate(data->clk);
/* If no clock rate is defined, fail. */
if (!p->uartclk) {
@ -493,17 +489,16 @@ static int dw8250_probe(struct platform_device *pdev)
goto err_clk;
}
data->pclk = devm_clk_get(dev, "apb_pclk");
if (IS_ERR(data->pclk) && PTR_ERR(data->pclk) == -EPROBE_DEFER) {
err = -EPROBE_DEFER;
data->pclk = devm_clk_get_optional(dev, "apb_pclk");
if (IS_ERR(data->pclk)) {
err = PTR_ERR(data->pclk);
goto err_clk;
}
if (!IS_ERR(data->pclk)) {
err = clk_prepare_enable(data->pclk);
if (err) {
dev_err(dev, "could not enable apb_pclk\n");
goto err_clk;
}
err = clk_prepare_enable(data->pclk);
if (err) {
dev_err(dev, "could not enable apb_pclk\n");
goto err_clk;
}
data->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
@ -546,12 +541,10 @@ static int dw8250_probe(struct platform_device *pdev)
reset_control_assert(data->rst);
err_pclk:
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);
clk_disable_unprepare(data->pclk);
err_clk:
if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk);
clk_disable_unprepare(data->clk);
return err;
}
@ -567,11 +560,9 @@ static int dw8250_remove(struct platform_device *pdev)
reset_control_assert(data->rst);
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);
clk_disable_unprepare(data->pclk);
if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk);
clk_disable_unprepare(data->clk);
pm_runtime_disable(dev);
pm_runtime_put_noidle(dev);
@ -604,11 +595,9 @@ static int dw8250_runtime_suspend(struct device *dev)
{
struct dw8250_data *data = dev_get_drvdata(dev);
if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk);
clk_disable_unprepare(data->clk);
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);
clk_disable_unprepare(data->pclk);
return 0;
}
@ -617,11 +606,9 @@ static int dw8250_runtime_resume(struct device *dev)
{
struct dw8250_data *data = dev_get_drvdata(dev);
if (!IS_ERR(data->pclk))
clk_prepare_enable(data->pclk);
clk_prepare_enable(data->pclk);
if (!IS_ERR(data->clk))
clk_prepare_enable(data->clk);
clk_prepare_enable(data->clk);
return 0;
}

View File

@ -166,6 +166,23 @@ static void xr17v35x_set_divisor(struct uart_port *p, unsigned int baud,
serial_port_out(p, 0x2, quot_frac);
}
static int xr17v35x_startup(struct uart_port *port)
{
/*
* First enable access to IER [7:5], ISR [5:4], FCR [5:4],
* MCR [7:5] and MSR [7:0]
*/
serial_port_out(port, UART_XR_EFR, UART_EFR_ECB);
/*
* Make sure all interrups are masked until initialization is
* complete and the FIFOs are cleared
*/
serial_port_out(port, UART_IER, 0);
return serial8250_do_startup(port);
}
static void exar_shutdown(struct uart_port *port)
{
unsigned char lsr;
@ -212,6 +229,8 @@ static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
port->port.get_divisor = xr17v35x_get_divisor;
port->port.set_divisor = xr17v35x_set_divisor;
port->port.startup = xr17v35x_startup;
} else {
port->port.type = PORT_XR17D15X;
}

View File

@ -221,17 +221,6 @@ static void qrk_serial_exit_dma(struct lpss8250 *lpss) {}
static int qrk_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
{
struct pci_dev *pdev = to_pci_dev(port->dev);
int ret;
pci_set_master(pdev);
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
port->irq = pci_irq_vector(pdev, 0);
qrk_serial_setup_dma(lpss, port);
return 0;
}
@ -293,16 +282,22 @@ static int lpss8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret)
return ret;
pci_set_master(pdev);
lpss = devm_kzalloc(&pdev->dev, sizeof(*lpss), GFP_KERNEL);
if (!lpss)
return -ENOMEM;
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
lpss->board = (struct lpss8250_board *)id->driver_data;
memset(&uart, 0, sizeof(struct uart_8250_port));
uart.port.dev = &pdev->dev;
uart.port.irq = pdev->irq;
uart.port.irq = pci_irq_vector(pdev, 0);
uart.port.private_data = &lpss->data;
uart.port.type = PORT_16550A;
uart.port.iotype = UPIO_MEM;
@ -337,6 +332,7 @@ static int lpss8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_exit:
if (lpss->board->exit)
lpss->board->exit(lpss);
pci_free_irq_vectors(pdev);
return ret;
}
@ -348,6 +344,7 @@ static void lpss8250_remove(struct pci_dev *pdev)
if (lpss->board->exit)
lpss->board->exit(lpss);
pci_free_irq_vectors(pdev);
}
static const struct lpss8250_board byt_board = {

View File

@ -544,7 +544,7 @@ static int mtk8250_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
data->rx_wakeup_irq = platform_get_irq(pdev, 1);
data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1);
return 0;
}

View File

@ -48,6 +48,36 @@ static inline void tegra_serial_handle_break(struct uart_port *port)
}
#endif
static int of_8250_rs485_config(struct uart_port *port,
struct serial_rs485 *rs485)
{
struct uart_8250_port *up = up_to_u8250p(port);
/* Clamp the delays to [0, 100ms] */
rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U);
rs485->delay_rts_after_send = min(rs485->delay_rts_after_send, 100U);
port->rs485 = *rs485;
/*
* Both serial8250_em485_init and serial8250_em485_destroy
* are idempotent
*/
if (rs485->flags & SER_RS485_ENABLED) {
int ret = serial8250_em485_init(up);
if (ret) {
rs485->flags &= ~SER_RS485_ENABLED;
port->rs485.flags &= ~SER_RS485_ENABLED;
}
return ret;
}
serial8250_em485_destroy(up);
return 0;
}
/*
* Fill a struct uart_port for a given device node
*/
@ -178,6 +208,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
port->flags |= UPF_SKIP_TEST;
port->dev = &ofdev->dev;
port->rs485_config = of_8250_rs485_config;
switch (type) {
case PORT_TEGRA:

View File

@ -743,16 +743,8 @@ static int pci_ni8430_init(struct pci_dev *dev)
}
/* UART Port Control Register */
#define NI16550_PCR_OFFSET 0x0f
#define NI16550_PCR_RS422 0x00
#define NI16550_PCR_ECHO_RS485 0x01
#define NI16550_PCR_DTR_RS485 0x02
#define NI16550_PCR_AUTO_RS485 0x03
#define NI16550_PCR_WIRE_MODE_MASK 0x03
#define NI16550_PCR_TXVR_ENABLE_BIT BIT(3)
#define NI16550_PCR_RS485_TERMINATION_BIT BIT(6)
#define NI16550_ACR_DTR_AUTO_DTR (0x2 << 3)
#define NI16550_ACR_DTR_MANUAL_DTR (0x0 << 3)
#define NI8430_PORTCON 0x0f
#define NI8430_PORTCON_TXVR_ENABLE (1 << 3)
static int
pci_ni8430_setup(struct serial_private *priv,
@ -774,117 +766,14 @@ pci_ni8430_setup(struct serial_private *priv,
return -ENOMEM;
/* enable the transceiver */
writeb(readb(p + offset + NI16550_PCR_OFFSET) | NI16550_PCR_TXVR_ENABLE_BIT,
p + offset + NI16550_PCR_OFFSET);
writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE,
p + offset + NI8430_PORTCON);
iounmap(p);
return setup_port(priv, port, bar, offset, board->reg_shift);
}
static int pci_ni8431_config_rs485(struct uart_port *port,
struct serial_rs485 *rs485)
{
u8 pcr, acr;
struct uart_8250_port *up;
up = container_of(port, struct uart_8250_port, port);
acr = up->acr;
pcr = port->serial_in(port, NI16550_PCR_OFFSET);
pcr &= ~NI16550_PCR_WIRE_MODE_MASK;
if (rs485->flags & SER_RS485_ENABLED) {
/* RS-485 */
if ((rs485->flags & SER_RS485_RX_DURING_TX) &&
(rs485->flags & SER_RS485_RTS_ON_SEND)) {
dev_dbg(port->dev, "Invalid 2-wire mode\n");
return -EINVAL;
}
if (rs485->flags & SER_RS485_RX_DURING_TX) {
/* Echo */
dev_vdbg(port->dev, "2-wire DTR with echo\n");
pcr |= NI16550_PCR_ECHO_RS485;
acr |= NI16550_ACR_DTR_MANUAL_DTR;
} else {
/* Auto or DTR */
if (rs485->flags & SER_RS485_RTS_ON_SEND) {
/* Auto */
dev_vdbg(port->dev, "2-wire Auto\n");
pcr |= NI16550_PCR_AUTO_RS485;
acr |= NI16550_ACR_DTR_AUTO_DTR;
} else {
/* DTR-controlled */
/* No Echo */
dev_vdbg(port->dev, "2-wire DTR no echo\n");
pcr |= NI16550_PCR_DTR_RS485;
acr |= NI16550_ACR_DTR_MANUAL_DTR;
}
}
} else {
/* RS-422 */
dev_vdbg(port->dev, "4-wire\n");
pcr |= NI16550_PCR_RS422;
acr |= NI16550_ACR_DTR_MANUAL_DTR;
}
dev_dbg(port->dev, "write pcr: 0x%08x\n", pcr);
port->serial_out(port, NI16550_PCR_OFFSET, pcr);
up->acr = acr;
port->serial_out(port, UART_SCR, UART_ACR);
port->serial_out(port, UART_ICR, up->acr);
/* Update the cache. */
port->rs485 = *rs485;
return 0;
}
static int pci_ni8431_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *uart, int idx)
{
u8 pcr, acr;
struct pci_dev *dev = priv->dev;
void __iomem *addr;
unsigned int bar, offset = board->first_offset;
if (idx >= board->num_ports)
return 1;
bar = FL_GET_BASE(board->flags);
offset += idx * board->uart_offset;
addr = pci_ioremap_bar(dev, bar);
if (!addr)
return -ENOMEM;
/* enable the transceiver */
writeb(readb(addr + NI16550_PCR_OFFSET) | NI16550_PCR_TXVR_ENABLE_BIT,
addr + NI16550_PCR_OFFSET);
pcr = readb(addr + NI16550_PCR_OFFSET);
pcr &= ~NI16550_PCR_WIRE_MODE_MASK;
/* set wire mode to default RS-422 */
pcr |= NI16550_PCR_RS422;
acr = NI16550_ACR_DTR_MANUAL_DTR;
/* write port configuration to register */
writeb(pcr, addr + NI16550_PCR_OFFSET);
/* access and write to UART acr register */
writeb(UART_ACR, addr + UART_SCR);
writeb(acr, addr + UART_ICR);
uart->port.rs485_config = &pci_ni8431_config_rs485;
iounmap(addr);
return setup_port(priv, uart, bar, offset, board->reg_shift);
}
static int pci_netmos_9900_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
@ -2021,15 +1910,6 @@ pci_moxa_setup(struct serial_private *priv,
#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM 0x10E9
#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM 0x11D8
#define PCIE_DEVICE_ID_NI_PXIE8430_2328 0x74C2
#define PCIE_DEVICE_ID_NI_PXIE8430_23216 0x74C1
#define PCI_DEVICE_ID_NI_PXI8431_4852 0x7081
#define PCI_DEVICE_ID_NI_PXI8431_4854 0x70DE
#define PCI_DEVICE_ID_NI_PXI8431_4858 0x70E3
#define PCI_DEVICE_ID_NI_PXI8433_4852 0x70E9
#define PCI_DEVICE_ID_NI_PXI8433_4854 0x70ED
#define PCIE_DEVICE_ID_NI_PXIE8431_4858 0x74C4
#define PCIE_DEVICE_ID_NI_PXIE8431_48516 0x74C3
#define PCI_DEVICE_ID_MOXA_CP102E 0x1024
#define PCI_DEVICE_ID_MOXA_CP102EL 0x1025
@ -2267,87 +2147,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.setup = pci_ni8430_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCIE_DEVICE_ID_NI_PXIE8430_2328,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8430_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCIE_DEVICE_ID_NI_PXIE8430_23216,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8430_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8431_4852,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8431_4854,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8431_4858,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8433_4852,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCI_DEVICE_ID_NI_PXI8433_4854,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCIE_DEVICE_ID_NI_PXIE8431_4858,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
{
.vendor = PCI_VENDOR_ID_NI,
.device = PCIE_DEVICE_ID_NI_PXIE8431_48516,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.init = pci_ni8430_init,
.setup = pci_ni8431_setup,
.exit = pci_ni8430_exit,
},
/* Quatech */
{
.vendor = PCI_VENDOR_ID_QUATECH,
@ -3104,13 +2903,6 @@ enum pci_board_num_t {
pbn_ni8430_4,
pbn_ni8430_8,
pbn_ni8430_16,
pbn_ni8430_pxie_8,
pbn_ni8430_pxie_16,
pbn_ni8431_2,
pbn_ni8431_4,
pbn_ni8431_8,
pbn_ni8431_pxie_8,
pbn_ni8431_pxie_16,
pbn_ADDIDATA_PCIe_1_3906250,
pbn_ADDIDATA_PCIe_2_3906250,
pbn_ADDIDATA_PCIe_4_3906250,
@ -3763,55 +3555,6 @@ static struct pciserial_board pci_boards[] = {
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8430_pxie_16] = {
.flags = FL_BASE0,
.num_ports = 16,
.base_baud = 3125000,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8430_pxie_8] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 3125000,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_8] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 3686400,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_4] = {
.flags = FL_BASE0,
.num_ports = 4,
.base_baud = 3686400,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_2] = {
.flags = FL_BASE0,
.num_ports = 2,
.base_baud = 3686400,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_pxie_16] = {
.flags = FL_BASE0,
.num_ports = 16,
.base_baud = 3125000,
.uart_offset = 0x10,
.first_offset = 0x800,
},
[pbn_ni8431_pxie_8] = {
.flags = FL_BASE0,
.num_ports = 8,
.base_baud = 3125000,
.uart_offset = 0x10,
.first_offset = 0x800,
},
/*
* ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com>
*/
@ -5565,33 +5308,6 @@ static const struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8430_4 },
{ PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8430_2328,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8430_pxie_8 },
{ PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8430_23216,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8430_pxie_16 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4852,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_2 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4854,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_4 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8431_4858,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_8 },
{ PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8431_4858,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_pxie_8 },
{ PCI_VENDOR_ID_NI, PCIE_DEVICE_ID_NI_PXIE8431_48516,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_pxie_16 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8433_4852,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_2 },
{ PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8433_4854,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_ni8431_4 },
/*
* MOXA

View File

@ -2114,20 +2114,6 @@ int serial8250_do_startup(struct uart_port *port)
enable_rsa(up);
#endif
if (port->type == PORT_XR17V35X) {
/*
* First enable access to IER [7:5], ISR [5:4], FCR [5:4],
* MCR [7:5] and MSR [7:0]
*/
serial_port_out(port, UART_XR_EFR, UART_EFR_ECB);
/*
* Make sure all interrups are masked until initialization is
* complete and the FIFOs are cleared
*/
serial_port_out(port, UART_IER, 0);
}
/*
* Clear the FIFO buffers and disable them.
* (they will be reenabled in set_termios())

View File

@ -243,6 +243,7 @@ config SERIAL_8250_ASPEED_VUART
tristate "Aspeed Virtual UART"
depends on SERIAL_8250
depends on OF
depends on REGMAP && MFD_SYSCON
help
If you want to use the virtual UART (VUART) device on Aspeed
BMC platforms, enable this option. This enables the 16550A-
@ -334,7 +335,7 @@ config SERIAL_8250_BCM2835AUX
Features and limitations of the UART are
Registers are similar to 16650 registers,
set bits in the control registers that are unsupported
set bits in the control registers that are unsupported
are ignored and read back as 0
7/8 bit operation with 1 start and 1 stop bit
8 symbols deep fifo for rx and tx

View File

@ -287,26 +287,26 @@ config SERIAL_SAMSUNG_CONSOLE
boot time.)
config SERIAL_SIRFSOC
tristate "SiRF SoC Platform Serial port support"
depends on ARCH_SIRF
select SERIAL_CORE
help
Support for the on-chip UART on the CSR SiRFprimaII series,
providing /dev/ttySiRF0, 1 and 2 (note, some machines may not
provide all of these ports, depending on how the serial port
pins are configured).
tristate "SiRF SoC Platform Serial port support"
depends on ARCH_SIRF
select SERIAL_CORE
help
Support for the on-chip UART on the CSR SiRFprimaII series,
providing /dev/ttySiRF0, 1 and 2 (note, some machines may not
provide all of these ports, depending on how the serial port
pins are configured).
config SERIAL_SIRFSOC_CONSOLE
bool "Support for console on SiRF SoC serial port"
depends on SERIAL_SIRFSOC=y
select SERIAL_CORE_CONSOLE
help
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttySiRFx". (Try "man bootparam" or see the documentation of
your boot loader about how to pass options to the kernel at
boot time.)
bool "Support for console on SiRF SoC serial port"
depends on SERIAL_SIRFSOC=y
select SERIAL_CORE_CONSOLE
help
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttySiRFx". (Try "man bootparam" or see the documentation of
your boot loader about how to pass options to the kernel at
boot time.)
config SERIAL_TEGRA
tristate "NVIDIA Tegra20/30 SoC serial controller"
@ -1078,41 +1078,41 @@ config SERIAL_SCCNXP_CONSOLE
Support for console on SCCNXP serial ports.
config SERIAL_SC16IS7XX_CORE
tristate
tristate
config SERIAL_SC16IS7XX
tristate "SC16IS7xx serial support"
select SERIAL_CORE
depends on (SPI_MASTER && !I2C) || I2C
help
This selects support for SC16IS7xx serial ports.
Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752,
SC16IS760 and SC16IS762. Select supported buses using options below.
tristate "SC16IS7xx serial support"
select SERIAL_CORE
depends on (SPI_MASTER && !I2C) || I2C
help
This selects support for SC16IS7xx serial ports.
Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752,
SC16IS760 and SC16IS762. Select supported buses using options below.
config SERIAL_SC16IS7XX_I2C
bool "SC16IS7xx for I2C interface"
depends on SERIAL_SC16IS7XX
depends on I2C
select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX
select REGMAP_I2C if I2C
default y
help
Enable SC16IS7xx driver on I2C bus,
If required say y, and say n to i2c if not required,
Enabled by default to support oldconfig.
You must select at least one bus for the driver to be built.
bool "SC16IS7xx for I2C interface"
depends on SERIAL_SC16IS7XX
depends on I2C
select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX
select REGMAP_I2C if I2C
default y
help
Enable SC16IS7xx driver on I2C bus,
If required say y, and say n to i2c if not required,
Enabled by default to support oldconfig.
You must select at least one bus for the driver to be built.
config SERIAL_SC16IS7XX_SPI
bool "SC16IS7xx for spi interface"
depends on SERIAL_SC16IS7XX
depends on SPI_MASTER
select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX
select REGMAP_SPI if SPI_MASTER
help
Enable SC16IS7xx driver on SPI bus,
If required say y, and say n to spi if not required,
This is additional support to exsisting driver.
You must select at least one bus for the driver to be built.
bool "SC16IS7xx for spi interface"
depends on SERIAL_SC16IS7XX
depends on SPI_MASTER
select SERIAL_SC16IS7XX_CORE if SERIAL_SC16IS7XX
select REGMAP_SPI if SPI_MASTER
help
Enable SC16IS7xx driver on SPI bus,
If required say y, and say n to spi if not required,
This is additional support to exsisting driver.
You must select at least one bus for the driver to be built.
config SERIAL_TIMBERDALE
tristate "Support for timberdale UART"
@ -1212,7 +1212,7 @@ config SERIAL_ALTERA_UART_CONSOLE
Enable a Altera UART port to be the system console.
config SERIAL_IFX6X60
tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)"
tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)"
depends on GPIOLIB || COMPILE_TEST
depends on SPI && HAS_DMA
help
@ -1392,19 +1392,19 @@ config SERIAL_FSL_LPUART_CONSOLE
you can make it the console by answering Y to this option.
config SERIAL_FSL_LINFLEXUART
tristate "Freescale linflexuart serial port support"
tristate "Freescale LINFlexD UART serial port support"
depends on PRINTK
select SERIAL_CORE
help
Support for the on-chip linflexuart on some Freescale SOCs.
Support for the on-chip LINFlexD UART on some Freescale SOCs.
config SERIAL_FSL_LINFLEXUART_CONSOLE
bool "Console on Freescale linflexuart serial port"
bool "Console on Freescale LINFlexD UART serial port"
depends on SERIAL_FSL_LINFLEXUART=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
help
If you have enabled the linflexuart serial port on the Freescale
If you have enabled the LINFlexD UART serial port on the Freescale
SoCs, you can make it the console by answering Y to this option.
config SERIAL_CONEXANT_DIGICOLOR

View File

@ -30,7 +30,7 @@ obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
obj-$(CONFIG_SERIAL_MAX310X) += max310x.o
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o

View File

@ -414,7 +414,7 @@ static void pl011_dma_probe(struct uart_amba_port *uap)
dma_cap_mask_t mask;
uap->dma_probed = true;
chan = dma_request_slave_channel_reason(dev, "tx");
chan = dma_request_chan(dev, "tx");
if (IS_ERR(chan)) {
if (PTR_ERR(chan) == -EPROBE_DEFER) {
uap->dma_probed = false;
@ -813,10 +813,8 @@ __acquires(&uap->port.lock)
if (!uap->using_tx_dma)
return;
/* Avoid deadlock with the DMA engine callback */
spin_unlock(&uap->port.lock);
dmaengine_terminate_all(uap->dmatx.chan);
spin_lock(&uap->port.lock);
dmaengine_terminate_async(uap->dmatx.chan);
if (uap->dmatx.queued) {
dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1,
DMA_TO_DEVICE);
@ -1236,10 +1234,6 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap)
#else
/* Blank functions if the DMA engine is not available */
static inline void pl011_dma_probe(struct uart_amba_port *uap)
{
}
static inline void pl011_dma_remove(struct uart_amba_port *uap)
{
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Freescale linflexuart serial port driver
* Freescale LINFlexD UART serial port driver
*
* Copyright 2012-2016 Freescale Semiconductor, Inc.
* Copyright 2017-2019 NXP
@ -940,5 +940,5 @@ static void __exit linflex_serial_exit(void)
module_init(linflex_serial_init);
module_exit(linflex_serial_exit);
MODULE_DESCRIPTION("Freescale linflex serial port driver");
MODULE_DESCRIPTION("Freescale LINFlexD serial port driver");
MODULE_LICENSE("GPL v2");

View File

@ -437,8 +437,8 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
}
sport->dma_tx_desc = dmaengine_prep_slave_sg(sport->dma_tx_chan, sgl,
sport->dma_tx_nents,
DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
ret, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT);
if (!sport->dma_tx_desc) {
dma_unmap_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
dev_err(dev, "Cannot prepare TX slave DMA!\n");
@ -1280,6 +1280,57 @@ static int lpuart_config_rs485(struct uart_port *port,
return 0;
}
static int lpuart32_config_rs485(struct uart_port *port,
struct serial_rs485 *rs485)
{
struct lpuart_port *sport = container_of(port,
struct lpuart_port, port);
unsigned long modem = lpuart32_read(&sport->port, UARTMODIR)
& ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE);
lpuart32_write(&sport->port, modem, UARTMODIR);
/* clear unsupported configurations */
rs485->delay_rts_before_send = 0;
rs485->delay_rts_after_send = 0;
rs485->flags &= ~SER_RS485_RX_DURING_TX;
if (rs485->flags & SER_RS485_ENABLED) {
/* Enable auto RS-485 RTS mode */
modem |= UARTMODEM_TXRTSE;
/*
* RTS needs to be logic HIGH either during transer _or_ after
* transfer, other variants are not supported by the hardware.
*/
if (!(rs485->flags & (SER_RS485_RTS_ON_SEND |
SER_RS485_RTS_AFTER_SEND)))
rs485->flags |= SER_RS485_RTS_ON_SEND;
if (rs485->flags & SER_RS485_RTS_ON_SEND &&
rs485->flags & SER_RS485_RTS_AFTER_SEND)
rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
/*
* The hardware defaults to RTS logic HIGH while transfer.
* Switch polarity in case RTS shall be logic HIGH
* after transfer.
* Note: UART is assumed to be active high.
*/
if (rs485->flags & SER_RS485_RTS_ON_SEND)
modem &= ~UARTMODEM_TXRTSPOL;
else if (rs485->flags & SER_RS485_RTS_AFTER_SEND)
modem |= UARTMODEM_TXRTSPOL;
}
/* Store the new configuration */
sport->port.rs485 = *rs485;
lpuart32_write(&sport->port, modem, UARTMODIR);
return 0;
}
static unsigned int lpuart_get_mctrl(struct uart_port *port)
{
unsigned int temp = 0;
@ -1333,18 +1384,7 @@ static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
unsigned long temp;
temp = lpuart32_read(port, UARTMODIR) &
~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
if (mctrl & TIOCM_RTS)
temp |= UARTMODIR_RXRTSE;
if (mctrl & TIOCM_CTS)
temp |= UARTMODIR_TXCTSE;
lpuart32_write(port, temp, UARTMODIR);
}
static void lpuart_break_ctl(struct uart_port *port, int break_state)
@ -1889,11 +1929,18 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
ctrl |= UARTCTRL_M;
}
/*
* When auto RS-485 RTS mode is enabled,
* hardware flow control need to be disabled.
*/
if (sport->port.rs485.flags & SER_RS485_ENABLED)
termios->c_cflag &= ~CRTSCTS;
if (termios->c_cflag & CRTSCTS) {
modem |= UARTMODEM_RXRTSE | UARTMODEM_TXCTSE;
modem |= (UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
} else {
termios->c_cflag &= ~CRTSCTS;
modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
modem &= ~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
}
if (termios->c_cflag & CSTOPB)
@ -2416,7 +2463,10 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.ops = &lpuart_pops;
sport->port.flags = UPF_BOOT_AUTOCONF;
sport->port.rs485_config = lpuart_config_rs485;
if (lpuart_is_32(sport))
sport->port.rs485_config = lpuart32_config_rs485;
else
sport->port.rs485_config = lpuart_config_rs485;
sport->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(sport->ipg_clk)) {
@ -2470,7 +2520,7 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.rs485.delay_rts_after_send)
dev_err(&pdev->dev, "driver doesn't support RTS delays\n");
lpuart_config_rs485(&sport->port, &sport->port.rs485);
sport->port.rs485_config(&sport->port, &sport->port.rs485);
sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
if (!sport->dma_tx_chan)

View File

@ -1230,6 +1230,9 @@ static int ifx_spi_spi_remove(struct spi_device *spi)
struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi);
/* stop activity */
tasklet_kill(&ifx_dev->io_work_tasklet);
pm_runtime_disable(&spi->dev);
/* free irq */
free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), ifx_dev);
free_irq(gpio_to_irq(ifx_dev->gpio.srdy), ifx_dev);

View File

@ -619,7 +619,7 @@ static void imx_uart_dma_tx(struct imx_port *sport)
dev_err(dev, "DMA mapping error for TX.\n");
return;
}
desc = dmaengine_prep_slave_sg(chan, sgl, sport->dma_tx_nents,
desc = dmaengine_prep_slave_sg(chan, sgl, ret,
DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
if (!desc) {
dma_unmap_sg(dev, sgl, sport->dma_tx_nents,
@ -1034,8 +1034,6 @@ static void imx_uart_timeout(struct timer_list *t)
}
}
#define RX_BUF_SIZE (PAGE_SIZE)
/*
* There are two kinds of RX DMA interrupts(such as in the MX6Q):
* [1] the RX DMA buffer is full.
@ -1118,7 +1116,8 @@ static void imx_uart_dma_rx_callback(void *data)
}
/* RX DMA buffer periods */
#define RX_DMA_PERIODS 4
#define RX_DMA_PERIODS 16
#define RX_BUF_SIZE (RX_DMA_PERIODS * PAGE_SIZE / 4)
static int imx_uart_start_rx_dma(struct imx_port *sport)
{

View File

@ -301,7 +301,7 @@ static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base)
dma = &msm_port->tx_dma;
/* allocate DMA resources, if available */
dma->chan = dma_request_slave_channel_reason(dev, "tx");
dma->chan = dma_request_chan(dev, "tx");
if (IS_ERR(dma->chan))
goto no_tx;
@ -344,7 +344,7 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base)
dma = &msm_port->rx_dma;
/* allocate DMA resources, if available */
dma->chan = dma_request_slave_channel_reason(dev, "rx");
dma->chan = dma_request_chan(dev, "rx");
if (IS_ERR(dma->chan))
goto no_rx;
@ -980,6 +980,7 @@ static unsigned int msm_get_mctrl(struct uart_port *port)
static void msm_reset(struct uart_port *port)
{
struct msm_port *msm_port = UART_TO_MSM(port);
unsigned int mr;
/* reset everything */
msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
@ -987,7 +988,10 @@ static void msm_reset(struct uart_port *port)
msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
msm_write(port, UART_CR_CMD_RESET_RFR, UART_CR);
mr = msm_read(port, UART_MR1);
mr &= ~UART_MR1_RX_RDY_CTL;
msm_write(port, mr, UART_MR1);
/* Disable DM modes */
if (msm_port->is_uartdm)

View File

@ -233,6 +233,7 @@ struct eg20t_port {
struct dma_chan *chan_rx;
struct scatterlist *sg_tx_p;
int nent;
int orig_nent;
struct scatterlist sg_rx;
int tx_dma_use;
void *rx_buf_virt;
@ -787,9 +788,10 @@ static void pch_dma_tx_complete(void *arg)
}
xmit->tail &= UART_XMIT_SIZE - 1;
async_tx_ack(priv->desc_tx);
dma_unmap_sg(port->dev, sg, priv->nent, DMA_TO_DEVICE);
dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE);
priv->tx_dma_use = 0;
priv->nent = 0;
priv->orig_nent = 0;
kfree(priv->sg_tx_p);
pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT);
}
@ -1010,6 +1012,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
dev_err(priv->port.dev, "%s:dma_map_sg Failed\n", __func__);
return 0;
}
priv->orig_nent = num;
priv->nent = nent;
for (i = 0; i < nent; i++, sg++) {

View File

@ -9,10 +9,12 @@
#include <linux/console.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_wakeirq.h>
#include <linux/qcom-geni-se.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
@ -115,6 +117,7 @@ struct qcom_geni_serial_port {
bool brk;
unsigned int tx_remaining;
int wakeup_irq;
};
static const struct uart_ops qcom_geni_console_pops;
@ -754,6 +757,15 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
uart_write_wakeup(uport);
}
static irqreturn_t qcom_geni_serial_wakeup_isr(int isr, void *dev)
{
struct uart_port *uport = dev;
pm_wakeup_event(uport->dev, 2000);
return IRQ_HANDLED;
}
static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
{
u32 m_irq_en;
@ -830,7 +842,7 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport)
if (uart_console(uport))
console_stop(uport->cons);
free_irq(uport->irq, uport);
disable_irq(uport->irq);
spin_lock_irqsave(&uport->lock, flags);
qcom_geni_serial_stop_tx(uport);
qcom_geni_serial_stop_rx(uport);
@ -890,21 +902,14 @@ static int qcom_geni_serial_startup(struct uart_port *uport)
int ret;
struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
scnprintf(port->name, sizeof(port->name),
"qcom_serial_%s%d",
(uart_console(uport) ? "console" : "uart"), uport->line);
if (!port->setup) {
ret = qcom_geni_serial_port_setup(uport);
if (ret)
return ret;
}
enable_irq(uport->irq);
ret = request_irq(uport->irq, qcom_geni_serial_isr, IRQF_TRIGGER_HIGH,
port->name, uport);
if (ret)
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
return ret;
return 0;
}
static unsigned long get_clk_cfg(unsigned long clk_freq)
@ -1297,11 +1302,44 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS;
port->tx_fifo_width = DEF_FIFO_WIDTH_BITS;
scnprintf(port->name, sizeof(port->name), "qcom_geni_serial_%s%d",
(uart_console(uport) ? "console" : "uart"), uport->line);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
uport->irq = irq;
irq_set_status_flags(uport->irq, IRQ_NOAUTOEN);
ret = devm_request_irq(uport->dev, uport->irq, qcom_geni_serial_isr,
IRQF_TRIGGER_HIGH, port->name, uport);
if (ret) {
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
return ret;
}
if (!console) {
port->wakeup_irq = platform_get_irq(pdev, 1);
if (port->wakeup_irq < 0) {
dev_err(&pdev->dev, "Failed to get wakeup IRQ %d\n",
port->wakeup_irq);
} else {
irq_set_status_flags(port->wakeup_irq, IRQ_NOAUTOEN);
ret = devm_request_irq(uport->dev, port->wakeup_irq,
qcom_geni_serial_wakeup_isr,
IRQF_TRIGGER_FALLING, "uart_wakeup", uport);
if (ret) {
dev_err(uport->dev, "Failed to register wakeup IRQ ret %d\n",
ret);
return ret;
}
device_init_wakeup(&pdev->dev, true);
ret = dev_pm_set_wake_irq(&pdev->dev, port->wakeup_irq);
if (unlikely(ret))
dev_err(uport->dev, "%s:Failed to set IRQ wake:%d\n",
__func__, ret);
}
}
uport->private_data = drv;
platform_set_drvdata(pdev, port);
port->handle_rx = console ? handle_rx_console : handle_rx_uart;
@ -1324,7 +1362,12 @@ static int __maybe_unused qcom_geni_serial_sys_suspend(struct device *dev)
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
return uart_suspend_port(uport->private_data, uport);
uart_suspend_port(uport->private_data, uport);
if (port->wakeup_irq > 0)
enable_irq(port->wakeup_irq);
return 0;
}
static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev)
@ -1332,6 +1375,9 @@ static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev)
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
if (port->wakeup_irq > 0)
disable_irq(port->wakeup_irq);
return uart_resume_port(uport->private_data, uport);
}

View File

@ -1122,8 +1122,7 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
int ret;
struct dma_slave_config dma_sconfig;
dma_chan = dma_request_slave_channel_reason(tup->uport.dev,
dma_to_memory ? "rx" : "tx");
dma_chan = dma_request_chan(tup->uport.dev, dma_to_memory ? "rx" : "tx");
if (IS_ERR(dma_chan)) {
ret = PTR_ERR(dma_chan);
dev_err(tup->uport.dev,

View File

@ -1111,7 +1111,7 @@ static int uart_break_ctl(struct tty_struct *tty, int break_state)
if (!uport)
goto out;
if (uport->type != PORT_UNKNOWN)
if (uport->type != PORT_UNKNOWN && uport->ops->break_ctl)
uport->ops->break_ctl(uport, break_state);
ret = 0;
out:

View File

@ -120,7 +120,8 @@ static u32 uart_usp_ff_empty_mask(struct uart_port *port)
empty_bit = ilog2(port->fifosize) + 1;
return (1 << empty_bit);
}
struct sirfsoc_uart_register sirfsoc_usp = {
static struct sirfsoc_uart_register sirfsoc_usp = {
.uart_reg = {
.sirfsoc_mode1 = 0x0000,
.sirfsoc_mode2 = 0x0004,
@ -186,7 +187,7 @@ struct sirfsoc_uart_register sirfsoc_usp = {
},
};
struct sirfsoc_uart_register sirfsoc_uart = {
static struct sirfsoc_uart_register sirfsoc_uart = {
.uart_reg = {
.sirfsoc_line_ctrl = 0x0040,
.sirfsoc_tx_rx_en = 0x004c,

View File

@ -919,6 +919,34 @@ static void sprd_pm(struct uart_port *port, unsigned int state,
}
}
#ifdef CONFIG_CONSOLE_POLL
static int sprd_poll_init(struct uart_port *port)
{
if (port->state->pm_state != UART_PM_STATE_ON) {
sprd_pm(port, UART_PM_STATE_ON, 0);
port->state->pm_state = UART_PM_STATE_ON;
}
return 0;
}
static int sprd_poll_get_char(struct uart_port *port)
{
while (!(serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK))
cpu_relax();
return serial_in(port, SPRD_RXD);
}
static void sprd_poll_put_char(struct uart_port *port, unsigned char ch)
{
while (serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK)
cpu_relax();
serial_out(port, SPRD_TXD, ch);
}
#endif
static const struct uart_ops serial_sprd_ops = {
.tx_empty = sprd_tx_empty,
.get_mctrl = sprd_get_mctrl,
@ -936,6 +964,11 @@ static const struct uart_ops serial_sprd_ops = {
.config_port = sprd_config_port,
.verify_port = sprd_verify_port,
.pm = sprd_pm,
#ifdef CONFIG_CONSOLE_POLL
.poll_init = sprd_poll_init,
.poll_get_char = sprd_poll_get_char,
.poll_put_char = sprd_poll_put_char,
#endif
};
#ifdef CONFIG_SERIAL_SPRD_CONSOLE

View File

@ -240,8 +240,8 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded)
* cleared by the sequence [read SR - read DR].
*/
if ((sr & USART_SR_ERR_MASK) && ofs->icr != UNDEF_REG)
stm32_clr_bits(port, ofs->icr, USART_ICR_ORECF |
USART_ICR_PECF | USART_ICR_FECF);
writel_relaxed(sr & USART_SR_ERR_MASK,
port->membase + ofs->icr);
c = stm32_get_char(port, &sr, &stm32_port->last_res);
port->icount.rx++;
@ -435,7 +435,7 @@ static void stm32_transmit_chars(struct uart_port *port)
if (ofs->icr == UNDEF_REG)
stm32_clr_bits(port, ofs->isr, USART_SR_TC);
else
stm32_set_bits(port, ofs->icr, USART_ICR_TCCF);
writel_relaxed(USART_ICR_TCCF, port->membase + ofs->icr);
if (stm32_port->tx_ch)
stm32_transmit_chars_dma(port);

View File

@ -22,7 +22,6 @@
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
#define ULITE_NAME "ttyUL"
#define ULITE_MAJOR 204
@ -55,7 +54,6 @@
#define ULITE_CONTROL_RST_TX 0x01
#define ULITE_CONTROL_RST_RX 0x02
#define ULITE_CONTROL_IE 0x10
#define UART_AUTOSUSPEND_TIMEOUT 3000
/* Static pointer to console port */
#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
@ -65,7 +63,6 @@ static struct uart_port *console_port;
struct uartlite_data {
const struct uartlite_reg_ops *reg_ops;
struct clk *clk;
struct uart_driver *ulite_uart_driver;
};
struct uartlite_reg_ops {
@ -393,12 +390,12 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
static void ulite_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
if (!state) {
pm_runtime_get_sync(port->dev);
} else {
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
}
struct uartlite_data *pdata = port->private_data;
if (!state)
clk_enable(pdata->clk);
else
clk_disable(pdata->clk);
}
#ifdef CONFIG_CONSOLE_POLL
@ -697,9 +694,7 @@ static int ulite_release(struct device *dev)
int rc = 0;
if (port) {
struct uartlite_data *pdata = port->private_data;
rc = uart_remove_one_port(pdata->ulite_uart_driver, port);
rc = uart_remove_one_port(&ulite_uart_driver, port);
dev_set_drvdata(dev, NULL);
port->mapbase = 0;
}
@ -717,11 +712,8 @@ static int __maybe_unused ulite_suspend(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
if (port) {
struct uartlite_data *pdata = port->private_data;
uart_suspend_port(pdata->ulite_uart_driver, port);
}
if (port)
uart_suspend_port(&ulite_uart_driver, port);
return 0;
}
@ -736,41 +728,17 @@ static int __maybe_unused ulite_resume(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
if (port) {
struct uartlite_data *pdata = port->private_data;
uart_resume_port(pdata->ulite_uart_driver, port);
}
if (port)
uart_resume_port(&ulite_uart_driver, port);
return 0;
}
static int __maybe_unused ulite_runtime_suspend(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
struct uartlite_data *pdata = port->private_data;
clk_disable(pdata->clk);
return 0;
};
static int __maybe_unused ulite_runtime_resume(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
struct uartlite_data *pdata = port->private_data;
clk_enable(pdata->clk);
return 0;
}
/* ---------------------------------------------------------------------
* Platform bus binding
*/
static const struct dev_pm_ops ulite_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(ulite_suspend, ulite_resume)
SET_RUNTIME_PM_OPS(ulite_runtime_suspend,
ulite_runtime_resume, NULL)
};
static SIMPLE_DEV_PM_OPS(ulite_pm_ops, ulite_suspend, ulite_resume);
#if defined(CONFIG_OF)
/* Match table for of_platform binding */
@ -795,22 +763,6 @@ static int ulite_probe(struct platform_device *pdev)
if (prop)
id = be32_to_cpup(prop);
#endif
if (id < 0) {
/* Look for a serialN alias */
id = of_alias_get_id(pdev->dev.of_node, "serial");
if (id < 0)
id = 0;
}
if (!ulite_uart_driver.state) {
dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
ret = uart_register_driver(&ulite_uart_driver);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register driver\n");
return ret;
}
}
pdata = devm_kzalloc(&pdev->dev, sizeof(struct uartlite_data),
GFP_KERNEL);
if (!pdata)
@ -836,22 +788,24 @@ static int ulite_probe(struct platform_device *pdev)
pdata->clk = NULL;
}
pdata->ulite_uart_driver = &ulite_uart_driver;
ret = clk_prepare_enable(pdata->clk);
if (ret) {
dev_err(&pdev->dev, "Failed to prepare clock\n");
return ret;
}
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
if (!ulite_uart_driver.state) {
dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
ret = uart_register_driver(&ulite_uart_driver);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register driver\n");
return ret;
}
}
ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata);
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
clk_disable(pdata->clk);
return ret;
}
@ -860,14 +814,9 @@ static int ulite_remove(struct platform_device *pdev)
{
struct uart_port *port = dev_get_drvdata(&pdev->dev);
struct uartlite_data *pdata = port->private_data;
int rc;
clk_unprepare(pdata->clk);
rc = ulite_release(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
return rc;
clk_disable_unprepare(pdata->clk);
return ulite_release(&pdev->dev);
}
/* work with hotplug and coldplug */

View File

@ -1345,9 +1345,12 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
if (!tty->port)
tty->port = driver->ports[idx];
WARN_RATELIMIT(!tty->port,
"%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n",
__func__, tty->driver->name);
if (WARN_RATELIMIT(!tty->port,
"%s: %s driver does not set tty->port. This would crash the kernel. Fix the driver!\n",
__func__, tty->driver->name)) {
retval = -EINVAL;
goto err_release_lock;
}
retval = tty_ldisc_lock(tty, 5 * HZ);
if (retval)
@ -1925,7 +1928,6 @@ EXPORT_SYMBOL_GPL(tty_kopen);
/**
* tty_open_by_driver - open a tty device
* @device: dev_t of device to open
* @inode: inode of device file
* @filp: file pointer to tty
*
* Performs the driver lookup, checks for a reopen, or otherwise
@ -1938,7 +1940,7 @@ EXPORT_SYMBOL_GPL(tty_kopen);
* - concurrent tty driver removal w/ lookup
* - concurrent tty removal from driver table
*/
static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode,
static struct tty_struct *tty_open_by_driver(dev_t device,
struct file *filp)
{
struct tty_struct *tty;
@ -2030,7 +2032,7 @@ static int tty_open(struct inode *inode, struct file *filp)
tty = tty_open_current_tty(device, filp);
if (!tty)
tty = tty_open_by_driver(device, inode, filp);
tty = tty_open_by_driver(device, filp);
if (IS_ERR(tty)) {
tty_free_file(filp);

View File

@ -156,12 +156,7 @@ static void put_ldops(struct tty_ldisc_ops *ldops)
* takes tty_ldiscs_lock to guard against ldisc races
*/
#if defined(CONFIG_LDISC_AUTOLOAD)
#define INITIAL_AUTOLOAD_STATE 1
#else
#define INITIAL_AUTOLOAD_STATE 0
#endif
static int tty_ldisc_autoload = INITIAL_AUTOLOAD_STATE;
static int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD);
static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
{

View File

@ -1491,7 +1491,7 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
kbd_rawcode(value);
if (event_type == EV_KEY)
if (event_type == EV_KEY && event_code <= KEY_MAX)
kbd_keycode(event_code, value, HW_RAW(handle->dev));
spin_unlock(&kbd_event_lock);

View File

@ -456,6 +456,9 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
size_t ret;
char *con_buf;
if (use_unicode(inode))
return -EOPNOTSUPP;
con_buf = (char *) __get_free_page(GFP_KERNEL);
if (!con_buf)
return -ENOMEM;

View File

@ -290,7 +290,7 @@
/* Sunix UART */
#define PORT_SUNIX 121
/* Freescale Linflex UART */
/* Freescale LINFlexD UART */
#define PORT_LINFLEXUART 122
#endif /* _UAPILINUX_SERIAL_CORE_H */