Merge tag 'tty-4.12-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/Serial patch updates for 4.12-rc1

  Not a lot of new things here, the normal number of serial driver
  updates and additions, tiny bugs fixed, and some core files split up
  to make future changes a bit easier for Nicolas's "tiny-tty" work.

  All of these have been in linux-next for a while"

* tag 'tty-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (62 commits)
  serial: small Makefile reordering
  tty: split job control support into a file of its own
  tty: move baudrate handling code to a file of its own
  console: move console_init() out of tty_io.c
  serial: 8250_early: Add earlycon support for Palmchip UART
  tty: pl011: use "qdf2400_e44" as the earlycon name for QDF2400 E44
  vt: make mouse selection of non-ASCII consistent
  vt: set mouse selection word-chars to gpm's default
  imx-serial: Reduce RX DMA startup latency when opening for reading
  serial: omap: suspend device on probe errors
  serial: omap: fix runtime-pm handling on unbind
  tty: serial: omap: add UPF_BOOT_AUTOCONF flag for DT init
  serial: samsung: Remove useless spinlock
  serial: samsung: Add missing checks for dma_map_single failure
  serial: samsung: Use right device for DMA-mapping calls
  serial: imx: setup DCEDTE early and ensure DCD and RI irqs to be off
  tty: fix comment typo s/repsonsible/responsible/
  tty: amba-pl011: Fix spurious TX interrupts
  serial: xuartps: Enable clocks in the pm disable case also
  serial: core: Re-use struct uart_port {name} field
  ...
This commit is contained in:
Linus Torvalds
2017-05-08 18:49:23 -07:00
48 changed files with 1396 additions and 1034 deletions

View File

@@ -218,7 +218,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up)
spin_unlock_irq(&i->lock);
irq_flags |= up->port.irqflags;
ret = request_irq(up->port.irq, serial8250_interrupt,
irq_flags, "serial", i);
irq_flags, up->port.name, i);
if (ret < 0)
serial_do_unlink(i, up);
}

View File

@@ -530,12 +530,11 @@ static int dw8250_probe(struct platform_device *pdev)
}
data->rst = devm_reset_control_get_optional(dev, NULL);
if (IS_ERR(data->rst) && PTR_ERR(data->rst) == -EPROBE_DEFER) {
err = -EPROBE_DEFER;
if (IS_ERR(data->rst)) {
err = PTR_ERR(data->rst);
goto err_pclk;
}
if (!IS_ERR(data->rst))
reset_control_deassert(data->rst);
reset_control_deassert(data->rst);
dw8250_quirks(p, data);
@@ -567,8 +566,7 @@ static int dw8250_probe(struct platform_device *pdev)
return 0;
err_reset:
if (!IS_ERR(data->rst))
reset_control_assert(data->rst);
reset_control_assert(data->rst);
err_pclk:
if (!IS_ERR(data->pclk))
@@ -589,8 +587,7 @@ static int dw8250_remove(struct platform_device *pdev)
serial8250_unregister_port(data->line);
if (!IS_ERR(data->rst))
reset_control_assert(data->rst);
reset_control_assert(data->rst);
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);

View File

@@ -39,6 +39,7 @@
static unsigned int __init serial8250_early_in(struct uart_port *port, int offset)
{
int reg_offset = offset;
offset <<= port->regshift;
switch (port->iotype) {
@@ -52,6 +53,8 @@ static unsigned int __init serial8250_early_in(struct uart_port *port, int offse
return ioread32be(port->membase + offset);
case UPIO_PORT:
return inb(port->iobase + offset);
case UPIO_AU:
return port->serial_in(port, reg_offset);
default:
return 0;
}
@@ -59,6 +62,7 @@ static unsigned int __init serial8250_early_in(struct uart_port *port, int offse
static void __init serial8250_early_out(struct uart_port *port, int offset, int value)
{
int reg_offset = offset;
offset <<= port->regshift;
switch (port->iotype) {
@@ -77,6 +81,9 @@ static void __init serial8250_early_out(struct uart_port *port, int offset, int
case UPIO_PORT:
outb(value, port->iobase + offset);
break;
case UPIO_AU:
port->serial_out(port, reg_offset, value);
break;
}
}
@@ -172,3 +179,20 @@ OF_EARLYCON_DECLARE(omap8250, "ti,omap3-uart", early_omap8250_setup);
OF_EARLYCON_DECLARE(omap8250, "ti,omap4-uart", early_omap8250_setup);
#endif
#ifdef CONFIG_SERIAL_8250_RT288X
unsigned int au_serial_in(struct uart_port *p, int offset);
void au_serial_out(struct uart_port *p, int offset, int value);
static int __init early_au_setup(struct earlycon_device *dev, const char *opt)
{
dev->port.serial_in = au_serial_in;
dev->port.serial_out = au_serial_out;
dev->port.iotype = UPIO_AU;
dev->con->write = early_serial8250_write;
return 0;
}
OF_EARLYCON_DECLARE(palmchip, "ralink,rt2880-uart", early_au_setup);
#endif

View File

@@ -483,5 +483,5 @@ static struct pci_driver exar_pci_driver = {
module_pci_driver(exar_pci_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Exar Serial Dricer");
MODULE_DESCRIPTION("Exar Serial Driver");
MODULE_AUTHOR("Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>");

View File

@@ -61,6 +61,12 @@
* The IRQ setting mode of F81866 is not the same with F81216 series.
* Level/Low: IRQ_MODE0:0, IRQ_MODE1:0
* Edge/High: IRQ_MODE0:1, IRQ_MODE1:0
*
* Clock speeds for UART (register F2h)
* 00: 1.8432MHz.
* 01: 18.432MHz.
* 10: 24MHz.
* 11: 14.769MHz.
*/
#define F81866_IRQ_MODE 0xf0
#define F81866_IRQ_SHARE BIT(0)
@@ -72,6 +78,13 @@
#define F81866_LDN_LOW 0x10
#define F81866_LDN_HIGH 0x16
#define F81866_UART_CLK 0xF2
#define F81866_UART_CLK_MASK (BIT(1) | BIT(0))
#define F81866_UART_CLK_1_8432MHZ 0
#define F81866_UART_CLK_14_769MHZ (BIT(1) | BIT(0))
#define F81866_UART_CLK_18_432MHZ BIT(0)
#define F81866_UART_CLK_24MHZ BIT(1)
struct fintek_8250 {
u16 pid;
u16 base_port;
@@ -256,8 +269,26 @@ static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata)
}
}
static int probe_setup_port(struct fintek_8250 *pdata, u16 io_address,
unsigned int irq)
static void fintek_8250_goto_highspeed(struct uart_8250_port *uart,
struct fintek_8250 *pdata)
{
sio_write_reg(pdata, LDN, pdata->index);
switch (pdata->pid) {
case CHIP_ID_F81866: /* set uart clock for high speed serial mode */
sio_write_mask_reg(pdata, F81866_UART_CLK,
F81866_UART_CLK_MASK,
F81866_UART_CLK_14_769MHZ);
uart->port.uartclk = 921600 * 16;
break;
default: /* leave clock speed untouched */
break;
}
}
static int probe_setup_port(struct fintek_8250 *pdata,
struct uart_8250_port *uart)
{
static const u16 addr[] = {0x4e, 0x2e};
static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67};
@@ -284,18 +315,20 @@ static int probe_setup_port(struct fintek_8250 *pdata, u16 io_address,
sio_write_reg(pdata, LDN, k);
aux = sio_read_reg(pdata, IO_ADDR1);
aux |= sio_read_reg(pdata, IO_ADDR2) << 8;
if (aux != io_address)
if (aux != uart->port.iobase)
continue;
pdata->index = k;
irq_data = irq_get_irq_data(irq);
irq_data = irq_get_irq_data(uart->port.irq);
if (irq_data)
level_mode =
irqd_is_level_type(irq_data);
fintek_8250_set_irq_mode(pdata, level_mode);
fintek_8250_set_max_fifo(pdata);
fintek_8250_goto_highspeed(uart, pdata);
fintek_8250_exit_key(addr[i]);
return 0;
@@ -330,7 +363,7 @@ int fintek_8250_probe(struct uart_8250_port *uart)
struct fintek_8250 *pdata;
struct fintek_8250 probe_data;
if (probe_setup_port(&probe_data, uart->port.iobase, uart->port.irq))
if (probe_setup_port(&probe_data, uart))
return -ENODEV;
pdata = devm_kzalloc(uart->port.dev, sizeof(*pdata), GFP_KERNEL);

View File

@@ -183,7 +183,6 @@ static void qrk_serial_setup_dma(struct lpss8250 *lpss, struct uart_port *port)
if (ret)
return;
pci_set_master(pdev);
pci_try_set_mwi(pdev);
/* Special DMA address for UART */
@@ -216,6 +215,8 @@ 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;

View File

@@ -328,7 +328,7 @@ static const s8 au_io_out_map[8] = {
-1, /* UART_SCR (unmapped) */
};
static unsigned int au_serial_in(struct uart_port *p, int offset)
unsigned int au_serial_in(struct uart_port *p, int offset)
{
if (offset >= ARRAY_SIZE(au_io_in_map))
return UINT_MAX;
@@ -338,7 +338,7 @@ static unsigned int au_serial_in(struct uart_port *p, int offset)
return __raw_readl(p->membase + (offset << p->regshift));
}
static void au_serial_out(struct uart_port *p, int offset, int value)
void au_serial_out(struct uart_port *p, int offset, int value)
{
if (offset >= ARRAY_SIZE(au_io_out_map))
return;

View File

@@ -630,6 +630,15 @@ config SERIAL_UARTLITE_CONSOLE
console (the system console is the device which receives all kernel
messages and warnings and which allows logins in single user mode).
config SERIAL_UARTLITE_NR_UARTS
int "Maximum number of uartlite serial ports"
depends on SERIAL_UARTLITE
range 1 256
default 1
help
Set this to the number of uartlites in your system, or the number
you think you might implement.
config SERIAL_SUNCORE
bool
depends on SPARC
@@ -1343,6 +1352,7 @@ config SERIAL_ALTERA_JTAGUART_CONSOLE
bool "Altera JTAG UART console support"
depends on SERIAL_ALTERA_JTAGUART=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
help
Enable a Altera JTAG UART port to be the system console.
@@ -1382,6 +1392,7 @@ config SERIAL_ALTERA_UART_CONSOLE
bool "Altera UART console support"
depends on SERIAL_ALTERA_UART=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
help
Enable a Altera UART port to be the system console.

View File

@@ -3,7 +3,6 @@
#
obj-$(CONFIG_SERIAL_CORE) += serial_core.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
obj-$(CONFIG_SERIAL_EARLYCON) += earlycon.o
obj-$(CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST) += earlycon-arm-semihost.o
@@ -17,6 +16,8 @@ obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o
obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
# Now bring in any enabled 8250/16450/16550 type drivers.
obj-$(CONFIG_SERIAL_8250) += 8250/

View File

@@ -383,6 +383,26 @@ console_initcall(altera_jtaguart_console_init);
#define ALTERA_JTAGUART_CONSOLE (&altera_jtaguart_console)
static void altera_jtaguart_earlycon_write(struct console *co, const char *s,
unsigned int count)
{
struct earlycon_device *dev = co->data;
uart_console_write(&dev->port, s, count, altera_jtaguart_console_putc);
}
static int __init altera_jtaguart_earlycon_setup(struct earlycon_device *dev,
const char *options)
{
if (!dev->port.membase)
return -ENODEV;
dev->con->write = altera_jtaguart_earlycon_write;
return 0;
}
OF_EARLYCON_DECLARE(juart, "altr,juart-1.0", altera_jtaguart_earlycon_setup);
#else
#define ALTERA_JTAGUART_CONSOLE NULL

View File

@@ -489,6 +489,38 @@ console_initcall(altera_uart_console_init);
#define ALTERA_UART_CONSOLE (&altera_uart_console)
static void altera_uart_earlycon_write(struct console *co, const char *s,
unsigned int count)
{
struct earlycon_device *dev = co->data;
uart_console_write(&dev->port, s, count, altera_uart_console_putc);
}
static int __init altera_uart_earlycon_setup(struct earlycon_device *dev,
const char *options)
{
struct uart_port *port = &dev->port;
if (!port->membase)
return -ENODEV;
/* Enable RX interrupts now */
writel(ALTERA_UART_CONTROL_RRDY_MSK,
port->membase + ALTERA_UART_CONTROL_REG);
if (dev->baud) {
unsigned int baudclk = port->uartclk / dev->baud;
writel(baudclk, port->membase + ALTERA_UART_DIVISOR_REG);
}
dev->con->write = altera_uart_earlycon_write;
return 0;
}
OF_EARLYCON_DECLARE(uart, "altr,uart-1.0", altera_uart_earlycon_setup);
#else
#define ALTERA_UART_CONSOLE NULL

View File

@@ -1327,14 +1327,15 @@ static void pl011_stop_tx(struct uart_port *port)
pl011_dma_tx_stop(uap);
}
static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq);
static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq);
/* Start TX with programmed I/O only (no DMA) */
static void pl011_start_tx_pio(struct uart_amba_port *uap)
{
uap->im |= UART011_TXIM;
pl011_write(uap->im, uap, REG_IMSC);
pl011_tx_chars(uap, false);
if (pl011_tx_chars(uap, false)) {
uap->im |= UART011_TXIM;
pl011_write(uap->im, uap, REG_IMSC);
}
}
static void pl011_start_tx(struct uart_port *port)
@@ -1414,25 +1415,26 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
return true;
}
static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq)
/* Returns true if tx interrupts have to be (kept) enabled */
static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq)
{
struct circ_buf *xmit = &uap->port.state->xmit;
int count = uap->fifosize >> 1;
if (uap->port.x_char) {
if (!pl011_tx_char(uap, uap->port.x_char, from_irq))
return;
return true;
uap->port.x_char = 0;
--count;
}
if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) {
pl011_stop_tx(&uap->port);
return;
return false;
}
/* If we are using DMA mode, try to send some characters. */
if (pl011_dma_tx_irq(uap))
return;
return true;
do {
if (likely(from_irq) && count-- == 0)
@@ -1447,8 +1449,11 @@ static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq)
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&uap->port);
if (uart_circ_empty(xmit))
if (uart_circ_empty(xmit)) {
pl011_stop_tx(&uap->port);
return false;
}
return true;
}
static void pl011_modem_status(struct uart_amba_port *uap)
@@ -2470,19 +2475,34 @@ static int __init pl011_early_console_setup(struct earlycon_device *device,
if (!device->port.membase)
return -ENODEV;
/* On QDF2400 SOCs affected by Erratum 44, the "qdf2400_e44" must
* also be specified, e.g. "earlycon=pl011,<address>,qdf2400_e44".
*/
if (!strcmp(device->options, "qdf2400_e44"))
device->con->write = qdf2400_e44_early_write;
else
device->con->write = pl011_early_write;
device->con->write = pl011_early_write;
return 0;
}
OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup);
OF_EARLYCON_DECLARE(pl011, "arm,sbsa-uart", pl011_early_console_setup);
EARLYCON_DECLARE(qdf2400_e44, pl011_early_console_setup);
/*
* On Qualcomm Datacenter Technologies QDF2400 SOCs affected by
* Erratum 44, traditional earlycon can be enabled by specifying
* "earlycon=qdf2400_e44,<address>". Any options are ignored.
*
* Alternatively, you can just specify "earlycon", and the early console
* will be enabled with the information from the SPCR table. In this
* case, the SPCR code will detect the need for the E44 work-around,
* and set the console name to "qdf2400_e44".
*/
static int __init
qdf2400_e44_early_console_setup(struct earlycon_device *device,
const char *opt)
{
if (!device->port.membase)
return -ENODEV;
device->con->write = qdf2400_e44_early_write;
return 0;
}
EARLYCON_DECLARE(qdf2400_e44, qdf2400_e44_early_console_setup);
#else
#define AMBA_CONSOLE NULL

View File

@@ -38,7 +38,6 @@
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/atmel_pdc.h>
#include <linux/atmel_serial.h>
#include <linux/uaccess.h>
#include <linux/platform_data/atmel.h>
#include <linux/timer.h>
@@ -71,6 +70,7 @@
#include <linux/serial_core.h>
#include "serial_mctrl_gpio.h"
#include "atmel_serial.h"
static void atmel_start_rx(struct uart_port *port);
static void atmel_stop_rx(struct uart_port *port);
@@ -119,8 +119,9 @@ struct atmel_uart_char {
/*
* at91: 6 USARTs and one DBGU port (SAM9260)
* avr32: 4
* samx7: 3 USARTs and 5 UARTs
*/
#define ATMEL_MAX_UART 7
#define ATMEL_MAX_UART 8
/*
* We wrap our port structure around the generic uart_port.
@@ -175,6 +176,7 @@ struct atmel_uart_port {
unsigned int pending_status;
spinlock_t lock_suspended;
#ifdef CONFIG_PM
struct {
u32 cr;
u32 mr;
@@ -185,6 +187,7 @@ struct atmel_uart_port {
u32 fmr;
u32 fimr;
} cache;
#endif
int (*prepare_rx)(struct uart_port *port);
int (*prepare_tx)(struct uart_port *port);

View File

@@ -0,0 +1,169 @@
/*
* include/linux/atmel_serial.h
*
* Copyright (C) 2005 Ivan Kokshaysky
* Copyright (C) SAN People
*
* USART registers.
* Based on AT91RM9200 datasheet revision E.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef ATMEL_SERIAL_H
#define ATMEL_SERIAL_H
#define ATMEL_US_CR 0x00 /* Control Register */
#define ATMEL_US_RSTRX BIT(2) /* Reset Receiver */
#define ATMEL_US_RSTTX BIT(3) /* Reset Transmitter */
#define ATMEL_US_RXEN BIT(4) /* Receiver Enable */
#define ATMEL_US_RXDIS BIT(5) /* Receiver Disable */
#define ATMEL_US_TXEN BIT(6) /* Transmitter Enable */
#define ATMEL_US_TXDIS BIT(7) /* Transmitter Disable */
#define ATMEL_US_RSTSTA BIT(8) /* Reset Status Bits */
#define ATMEL_US_STTBRK BIT(9) /* Start Break */
#define ATMEL_US_STPBRK BIT(10) /* Stop Break */
#define ATMEL_US_STTTO BIT(11) /* Start Time-out */
#define ATMEL_US_SENDA BIT(12) /* Send Address */
#define ATMEL_US_RSTIT BIT(13) /* Reset Iterations */
#define ATMEL_US_RSTNACK BIT(14) /* Reset Non Acknowledge */
#define ATMEL_US_RETTO BIT(15) /* Rearm Time-out */
#define ATMEL_US_DTREN BIT(16) /* Data Terminal Ready Enable */
#define ATMEL_US_DTRDIS BIT(17) /* Data Terminal Ready Disable */
#define ATMEL_US_RTSEN BIT(18) /* Request To Send Enable */
#define ATMEL_US_RTSDIS BIT(19) /* Request To Send Disable */
#define ATMEL_US_TXFCLR BIT(24) /* Transmit FIFO Clear */
#define ATMEL_US_RXFCLR BIT(25) /* Receive FIFO Clear */
#define ATMEL_US_TXFLCLR BIT(26) /* Transmit FIFO Lock Clear */
#define ATMEL_US_FIFOEN BIT(30) /* FIFO enable */
#define ATMEL_US_FIFODIS BIT(31) /* FIFO disable */
#define ATMEL_US_MR 0x04 /* Mode Register */
#define ATMEL_US_USMODE GENMASK(3, 0) /* Mode of the USART */
#define ATMEL_US_USMODE_NORMAL 0
#define ATMEL_US_USMODE_RS485 1
#define ATMEL_US_USMODE_HWHS 2
#define ATMEL_US_USMODE_MODEM 3
#define ATMEL_US_USMODE_ISO7816_T0 4
#define ATMEL_US_USMODE_ISO7816_T1 6
#define ATMEL_US_USMODE_IRDA 8
#define ATMEL_US_USCLKS GENMASK(5, 4) /* Clock Selection */
#define ATMEL_US_USCLKS_MCK (0 << 4)
#define ATMEL_US_USCLKS_MCK_DIV8 (1 << 4)
#define ATMEL_US_USCLKS_SCK (3 << 4)
#define ATMEL_US_CHRL GENMASK(7, 6) /* Character Length */
#define ATMEL_US_CHRL_5 (0 << 6)
#define ATMEL_US_CHRL_6 (1 << 6)
#define ATMEL_US_CHRL_7 (2 << 6)
#define ATMEL_US_CHRL_8 (3 << 6)
#define ATMEL_US_SYNC BIT(8) /* Synchronous Mode Select */
#define ATMEL_US_PAR GENMASK(11, 9) /* Parity Type */
#define ATMEL_US_PAR_EVEN (0 << 9)
#define ATMEL_US_PAR_ODD (1 << 9)
#define ATMEL_US_PAR_SPACE (2 << 9)
#define ATMEL_US_PAR_MARK (3 << 9)
#define ATMEL_US_PAR_NONE (4 << 9)
#define ATMEL_US_PAR_MULTI_DROP (6 << 9)
#define ATMEL_US_NBSTOP GENMASK(13, 12) /* Number of Stop Bits */
#define ATMEL_US_NBSTOP_1 (0 << 12)
#define ATMEL_US_NBSTOP_1_5 (1 << 12)
#define ATMEL_US_NBSTOP_2 (2 << 12)
#define ATMEL_US_CHMODE GENMASK(15, 14) /* Channel Mode */
#define ATMEL_US_CHMODE_NORMAL (0 << 14)
#define ATMEL_US_CHMODE_ECHO (1 << 14)
#define ATMEL_US_CHMODE_LOC_LOOP (2 << 14)
#define ATMEL_US_CHMODE_REM_LOOP (3 << 14)
#define ATMEL_US_MSBF BIT(16) /* Bit Order */
#define ATMEL_US_MODE9 BIT(17) /* 9-bit Character Length */
#define ATMEL_US_CLKO BIT(18) /* Clock Output Select */
#define ATMEL_US_OVER BIT(19) /* Oversampling Mode */
#define ATMEL_US_INACK BIT(20) /* Inhibit Non Acknowledge */
#define ATMEL_US_DSNACK BIT(21) /* Disable Successive NACK */
#define ATMEL_US_MAX_ITER GENMASK(26, 24) /* Max Iterations */
#define ATMEL_US_FILTER BIT(28) /* Infrared Receive Line Filter */
#define ATMEL_US_IER 0x08 /* Interrupt Enable Register */
#define ATMEL_US_RXRDY BIT(0) /* Receiver Ready */
#define ATMEL_US_TXRDY BIT(1) /* Transmitter Ready */
#define ATMEL_US_RXBRK BIT(2) /* Break Received / End of Break */
#define ATMEL_US_ENDRX BIT(3) /* End of Receiver Transfer */
#define ATMEL_US_ENDTX BIT(4) /* End of Transmitter Transfer */
#define ATMEL_US_OVRE BIT(5) /* Overrun Error */
#define ATMEL_US_FRAME BIT(6) /* Framing Error */
#define ATMEL_US_PARE BIT(7) /* Parity Error */
#define ATMEL_US_TIMEOUT BIT(8) /* Receiver Time-out */
#define ATMEL_US_TXEMPTY BIT(9) /* Transmitter Empty */
#define ATMEL_US_ITERATION BIT(10) /* Max number of Repetitions Reached */
#define ATMEL_US_TXBUFE BIT(11) /* Transmission Buffer Empty */
#define ATMEL_US_RXBUFF BIT(12) /* Reception Buffer Full */
#define ATMEL_US_NACK BIT(13) /* Non Acknowledge */
#define ATMEL_US_RIIC BIT(16) /* Ring Indicator Input Change */
#define ATMEL_US_DSRIC BIT(17) /* Data Set Ready Input Change */
#define ATMEL_US_DCDIC BIT(18) /* Data Carrier Detect Input Change */
#define ATMEL_US_CTSIC BIT(19) /* Clear to Send Input Change */
#define ATMEL_US_RI BIT(20) /* RI */
#define ATMEL_US_DSR BIT(21) /* DSR */
#define ATMEL_US_DCD BIT(22) /* DCD */
#define ATMEL_US_CTS BIT(23) /* CTS */
#define ATMEL_US_IDR 0x0c /* Interrupt Disable Register */
#define ATMEL_US_IMR 0x10 /* Interrupt Mask Register */
#define ATMEL_US_CSR 0x14 /* Channel Status Register */
#define ATMEL_US_RHR 0x18 /* Receiver Holding Register */
#define ATMEL_US_THR 0x1c /* Transmitter Holding Register */
#define ATMEL_US_SYNH BIT(15) /* Transmit/Receive Sync */
#define ATMEL_US_BRGR 0x20 /* Baud Rate Generator Register */
#define ATMEL_US_CD GENMASK(15, 0) /* Clock Divider */
#define ATMEL_US_FP_OFFSET 16 /* Fractional Part */
#define ATMEL_US_FP_MASK 0x7
#define ATMEL_US_RTOR 0x24 /* Receiver Time-out Register for USART */
#define ATMEL_UA_RTOR 0x28 /* Receiver Time-out Register for UART */
#define ATMEL_US_TO GENMASK(15, 0) /* Time-out Value */
#define ATMEL_US_TTGR 0x28 /* Transmitter Timeguard Register */
#define ATMEL_US_TG GENMASK(7, 0) /* Timeguard Value */
#define ATMEL_US_FIDI 0x40 /* FI DI Ratio Register */
#define ATMEL_US_NER 0x44 /* Number of Errors Register */
#define ATMEL_US_IF 0x4c /* IrDA Filter Register */
#define ATMEL_US_CMPR 0x90 /* Comparaison Register */
#define ATMEL_US_FMR 0xa0 /* FIFO Mode Register */
#define ATMEL_US_TXRDYM(data) (((data) & 0x3) << 0) /* TX Ready Mode */
#define ATMEL_US_RXRDYM(data) (((data) & 0x3) << 4) /* RX Ready Mode */
#define ATMEL_US_ONE_DATA 0x0
#define ATMEL_US_TWO_DATA 0x1
#define ATMEL_US_FOUR_DATA 0x2
#define ATMEL_US_FRTSC BIT(7) /* FIFO RTS pin Control */
#define ATMEL_US_TXFTHRES(thr) (((thr) & 0x3f) << 8) /* TX FIFO Threshold */
#define ATMEL_US_RXFTHRES(thr) (((thr) & 0x3f) << 16) /* RX FIFO Threshold */
#define ATMEL_US_RXFTHRES2(thr) (((thr) & 0x3f) << 24) /* RX FIFO Threshold2 */
#define ATMEL_US_FLR 0xa4 /* FIFO Level Register */
#define ATMEL_US_TXFL(reg) (((reg) >> 0) & 0x3f) /* TX FIFO Level */
#define ATMEL_US_RXFL(reg) (((reg) >> 16) & 0x3f) /* RX FIFO Level */
#define ATMEL_US_FIER 0xa8 /* FIFO Interrupt Enable Register */
#define ATMEL_US_FIDR 0xac /* FIFO Interrupt Disable Register */
#define ATMEL_US_FIMR 0xb0 /* FIFO Interrupt Mask Register */
#define ATMEL_US_FESR 0xb4 /* FIFO Event Status Register */
#define ATMEL_US_TXFEF BIT(0) /* Transmit FIFO Empty Flag */
#define ATMEL_US_TXFFF BIT(1) /* Transmit FIFO Full Flag */
#define ATMEL_US_TXFTHF BIT(2) /* Transmit FIFO Threshold Flag */
#define ATMEL_US_RXFEF BIT(3) /* Receive FIFO Empty Flag */
#define ATMEL_US_RXFFF BIT(4) /* Receive FIFO Full Flag */
#define ATMEL_US_RXFTHF BIT(5) /* Receive FIFO Threshold Flag */
#define ATMEL_US_TXFPTEF BIT(6) /* Transmit FIFO Pointer Error Flag */
#define ATMEL_US_RXFPTEF BIT(7) /* Receive FIFO Pointer Error Flag */
#define ATMEL_US_TXFLOCK BIT(8) /* Transmit FIFO Lock (FESR only) */
#define ATMEL_US_RXFTHF2 BIT(9) /* Receive FIFO Threshold Flag 2 */
#define ATMEL_US_NAME 0xf0 /* Ip Name */
#define ATMEL_US_VERSION 0xfc /* Ip Version */
#endif

View File

@@ -1705,6 +1705,13 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count)
{
struct lpuart_port *sport = lpuart_ports[co->index];
unsigned char old_cr2, cr2;
unsigned long flags;
int locked = 1;
if (sport->port.sysrq || oops_in_progress)
locked = spin_trylock_irqsave(&sport->port.lock, flags);
else
spin_lock_irqsave(&sport->port.lock, flags);
/* first save CR2 and then disable interrupts */
cr2 = old_cr2 = readb(sport->port.membase + UARTCR2);
@@ -1719,6 +1726,9 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count)
barrier();
writeb(old_cr2, sport->port.membase + UARTCR2);
if (locked)
spin_unlock_irqrestore(&sport->port.lock, flags);
}
static void
@@ -1726,6 +1736,13 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count)
{
struct lpuart_port *sport = lpuart_ports[co->index];
unsigned long old_cr, cr;
unsigned long flags;
int locked = 1;
if (sport->port.sysrq || oops_in_progress)
locked = spin_trylock_irqsave(&sport->port.lock, flags);
else
spin_lock_irqsave(&sport->port.lock, flags);
/* first save CR2 and then disable interrupts */
cr = old_cr = lpuart32_read(sport->port.membase + UARTCTRL);
@@ -1740,6 +1757,9 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count)
barrier();
lpuart32_write(old_cr, sport->port.membase + UARTCTRL);
if (locked)
spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*

View File

@@ -719,6 +719,27 @@ out:
return IRQ_HANDLED;
}
static void imx_disable_rx_int(struct imx_port *sport)
{
unsigned long temp;
sport->dma_is_rxing = 1;
/* disable the receiver ready and aging timer interrupts */
temp = readl(sport->port.membase + UCR1);
temp &= ~(UCR1_RRDYEN);
writel(temp, sport->port.membase + UCR1);
temp = readl(sport->port.membase + UCR2);
temp &= ~(UCR2_ATEN);
writel(temp, sport->port.membase + UCR2);
/* disable the rx errors interrupts */
temp = readl(sport->port.membase + UCR4);
temp &= ~UCR4_OREN;
writel(temp, sport->port.membase + UCR4);
}
static void clear_rx_errors(struct imx_port *sport);
static int start_rx_dma(struct imx_port *sport);
/*
@@ -734,21 +755,8 @@ static void imx_dma_rxint(struct imx_port *sport)
temp = readl(sport->port.membase + USR2);
if ((temp & USR2_RDR) && !sport->dma_is_rxing) {
sport->dma_is_rxing = 1;
/* disable the receiver ready and aging timer interrupts */
temp = readl(sport->port.membase + UCR1);
temp &= ~(UCR1_RRDYEN);
writel(temp, sport->port.membase + UCR1);
temp = readl(sport->port.membase + UCR2);
temp &= ~(UCR2_ATEN);
writel(temp, sport->port.membase + UCR2);
/* disable the rx errors interrupts */
temp = readl(sport->port.membase + UCR4);
temp &= ~UCR4_OREN;
writel(temp, sport->port.membase + UCR4);
imx_disable_rx_int(sport);
/* tell the DMA to receive the data. */
start_rx_dma(sport);
@@ -1317,19 +1325,10 @@ static int imx_startup(struct uart_port *port)
if (!is_imx1_uart(sport)) {
temp = readl(sport->port.membase + UCR3);
/*
* The effect of RI and DCD differs depending on the UFCR_DCEDTE
* bit. In DCE mode they control the outputs, in DTE mode they
* enable the respective irqs. At least the DCD irq cannot be
* cleared on i.MX25 at least, so it's not usable and must be
* disabled. I don't have test hardware to check if RI has the
* same problem but I consider this likely so it's disabled for
* now, too.
*/
temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP |
UCR3_DTRDEN | UCR3_RI | UCR3_DCD;
temp |= UCR3_DTRDEN | UCR3_RI | UCR3_DCD;
if (sport->dte_mode)
/* disable broken interrupts */
temp &= ~(UCR3_RI | UCR3_DCD);
writel(temp, sport->port.membase + UCR3);
@@ -1339,6 +1338,33 @@ static int imx_startup(struct uart_port *port)
* Enable modem status interrupts
*/
imx_enable_ms(&sport->port);
/*
* If the serial port is opened for reading start RX DMA immediately
* instead of waiting for RX FIFO interrupts. In our iMX53 the average
* delay for the first reception dropped from approximately 35000
* microseconds to 1000 microseconds.
*/
if (sport->dma_is_enabled) {
struct tty_struct *tty = sport->port.state->port.tty;
struct tty_file_private *file_priv;
int readcnt = 0;
spin_lock(&tty->files_lock);
if (!list_empty(&tty->tty_files))
list_for_each_entry(file_priv, &tty->tty_files, list)
if (!(file_priv->file->f_flags & O_WRONLY))
readcnt++;
spin_unlock(&tty->files_lock);
if (readcnt > 0) {
imx_disable_rx_int(sport);
start_rx_dma(sport);
}
}
spin_unlock_irqrestore(&sport->port.lock, flags);
return 0;
@@ -1584,8 +1610,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
ufcr = readl(sport->port.membase + UFCR);
ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div);
if (sport->dte_mode)
ufcr |= UFCR_DCEDTE;
writel(ufcr, sport->port.membase + UFCR);
writel(num, sport->port.membase + UBIR);
@@ -2153,6 +2177,27 @@ static int serial_imx_probe(struct platform_device *pdev)
UCR1_TXMPTYEN | UCR1_RTSDEN);
writel_relaxed(reg, sport->port.membase + UCR1);
if (!is_imx1_uart(sport) && sport->dte_mode) {
/*
* The DCEDTE bit changes the direction of DSR, DCD, DTR and RI
* and influences if UCR3_RI and UCR3_DCD changes the level of RI
* and DCD (when they are outputs) or enables the respective
* irqs. So set this bit early, i.e. before requesting irqs.
*/
writel(UFCR_DCEDTE, sport->port.membase + UFCR);
/*
* Disable UCR3_RI and UCR3_DCD irqs. They are also not
* enabled later because they cannot be cleared
* (confirmed on i.MX25) which makes them unusable.
*/
writel(IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP | UCR3_DSR,
sport->port.membase + UCR3);
} else {
writel(0, sport->port.membase + UFCR);
}
clk_disable_unprepare(sport->clk_ipg);
/*

View File

@@ -1770,7 +1770,8 @@ static int serial_omap_probe(struct platform_device *pdev)
return 0;
err_add_port:
pm_runtime_put(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_qos_remove_request(&up->pm_qos_request);
device_init_wakeup(up->dev, false);
@@ -1783,9 +1784,13 @@ static int serial_omap_remove(struct platform_device *dev)
{
struct uart_omap_port *up = platform_get_drvdata(dev);
pm_runtime_get_sync(up->dev);
uart_remove_one_port(&serial_omap_reg, &up->port);
pm_runtime_dont_use_autosuspend(up->dev);
pm_runtime_put_sync(up->dev);
pm_runtime_disable(up->dev);
uart_remove_one_port(&serial_omap_reg, &up->port);
pm_qos_remove_request(&up->pm_qos_request);
device_init_wakeup(&dev->dev, false);

View File

@@ -859,7 +859,7 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
{
struct s3c24xx_uart_dma *dma = p->dma;
unsigned long flags;
int ret;
/* Default slave configuration parameters */
dma->rx_conf.direction = DMA_DEV_TO_MEM;
@@ -884,8 +884,8 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
dma->tx_chan = dma_request_chan(p->port.dev, "tx");
if (IS_ERR(dma->tx_chan)) {
dma_release_channel(dma->rx_chan);
return PTR_ERR(dma->tx_chan);
ret = PTR_ERR(dma->tx_chan);
goto err_release_rx;
}
dmaengine_slave_config(dma->tx_chan, &dma->tx_conf);
@@ -894,26 +894,38 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
dma->rx_size = PAGE_SIZE;
dma->rx_buf = kmalloc(dma->rx_size, GFP_KERNEL);
if (!dma->rx_buf) {
dma_release_channel(dma->rx_chan);
dma_release_channel(dma->tx_chan);
return -ENOMEM;
ret = -ENOMEM;
goto err_release_tx;
}
dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf,
dma->rx_addr = dma_map_single(p->port.dev, dma->rx_buf,
dma->rx_size, DMA_FROM_DEVICE);
spin_lock_irqsave(&p->port.lock, flags);
if (dma_mapping_error(p->port.dev, dma->rx_addr)) {
ret = -EIO;
goto err_free_rx;
}
/* TX buffer */
dma->tx_addr = dma_map_single(dma->tx_chan->device->dev,
p->port.state->xmit.buf,
dma->tx_addr = dma_map_single(p->port.dev, p->port.state->xmit.buf,
UART_XMIT_SIZE, DMA_TO_DEVICE);
spin_unlock_irqrestore(&p->port.lock, flags);
if (dma_mapping_error(p->port.dev, dma->tx_addr)) {
ret = -EIO;
goto err_unmap_rx;
}
return 0;
err_unmap_rx:
dma_unmap_single(p->port.dev, dma->rx_addr, dma->rx_size,
DMA_FROM_DEVICE);
err_free_rx:
kfree(dma->rx_buf);
err_release_tx:
dma_release_channel(dma->tx_chan);
err_release_rx:
dma_release_channel(dma->rx_chan);
return ret;
}
static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
@@ -922,7 +934,7 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
if (dma->rx_chan) {
dmaengine_terminate_all(dma->rx_chan);
dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr,
dma_unmap_single(p->port.dev, dma->rx_addr,
dma->rx_size, DMA_FROM_DEVICE);
kfree(dma->rx_buf);
dma_release_channel(dma->rx_chan);
@@ -931,7 +943,7 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
if (dma->tx_chan) {
dmaengine_terminate_all(dma->tx_chan);
dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr,
dma_unmap_single(p->port.dev, dma->tx_addr,
UART_XMIT_SIZE, DMA_TO_DEVICE);
dma_release_channel(dma->tx_chan);
dma->tx_chan = NULL;

View File

@@ -41,7 +41,7 @@
#include <linux/tty_flip.h>
#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/refcount.h>
#include <asm/io.h>
#include <asm/war.h>
@@ -103,7 +103,7 @@ struct sbd_port {
struct sbd_duart {
struct sbd_port sport[2];
unsigned long mapctrl;
atomic_t map_guard;
refcount_t map_guard;
};
#define to_sport(uport) container_of(uport, struct sbd_port, port)
@@ -654,15 +654,13 @@ static void sbd_release_port(struct uart_port *uport)
{
struct sbd_port *sport = to_sport(uport);
struct sbd_duart *duart = sport->duart;
int map_guard;
iounmap(sport->memctrl);
sport->memctrl = NULL;
iounmap(uport->membase);
uport->membase = NULL;
map_guard = atomic_add_return(-1, &duart->map_guard);
if (!map_guard)
if(refcount_dec_and_test(&duart->map_guard))
release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING);
release_mem_region(uport->mapbase, DUART_CHANREG_SPACING);
}
@@ -698,7 +696,6 @@ static int sbd_request_port(struct uart_port *uport)
{
const char *err = KERN_ERR "sbd: Unable to reserve MMIO resource\n";
struct sbd_duart *duart = to_sport(uport)->duart;
int map_guard;
int ret = 0;
if (!request_mem_region(uport->mapbase, DUART_CHANREG_SPACING,
@@ -706,11 +703,11 @@ static int sbd_request_port(struct uart_port *uport)
printk(err);
return -EBUSY;
}
map_guard = atomic_add_return(1, &duart->map_guard);
if (map_guard == 1) {
refcount_inc(&duart->map_guard);
if (refcount_read(&duart->map_guard) == 1) {
if (!request_mem_region(duart->mapctrl, DUART_CHANREG_SPACING,
"sb1250-duart")) {
atomic_add(-1, &duart->map_guard);
refcount_dec(&duart->map_guard);
printk(err);
ret = -EBUSY;
}
@@ -718,8 +715,7 @@ static int sbd_request_port(struct uart_port *uport)
if (!ret) {
ret = sbd_map_port(uport);
if (ret) {
map_guard = atomic_add_return(-1, &duart->map_guard);
if (!map_guard)
if (refcount_dec_and_test(&duart->map_guard))
release_mem_region(duart->mapctrl,
DUART_CHANREG_SPACING);
}

View File

@@ -2117,9 +2117,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
for (tries = 3; !ops->tx_empty(uport) && tries; tries--)
msleep(10);
if (!tries)
dev_err(uport->dev, "%s%d: Unable to drain transmitter\n",
drv->dev_name,
drv->tty_driver->name_base + uport->line);
dev_err(uport->dev, "%s: Unable to drain transmitter\n",
uport->name);
ops->shutdown(uport);
}
@@ -2248,11 +2247,10 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
break;
}
printk(KERN_INFO "%s%s%s%d at %s (irq = %d, base_baud = %d) is a %s\n",
pr_info("%s%s%s at %s (irq = %d, base_baud = %d) is a %s\n",
port->dev ? dev_name(port->dev) : "",
port->dev ? ": " : "",
drv->dev_name,
drv->tty_driver->name_base + port->line,
port->name,
address, port->irq, port->uartclk / 16, uart_type(port));
}
@@ -2331,9 +2329,6 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)
int flow = 'n';
int ret = 0;
if (!state)
return -1;
tport = &state->port;
mutex_lock(&tport->mutex);
@@ -2368,13 +2363,12 @@ static int uart_poll_get_char(struct tty_driver *driver, int line)
struct uart_port *port;
int ret = -1;
if (state) {
port = uart_port_ref(state);
if (port) {
ret = port->ops->poll_get_char(port);
uart_port_deref(port);
}
port = uart_port_ref(state);
if (port) {
ret = port->ops->poll_get_char(port);
uart_port_deref(port);
}
return ret;
}
@@ -2384,9 +2378,6 @@ static void uart_poll_put_char(struct tty_driver *driver, int line, char ch)
struct uart_state *state = drv->state + line;
struct uart_port *port;
if (!state)
return;
port = uart_port_ref(state);
if (!port)
return;
@@ -2751,6 +2742,12 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
state->pm_state = UART_PM_STATE_UNDEFINED;
uport->cons = drv->cons;
uport->minor = drv->tty_driver->minor_start + uport->line;
uport->name = kasprintf(GFP_KERNEL, "%s%d", drv->dev_name,
drv->tty_driver->name_base + uport->line);
if (!uport->name) {
ret = -ENOMEM;
goto out;
}
/*
* If this port is a console, then the spinlock is already
@@ -2868,6 +2865,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
if (uport->type != PORT_UNKNOWN && uport->ops->release_port)
uport->ops->release_port(uport);
kfree(uport->tty_groups);
kfree(uport->name);
/*
* Indicate that there isn't a port here anymore.

View File

@@ -683,24 +683,37 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
}
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
u16 data = serial_port_in(port, SCPDR);
u16 ctrl = serial_port_in(port, SCPCR);
/* Enable RXD and TXD pin functions */
ctrl &= ~(SCPCR_RXDC | SCPCR_TXDC);
if (to_sci_port(port)->has_rtscts) {
/* RTS# is output, driven 1 */
ctrl |= SCPCR_RTSC;
serial_port_out(port, SCPDR,
serial_port_in(port, SCPDR) | SCPDR_RTSD);
/* RTS# is output, active low, unless autorts */
if (!(port->mctrl & TIOCM_RTS)) {
ctrl |= SCPCR_RTSC;
data |= SCPDR_RTSD;
} else if (!s->autorts) {
ctrl |= SCPCR_RTSC;
data &= ~SCPDR_RTSD;
} else {
/* Enable RTS# pin function */
ctrl &= ~SCPCR_RTSC;
}
/* Enable CTS# pin function */
ctrl &= ~SCPCR_CTSC;
}
serial_port_out(port, SCPDR, data);
serial_port_out(port, SCPCR, ctrl);
} else if (sci_getreg(port, SCSPTR)->size) {
u16 status = serial_port_in(port, SCSPTR);
/* RTS# is output, driven 1 */
status |= SCSPTR_RTSIO | SCSPTR_RTSDT;
/* RTS# is always output; and active low, unless autorts */
status |= SCSPTR_RTSIO;
if (!(port->mctrl & TIOCM_RTS))
status |= SCSPTR_RTSDT;
else if (!s->autorts)
status &= ~SCSPTR_RTSDT;
/* CTS# and SCK are inputs */
status &= ~(SCSPTR_CTSIO | SCSPTR_SCKIO);
serial_port_out(port, SCSPTR, status);
@@ -1985,12 +1998,14 @@ static int sci_startup(struct uart_port *port)
dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
ret = sci_request_irq(s);
if (unlikely(ret < 0))
return ret;
sci_request_dma(port);
ret = sci_request_irq(s);
if (unlikely(ret < 0)) {
sci_free_dma(port);
return ret;
}
return 0;
}
@@ -2021,8 +2036,8 @@ static void sci_shutdown(struct uart_port *port)
}
#endif
sci_free_dma(port);
sci_free_irq(s);
sci_free_dma(port);
}
static int sci_sck_calc(struct sci_port *s, unsigned int bps,
@@ -2157,10 +2172,6 @@ static void sci_reset(struct uart_port *port)
unsigned int status;
struct sci_port *s = to_sci_port(port);
do {
status = serial_port_in(port, SCxSR);
} while (!(status & SCxSR_TEND(port)));
serial_port_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
reg = sci_getreg(port, SCFCR);
@@ -2374,6 +2385,10 @@ done:
serial_port_out(port, SCFCR, ctrl);
}
if (port->flags & UPF_HARD_FLOW) {
/* Refresh (Auto) RTS */
sci_set_mctrl(port, port->mctrl);
}
scr_val |= SCSCR_RE | SCSCR_TE |
(s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0));

View File

@@ -36,7 +36,7 @@
#define SPRD_FIFO_SIZE 128
#define SPRD_DEF_RATE 26000000
#define SPRD_BAUD_IO_LIMIT 3000000
#define SPRD_TIMEOUT 256
#define SPRD_TIMEOUT 256000
/* the offset of serial registers and BITs for them */
/* data registers */

View File

@@ -887,13 +887,12 @@ static void asc_console_write(struct console *co, const char *s, unsigned count)
int locked = 1;
u32 intenable;
local_irq_save(flags);
if (port->sysrq)
locked = 0; /* asc_interrupt has already claimed the lock */
else if (oops_in_progress)
locked = spin_trylock(&port->lock);
locked = spin_trylock_irqsave(&port->lock, flags);
else
spin_lock(&port->lock);
spin_lock_irqsave(&port->lock, flags);
/*
* Disable interrupts so we don't get the IRQ line bouncing
@@ -911,14 +910,13 @@ static void asc_console_write(struct console *co, const char *s, unsigned count)
asc_out(port, ASC_INTEN, intenable);
if (locked)
spin_unlock(&port->lock);
local_irq_restore(flags);
spin_unlock_irqrestore(&port->lock, flags);
}
static int asc_console_setup(struct console *co, char *options)
{
struct asc_port *ascport;
int baud = 9600;
int baud = 115200;
int bits = 8;
int parity = 'n';
int flow = 'n';

View File

@@ -28,7 +28,7 @@
#define ULITE_NAME "ttyUL"
#define ULITE_MAJOR 204
#define ULITE_MINOR 187
#define ULITE_NR_UARTS 16
#define ULITE_NR_UARTS CONFIG_SERIAL_UARTLITE_NR_UARTS
/* ---------------------------------------------------------------------
* Register definitions

View File

@@ -30,6 +30,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#define CDNS_UART_TTY_NAME "ttyPS"
#define CDNS_UART_NAME "xuartps"
@@ -176,6 +177,7 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
#define CDNS_UART_BDIV_MIN 4
#define CDNS_UART_BDIV_MAX 255
#define CDNS_UART_CD_MAX 65535
#define UART_AUTOSUSPEND_TIMEOUT 3000
/**
* struct cdns_uart - device data
@@ -1065,16 +1067,13 @@ static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c)
static void cdns_uart_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
struct cdns_uart *cdns_uart = port->private_data;
switch (state) {
case UART_PM_STATE_OFF:
clk_disable(cdns_uart->uartclk);
clk_disable(cdns_uart->pclk);
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
break;
default:
clk_enable(cdns_uart->pclk);
clk_enable(cdns_uart->uartclk);
pm_runtime_get_sync(port->dev);
break;
}
}
@@ -1353,12 +1352,7 @@ static int cdns_uart_suspend(struct device *device)
* the suspend.
*/
uart_suspend_port(&cdns_uart_uart_driver, port);
if (console_suspend_enabled && !may_wake) {
struct cdns_uart *cdns_uart = port->private_data;
clk_disable(cdns_uart->uartclk);
clk_disable(cdns_uart->pclk);
} else {
if (!(console_suspend_enabled && !may_wake)) {
unsigned long flags = 0;
spin_lock_irqsave(&port->lock, flags);
@@ -1423,6 +1417,8 @@ static int cdns_uart_resume(struct device *device)
ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN;
writel(ctrl_reg, port->membase + CDNS_UART_CR);
clk_disable(cdns_uart->uartclk);
clk_disable(cdns_uart->pclk);
spin_unlock_irqrestore(&port->lock, flags);
} else {
spin_lock_irqsave(&port->lock, flags);
@@ -1436,9 +1432,33 @@ static int cdns_uart_resume(struct device *device)
return uart_resume_port(&cdns_uart_uart_driver, port);
}
#endif /* ! CONFIG_PM_SLEEP */
static int __maybe_unused cdns_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct uart_port *port = platform_get_drvdata(pdev);
struct cdns_uart *cdns_uart = port->private_data;
static SIMPLE_DEV_PM_OPS(cdns_uart_dev_pm_ops, cdns_uart_suspend,
cdns_uart_resume);
clk_disable(cdns_uart->uartclk);
clk_disable(cdns_uart->pclk);
return 0;
};
static int __maybe_unused cdns_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct uart_port *port = platform_get_drvdata(pdev);
struct cdns_uart *cdns_uart = port->private_data;
clk_enable(cdns_uart->pclk);
clk_enable(cdns_uart->uartclk);
return 0;
};
static const struct dev_pm_ops cdns_uart_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(cdns_uart_suspend, cdns_uart_resume)
SET_RUNTIME_PM_OPS(cdns_runtime_suspend,
cdns_runtime_resume, NULL)
};
static const struct cdns_platform_data zynqmp_uart_def = {
.quirks = CDNS_UART_RXBS_SUPPORT, };
@@ -1501,12 +1521,12 @@ static int cdns_uart_probe(struct platform_device *pdev)
return PTR_ERR(cdns_uart_data->uartclk);
}
rc = clk_prepare(cdns_uart_data->pclk);
rc = clk_prepare_enable(cdns_uart_data->pclk);
if (rc) {
dev_err(&pdev->dev, "Unable to enable pclk clock.\n");
return rc;
}
rc = clk_prepare(cdns_uart_data->uartclk);
rc = clk_prepare_enable(cdns_uart_data->uartclk);
if (rc) {
dev_err(&pdev->dev, "Unable to enable device clock.\n");
goto err_out_clk_dis_pclk;
@@ -1558,6 +1578,11 @@ static int cdns_uart_probe(struct platform_device *pdev)
cdns_uart_data->port = port;
platform_set_drvdata(pdev, port);
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);
rc = uart_add_one_port(&cdns_uart_uart_driver, port);
if (rc) {
dev_err(&pdev->dev,
@@ -1573,9 +1598,12 @@ err_out_notif_unreg:
&cdns_uart_data->clk_rate_change_nb);
#endif
err_out_clk_disable:
clk_unprepare(cdns_uart_data->uartclk);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
clk_disable_unprepare(cdns_uart_data->uartclk);
err_out_clk_dis_pclk:
clk_unprepare(cdns_uart_data->pclk);
clk_disable_unprepare(cdns_uart_data->pclk);
return rc;
}
@@ -1599,8 +1627,11 @@ static int cdns_uart_remove(struct platform_device *pdev)
#endif
rc = uart_remove_one_port(&cdns_uart_uart_driver, port);
port->mapbase = 0;
clk_unprepare(cdns_uart_data->uartclk);
clk_unprepare(cdns_uart_data->pclk);
clk_disable_unprepare(cdns_uart_data->uartclk);
clk_disable_unprepare(cdns_uart_data->pclk);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
return rc;
}