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
Родитель c3bed3b20e 27ed14d0ec
Коммит 537bd0a159
49 изменённых файлов: 665 добавлений и 715 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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.

Просмотреть файл

@ -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:

Просмотреть файл

@ -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.

Просмотреть файл

@ -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.

Просмотреть файл

@ -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``

Просмотреть файл

@ -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``

Просмотреть файл

@ -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``

Просмотреть файл

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

Просмотреть файл

@ -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

Просмотреть файл

@ -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
*/

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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)

Просмотреть файл

@ -552,16 +552,97 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
}
#ifdef CONFIG_ACPI
#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 = NULL;
struct serdev_device *serdev;
int err;
if (acpi_bus_get_status(adev) || !adev->status.present ||
acpi_device_enumerated(adev))
return AE_OK;
serdev = serdev_device_alloc(ctrl);
if (!serdev) {
dev_err(&ctrl->dev, "failed to allocate serdev device for %s\n",
@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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,7 +290,9 @@ 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)
if (ret)
goto out;
p->uartclk = rate;
out:
@ -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)) {
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);
else
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,18 +489,17 @@ 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;
}
}
data->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
if (IS_ERR(data->rst)) {
@ -546,11 +541,9 @@ err_reset:
reset_control_assert(data->rst);
err_pclk:
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);
err_clk:
if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk);
return err;
@ -567,10 +560,8 @@ static int dw8250_remove(struct platform_device *pdev)
reset_control_assert(data->rst);
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);
if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk);
pm_runtime_disable(dev);
@ -604,10 +595,8 @@ 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);
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);
return 0;
@ -617,10 +606,8 @@ 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);
if (!IS_ERR(data->clk))
clk_prepare_enable(data->clk);
return 0;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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 = {

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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:

Просмотреть файл

@ -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

Просмотреть файл

@ -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())

Просмотреть файл

@ -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-

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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)
{
}

Просмотреть файл

@ -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");

Просмотреть файл

@ -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,6 +2463,9 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.ops = &lpuart_pops;
sport->port.flags = UPF_BOOT_AUTOCONF;
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");
@ -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)

Просмотреть файл

@ -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);

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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)

Просмотреть файл

@ -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++) {

Просмотреть файл

@ -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 @@ out_write_wakeup:
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);
}

Просмотреть файл

Просмотреть файл

@ -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,

Просмотреть файл

@ -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:

Просмотреть файл

@ -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,

Просмотреть файл

@ -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

Просмотреть файл

@ -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);

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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 @@ retry_open:
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);

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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 */