提交 a22e48cf 编写于 作者: L Linus Torvalds

Merge tag 'tty-4.18-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 driver update for 4.18-rc1.

  There's nothing major here, just lots of serial driver updates. Full
  details are in the shortlog, nothing anything specific to call out
  here.

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

* tag 'tty-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (55 commits)
  vt: Perform safe console erase only once
  serial: imx: disable UCR4_OREN on shutdown
  serial: imx: drop CTS/RTS handling from shutdown
  tty: fix typo in ASYNCB_FOURPORT comment
  serial: samsung: check DMA engine capabilities before using DMA mode
  tty: Fix data race in tty_insert_flip_string_fixed_flag
  tty: serial: msm_geni_serial: Fix TX infinite loop
  serial: 8250_dw: Fix runtime PM handling
  serial: 8250: omap: Fix idling of clocks for unused uarts
  tty: serial: drop ATH79 specific SoC symbols
  serial: 8250: Add missing rxtrig_bytes on Altera 16550 UART
  serial/aspeed-vuart: fix a couple mod_timer() calls
  serial: sh-sci: Use spin_{try}lock_irqsave instead of open coding version
  serial: 8250_of: Add IO space support
  tty/serial: atmel: use port->name as name in request_irq()
  serial: imx: dma_unmap_sg buffers on shutdown
  serial: imx: cleanup imx_uart_disable_dma()
  tty: serial: qcom_geni_serial: Add early console support
  tty: serial: qcom_geni_serial: Return IRQ_NONE for spurious interrupts
  tty: serial: qcom_geni_serial: Use iowrite32_rep to write to FIFO
  ...
......@@ -1020,6 +1020,12 @@
address. The serial port must already be setup
and configured. Options are not yet supported.
qcom_geni,<addr>
Start an early, polled-mode console on a Qualcomm
Generic Interface (GENI) based serial port at the
specified address. The serial port must already be
setup and configured. Options are not yet supported.
earlyprintk= [X86,SH,ARM,M68k,S390]
earlyprintk=vga
earlyprintk=efi
......
......@@ -163,7 +163,7 @@ i2c1: i2c@11100 {
};
uart0: serial@12000 {
compatible = "snps,dw-apb-uart";
compatible = "marvell,armada-38x-uart";
reg = <0x12000 0x100>;
reg-shift = <2>;
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
......@@ -173,7 +173,7 @@ uart0: serial@12000 {
};
uart1: serial@12100 {
compatible = "snps,dw-apb-uart";
compatible = "marvell,armada-38x-uart";
reg = <0x12100 0x100>;
reg-shift = <2>;
interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
......
......@@ -416,7 +416,7 @@ void ipwireless_network_packet_received(struct ipw_network *network,
struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw)
{
struct ipw_network *network =
kzalloc(sizeof(struct ipw_network), GFP_ATOMIC);
kzalloc(sizeof(struct ipw_network), GFP_KERNEL);
if (!network)
return NULL;
......
......@@ -2675,7 +2675,7 @@ static inline void muxnet_put(struct gsm_mux_net *mux_net)
kref_put(&mux_net->ref, net_free);
}
static int gsm_mux_net_start_xmit(struct sk_buff *skb,
static netdev_tx_t gsm_mux_net_start_xmit(struct sk_buff *skb,
struct net_device *net)
{
struct gsm_mux_net *mux_net = netdev_priv(net);
......
......@@ -72,19 +72,19 @@ do { \
#define TMP_BUF_MAX 256
#define DUMP(buf__,len__) \
do { \
char tbuf[TMP_BUF_MAX] = {0};\
if (len__ > 1) {\
snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s", buf__);\
if (tbuf[len__-2] == '\r') {\
tbuf[len__-2] = 'r';\
} \
DBG1("SENDING: '%s' (%d+n)", tbuf, len__);\
} else {\
DBG1("SENDING: '%s' (%d)", tbuf, len__);\
} \
} while (0)
#define DUMP(buf__, len__) \
do { \
char tbuf[TMP_BUF_MAX] = {0}; \
if (len__ > 1) { \
u32 data_len = min_t(u32, len__, TMP_BUF_MAX); \
strscpy(tbuf, buf__, data_len); \
if (tbuf[data_len - 2] == '\r') \
tbuf[data_len - 2] = 'r'; \
DBG1("SENDING: '%s' (%d+n)", tbuf, len__); \
} else { \
DBG1("SENDING: '%s' (%d)", tbuf, len__); \
} \
} while (0)
/* Defines */
#define NOZOMI_NAME "nozomi"
......@@ -102,41 +102,41 @@ do { \
#define RECEIVE_BUF_MAX 4
#define R_IIR 0x0000 /* Interrupt Identity Register */
#define R_FCR 0x0000 /* Flow Control Register */
#define R_IER 0x0004 /* Interrupt Enable Register */
#define R_IIR 0x0000 /* Interrupt Identity Register */
#define R_FCR 0x0000 /* Flow Control Register */
#define R_IER 0x0004 /* Interrupt Enable Register */
#define NOZOMI_CONFIG_MAGIC 0xEFEFFEFE
#define TOGGLE_VALID 0x0000
/* Definition of interrupt tokens */
#define MDM_DL1 0x0001
#define MDM_UL1 0x0002
#define MDM_DL2 0x0004
#define MDM_UL2 0x0008
#define DIAG_DL1 0x0010
#define DIAG_DL2 0x0020
#define DIAG_UL 0x0040
#define APP1_DL 0x0080
#define APP1_UL 0x0100
#define APP2_DL 0x0200
#define APP2_UL 0x0400
#define CTRL_DL 0x0800
#define CTRL_UL 0x1000
#define RESET 0x8000
#define MDM_DL (MDM_DL1 | MDM_DL2)
#define MDM_UL (MDM_UL1 | MDM_UL2)
#define DIAG_DL (DIAG_DL1 | DIAG_DL2)
#define MDM_DL1 0x0001
#define MDM_UL1 0x0002
#define MDM_DL2 0x0004
#define MDM_UL2 0x0008
#define DIAG_DL1 0x0010
#define DIAG_DL2 0x0020
#define DIAG_UL 0x0040
#define APP1_DL 0x0080
#define APP1_UL 0x0100
#define APP2_DL 0x0200
#define APP2_UL 0x0400
#define CTRL_DL 0x0800
#define CTRL_UL 0x1000
#define RESET 0x8000
#define MDM_DL (MDM_DL1 | MDM_DL2)
#define MDM_UL (MDM_UL1 | MDM_UL2)
#define DIAG_DL (DIAG_DL1 | DIAG_DL2)
/* modem signal definition */
#define CTRL_DSR 0x0001
#define CTRL_DCD 0x0002
#define CTRL_RI 0x0004
#define CTRL_CTS 0x0008
#define CTRL_DSR 0x0001
#define CTRL_DCD 0x0002
#define CTRL_RI 0x0004
#define CTRL_CTS 0x0008
#define CTRL_DTR 0x0001
#define CTRL_RTS 0x0002
#define CTRL_DTR 0x0001
#define CTRL_RTS 0x0002
#define MAX_PORT 4
#define NOZOMI_MAX_PORTS 5
......@@ -155,7 +155,7 @@ enum card_type {
/* Initialization states a card can be in */
enum card_state {
NOZOMI_STATE_UKNOWN = 0,
NOZOMI_STATE_UNKNOWN = 0,
NOZOMI_STATE_ENABLED = 1, /* pci device enabled */
NOZOMI_STATE_ALLOCATED = 2, /* config setup done */
NOZOMI_STATE_READY = 3, /* flowcontrols received */
......@@ -365,7 +365,7 @@ struct buffer {
u8 *data;
} __attribute__ ((packed));
/* Global variables */
/* Global variables */
static const struct pci_device_id nozomi_pci_tbl[] = {
{PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */
{},
......@@ -1686,12 +1686,12 @@ static int ntty_tiocmget(struct tty_struct *tty)
/* Note: these could change under us but it is not clear this
matters if so */
return (ctrl_ul->RTS ? TIOCM_RTS : 0) |
(ctrl_ul->DTR ? TIOCM_DTR : 0) |
(ctrl_dl->DCD ? TIOCM_CAR : 0) |
(ctrl_dl->RI ? TIOCM_RNG : 0) |
(ctrl_dl->DSR ? TIOCM_DSR : 0) |
(ctrl_dl->CTS ? TIOCM_CTS : 0);
return (ctrl_ul->RTS ? TIOCM_RTS : 0)
| (ctrl_ul->DTR ? TIOCM_DTR : 0)
| (ctrl_dl->DCD ? TIOCM_CAR : 0)
| (ctrl_dl->RI ? TIOCM_RNG : 0)
| (ctrl_dl->DSR ? TIOCM_DSR : 0)
| (ctrl_dl->CTS ? TIOCM_CTS : 0);
}
/* Sets io controls parameters */
......@@ -1722,10 +1722,10 @@ static int ntty_cflags_changed(struct port *port, unsigned long flags,
const struct async_icount cnow = port->tty_icount;
int ret;
ret = ((flags & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
((flags & TIOCM_CD) && (cnow.dcd != cprev->dcd)) ||
((flags & TIOCM_CTS) && (cnow.cts != cprev->cts));
ret = ((flags & TIOCM_RNG) && (cnow.rng != cprev->rng))
|| ((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr))
|| ((flags & TIOCM_CD) && (cnow.dcd != cprev->dcd))
|| ((flags & TIOCM_CTS) && (cnow.cts != cprev->cts));
*cprev = cnow;
......
......@@ -110,16 +110,19 @@ static void pty_unthrottle(struct tty_struct *tty)
static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
{
struct tty_struct *to = tty->link;
unsigned long flags;
if (tty->stopped)
return 0;
if (c > 0) {
spin_lock_irqsave(&to->port->lock, flags);
/* Stuff the data into the input queue of the other end */
c = tty_insert_flip_string(to->port, buf, c);
/* And shovel */
if (c)
tty_flip_buffer_push(to->port);
spin_unlock_irqrestore(&to->port->lock, flags);
}
return c;
}
......
......@@ -10,6 +10,8 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/clk.h>
#include "8250.h"
......@@ -28,8 +30,17 @@ struct aspeed_vuart {
void __iomem *regs;
struct clk *clk;
int line;
struct timer_list unthrottle_timer;
struct uart_8250_port *port;
};
/*
* If we fill the tty flip buffers, we throttle the data ready interrupt
* to prevent dropped characters. This timeout defines how long we wait
* to (conditionally, depending on buffer state) unthrottle.
*/
static const int unthrottle_timeout = HZ/10;
/*
* The VUART is basically two UART 'front ends' connected by their FIFO
* (no actual serial line in between). One is on the BMC side (management
......@@ -179,6 +190,114 @@ static void aspeed_vuart_shutdown(struct uart_port *uart_port)
serial8250_do_shutdown(uart_port);
}
static void __aspeed_vuart_set_throttle(struct uart_8250_port *up,
bool throttle)
{
unsigned char irqs = UART_IER_RLSI | UART_IER_RDI;
up->ier &= ~irqs;
if (!throttle)
up->ier |= irqs;
serial_out(up, UART_IER, up->ier);
}
static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle)
{
struct uart_8250_port *up = up_to_u8250p(port);
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
__aspeed_vuart_set_throttle(up, throttle);
spin_unlock_irqrestore(&port->lock, flags);
}
static void aspeed_vuart_throttle(struct uart_port *port)
{
aspeed_vuart_set_throttle(port, true);
}
static void aspeed_vuart_unthrottle(struct uart_port *port)
{
aspeed_vuart_set_throttle(port, false);
}
static void aspeed_vuart_unthrottle_exp(struct timer_list *timer)
{
struct aspeed_vuart *vuart = from_timer(vuart, timer, unthrottle_timer);
struct uart_8250_port *up = vuart->port;
if (!tty_buffer_space_avail(&up->port.state->port)) {
mod_timer(&vuart->unthrottle_timer,
jiffies + unthrottle_timeout);
return;
}
aspeed_vuart_unthrottle(&up->port);
}
/*
* Custom interrupt handler to manage finer-grained flow control. Although we
* have throttle/unthrottle callbacks, we've seen that the VUART device can
* deliver characters faster than the ldisc has a chance to check buffer space
* against the throttle threshold. This results in dropped characters before
* the throttle.
*
* We do this by checking for flip buffer space before RX. If we have no space,
* throttle now and schedule an unthrottle for later, once the ldisc has had
* a chance to drain the buffers.
*/
static int aspeed_vuart_handle_irq(struct uart_port *port)
{
struct uart_8250_port *up = up_to_u8250p(port);
unsigned int iir, lsr;
unsigned long flags;
int space, count;
iir = serial_port_in(port, UART_IIR);
if (iir & UART_IIR_NO_INT)
return 0;
spin_lock_irqsave(&port->lock, flags);
lsr = serial_port_in(port, UART_LSR);
if (lsr & (UART_LSR_DR | UART_LSR_BI)) {
space = tty_buffer_space_avail(&port->state->port);
if (!space) {
/* throttle and schedule an unthrottle later */
struct aspeed_vuart *vuart = port->private_data;
__aspeed_vuart_set_throttle(up, true);
if (!timer_pending(&vuart->unthrottle_timer)) {
vuart->port = up;
mod_timer(&vuart->unthrottle_timer,
jiffies + unthrottle_timeout);
}
} else {
count = min(space, 256);
do {
serial8250_read_char(up, lsr);
lsr = serial_in(up, UART_LSR);
if (--count == 0)
break;
} while (lsr & (UART_LSR_DR | UART_LSR_BI));
tty_flip_buffer_push(&port->state->port);
}
}
serial8250_modem_status(up);
if (lsr & UART_LSR_THRE)
serial8250_tx_chars(up);
spin_unlock_irqrestore(&port->lock, flags);
return 1;
}
static int aspeed_vuart_probe(struct platform_device *pdev)
{
struct uart_8250_port port;
......@@ -195,6 +314,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
return -ENOMEM;
vuart->dev = &pdev->dev;
timer_setup(&vuart->unthrottle_timer, aspeed_vuart_unthrottle_exp, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
vuart->regs = devm_ioremap_resource(&pdev->dev, res);
......@@ -208,6 +328,9 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
port.port.mapsize = resource_size(res);
port.port.startup = aspeed_vuart_startup;
port.port.shutdown = aspeed_vuart_shutdown;
port.port.throttle = aspeed_vuart_throttle;
port.port.unthrottle = aspeed_vuart_unthrottle;
port.port.status = UPSTAT_SYNC_FIFO;
port.port.dev = &pdev->dev;
rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
......@@ -253,6 +376,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
port.port.irq = irq_of_parse_and_map(np, 0);
port.port.irqflags = IRQF_SHARED;
port.port.handle_irq = aspeed_vuart_handle_irq;
port.port.iotype = UPIO_MEM;
port.port.type = PORT_16550A;
port.port.uartclk = clk;
......@@ -292,6 +416,7 @@ static int aspeed_vuart_remove(struct platform_device *pdev)
{
struct aspeed_vuart *vuart = platform_get_drvdata(pdev);
del_timer_sync(&vuart->unthrottle_timer);
aspeed_vuart_set_enabled(vuart, false);
serial8250_unregister_port(vuart->line);
sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
......
......@@ -121,25 +121,44 @@ static void dw8250_check_lcr(struct uart_port *p, int value)
}
/* Returns once the transmitter is empty or we run out of retries */
static void dw8250_tx_wait_empty(struct uart_port *p, int tries)
static void dw8250_tx_wait_empty(struct uart_port *p)
{
unsigned int tries = 20000;
unsigned int delay_threshold = tries - 1000;
unsigned int lsr;
while (tries--) {
lsr = readb (p->membase + (UART_LSR << p->regshift));
if (lsr & UART_LSR_TEMT)
break;
udelay (10);
/* The device is first given a chance to empty without delay,
* to avoid slowdowns at high bitrates. If after 1000 tries
* the buffer has still not emptied, allow more time for low-
* speed links. */
if (tries < delay_threshold)
udelay (1);
}
}
static void dw8250_serial_out(struct uart_port *p, int offset, int value)
static void dw8250_serial_out38x(struct uart_port *p, int offset, int value)
{
struct dw8250_data *d = p->private_data;
/* Allow the TX to drain before we reconfigure */
if (offset == UART_LCR)
dw8250_tx_wait_empty(p, 1000);
dw8250_tx_wait_empty(p);
writeb(value, p->membase + (offset << p->regshift));
if (offset == UART_LCR && !d->uart_16550_compatible)
dw8250_check_lcr(p, value);
}
static void dw8250_serial_out(struct uart_port *p, int offset, int value)
{
struct dw8250_data *d = p->private_data;
writeb(value, p->membase + (offset << p->regshift));
......@@ -357,6 +376,9 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
p->serial_in = dw8250_serial_in32be;
p->serial_out = dw8250_serial_out32be;
}
if (of_device_is_compatible(np, "marvell,armada-38x-uart"))
p->serial_out = dw8250_serial_out38x;
} else if (acpi_dev_present("APMC0D08", NULL, -1)) {
p->iotype = UPIO_MEM32;
p->regshift = 2;
......@@ -554,6 +576,10 @@ static int dw8250_probe(struct platform_device *pdev)
if (!data->skip_autocfg)
dw8250_setup_port(p);
#ifdef CONFIG_PM
uart.capabilities |= UART_CAP_RPM;
#endif
/* If we have a valid fifosize, try hooking up DMA */
if (p->fifosize) {
data->dma.rxconf.src_maxburst = p->fifosize / 4;
......@@ -666,6 +692,7 @@ static const struct dev_pm_ops dw8250_pm_ops = {
static const struct of_device_id dw8250_of_match[] = {
{ .compatible = "snps,dw-apb-uart" },
{ .compatible = "cavium,octeon-3860-uart" },
{ .compatible = "marvell,armada-38x-uart" },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, dw8250_of_match);
......
......@@ -122,7 +122,7 @@ static void __init init_port(struct earlycon_device *device)
serial8250_early_out(port, UART_FCR, 0); /* no fifo */
serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */
if (port->uartclk && device->baud) {
if (port->uartclk) {
divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud);
c = serial8250_early_in(port, UART_LCR);
serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB);
......
......@@ -92,13 +92,43 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
goto err_unprepare;
}
port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT |
UPF_FIXED_TYPE;
spin_lock_init(&port->lock);
port->mapbase = resource.start;
port->mapsize = resource_size(&resource);
/* Check for shifted address mapping */
if (of_property_read_u32(np, "reg-offset", &prop) == 0)
port->mapbase += prop;
if (resource_type(&resource) == IORESOURCE_IO) {
port->iotype = UPIO_PORT;
port->iobase = resource.start;
} else {
port->mapbase = resource.start;
port->mapsize = resource_size(&resource);
/* Check for shifted address mapping */
if (of_property_read_u32(np, "reg-offset", &prop) == 0)
port->mapbase += prop;
port->iotype = UPIO_MEM;
if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
switch (prop) {
case 1:
port->iotype = UPIO_MEM;
break;
case 2:
port->iotype = UPIO_MEM16;
break;
case 4:
port->iotype = of_device_is_big_endian(np) ?
UPIO_MEM32BE : UPIO_MEM32;
break;
default:
dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
prop);
ret = -EINVAL;
goto err_dispose;
}
}
port->flags |= UPF_IOREMAP;
}
/* Check for registers offset within the devices address range */
if (of_property_read_u32(np, "reg-shift", &prop) == 0)
......@@ -114,26 +144,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
port->line = ret;
port->irq = irq_of_parse_and_map(np, 0);
port->iotype = UPIO_MEM;
if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
switch (prop) {
case 1:
port->iotype = UPIO_MEM;
break;
case 2:
port->iotype = UPIO_MEM16;
break;
case 4:
port->iotype = of_device_is_big_endian(np) ?
UPIO_MEM32BE : UPIO_MEM32;
break;
default:
dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
prop);
ret = -EINVAL;
goto err_dispose;
}
}
info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL);
if (IS_ERR(info->rst)) {
......@@ -147,8 +157,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
port->type = type;
port->uartclk = clk;
port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
| UPF_FIXED_PORT | UPF_FIXED_TYPE;
port->irqflags |= IRQF_SHARED;
if (of_property_read_bool(np, "no-loopback-test"))
port->flags |= UPF_SKIP_TEST;
......
......@@ -1110,13 +1110,14 @@ static int omap8250_no_handle_irq(struct uart_port *port)
return 0;
}
static const u8 omap4_habit = UART_ERRATA_CLOCK_DISABLE;
static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE;
static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE;
static const struct of_device_id omap8250_dt_ids[] = {
{ .compatible = "ti,omap2-uart" },
{ .compatible = "ti,omap3-uart" },
{ .compatible = "ti,omap4-uart" },
{ .compatible = "ti,omap4-uart", .data = &omap4_habit, },
{ .compatible = "ti,am3352-uart", .data = &am3352_habit, },
{ .compatible = "ti,am4372-uart", .data = &am3352_habit, },
{ .compatible = "ti,dra742-uart", .data = &dra742_habit, },
......@@ -1310,8 +1311,17 @@ static void omap8250_complete(struct device *dev)
static int omap8250_suspend(struct device *dev)
{
struct omap8250_priv *priv = dev_get_drvdata(dev);
struct uart_8250_port *up = serial8250_get_port(priv->line);
serial8250_suspend_port(priv->line);
pm_runtime_get_sync(dev);
if (!device_may_wakeup(dev))
priv->wer = 0;
serial_out(up, UART_OMAP_WER, priv->wer);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
flush_work(&priv->qos_work);
return 0;
}
......@@ -1353,6 +1363,19 @@ static int omap8250_soft_reset(struct device *dev)
int sysc;
int syss;
/*
* At least on omap4, unused uarts may not idle after reset without
* a basic scr dma configuration even with no dma in use. The
* module clkctrl status bits will be 1 instead of 3 blocking idle
* for the whole clockdomain. The softreset below will clear scr,
* and we restore it on resume so this is safe to do on all SoCs
* needing omap8250_soft_reset() quirk. Do it in two writes as
* recommended in the comment for omap8250_update_scr().
*/
serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1);
serial_out(up, UART_OMAP_SCR,
OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL);
sysc = serial_in(up, UART_OMAP_SYSC);
/* softreset the UART */
......@@ -1403,6 +1426,8 @@ static int omap8250_runtime_suspend(struct device *dev)
/* Restore to UART mode after reset (for wakeup) */
omap8250_update_mdr1(up, priv);
/* Restore wakeup enable register */
serial_out(up, UART_OMAP_WER, priv->wer);
}
if (up->dma && up->dma->rxchan)
......
......@@ -243,6 +243,7 @@ static const struct serial8250_config uart_config[] = {
.fifo_size = 32,
.tx_loadsz = 32,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.rxtrig_bytes = {1, 8, 16, 30},
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
[PORT_ALTR_16550_F64] = {
......@@ -250,6 +251,7 @@ static const struct serial8250_config uart_config[] = {
.fifo_size = 64,
.tx_loadsz = 64,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.rxtrig_bytes = {1, 16, 32, 62},
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
[PORT_ALTR_16550_F128] = {
......@@ -257,6 +259,7 @@ static const struct serial8250_config uart_config[] = {
.fifo_size = 128,
.tx_loadsz = 128,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.rxtrig_bytes = {1, 32, 64, 126},
.flags = UART_CAP_FIFO | UART_CAP_AFE,
},
/*
......@@ -1680,7 +1683,7 @@ static void serial8250_enable_ms(struct uart_port *port)
serial8250_rpm_put(up);
}
static void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
{
struct uart_port *port = &up->port;
unsigned char ch;
......@@ -1740,6 +1743,7 @@ static void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
}
EXPORT_SYMBOL_GPL(serial8250_read_char);
/*
* serial8250_rx_chars: processes according to the passed in LSR
......
......@@ -115,7 +115,6 @@ config SERIAL_SB1250_DUART_CONSOLE
config SERIAL_ATMEL
bool "AT91 on-chip serial port support"
depends on HAS_DMA
depends on ARCH_AT91 || COMPILE_TEST
select SERIAL_CORE
select SERIAL_MCTRL_GPIO if GPIOLIB
......@@ -500,7 +499,6 @@ config SERIAL_SA1100_CONSOLE
config SERIAL_IMX
tristate "IMX serial port support"
depends on HAS_DMA
depends on ARCH_MXC || COMPILE_TEST
select SERIAL_CORE
select RATIONAL
......@@ -676,6 +674,8 @@ config SERIAL_SH_SCI
config SERIAL_SH_SCI_NR_UARTS
int "Maximum number of SCI(F) serial ports" if EXPERT
range 1 64 if 64BIT
range 1 32 if !64BIT
depends on SERIAL_SH_SCI
default "3" if H8300
default "10" if SUPERH
......@@ -1262,7 +1262,6 @@ config SERIAL_PCH_UART_CONSOLE
config SERIAL_MXS_AUART
tristate "MXS AUART support"
depends on HAS_DMA
depends on ARCH_MXS || MACH_ASM9260 || COMPILE_TEST
select SERIAL_CORE
select SERIAL_MCTRL_GPIO if GPIOLIB
......@@ -1295,7 +1294,7 @@ config SERIAL_XILINX_PS_UART_CONSOLE
config SERIAL_AR933X
tristate "AR933X serial port support"
depends on HAVE_CLK && SOC_AR933X
depends on HAVE_CLK && ATH79
select SERIAL_CORE
help
If you have an Atheros AR933X SOC based board and want to use the
......@@ -1473,7 +1472,6 @@ config SERIAL_SPRD_CONSOLE
config SERIAL_STM32
tristate "STMicroelectronics STM32 serial port support"
select SERIAL_CORE
depends on HAS_DMA
depends on ARCH_STM32 || COMPILE_TEST
help
This driver is for the on-chip Serial Controller on
......
......@@ -1727,10 +1727,26 @@ static int pl011_allocate_irq(struct uart_amba_port *uap)
*/
static void pl011_enable_interrupts(struct uart_amba_port *uap)
{
unsigned int i;
spin_lock_irq(&uap->port.lock);
/* Clear out any spuriously appearing RX interrupts */
pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
/*
* RXIS is asserted only when the RX FIFO transitions from below
* to above the trigger threshold. If the RX FIFO is already
* full to the threshold this can't happen and RXIS will now be
* stuck off. Drain the RX FIFO explicitly to fix this:
*/
for (i = 0; i < uap->fifosize * 2; ++i) {
if (pl011_read(uap, REG_FR) & UART01x_FR_RXFE)
break;
pl011_read(uap, REG_DR);
}
uap->im = UART011_RTIM;
if (!pl011_dma_rx_running(uap))
uap->im |= UART011_RXIM;
......
......@@ -1757,7 +1757,6 @@ static int atmel_startup(struct uart_port *port)
{
struct platform_device *pdev = to_platform_device(port->dev);
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
struct tty_struct *tty = port->state->port.tty;
int retval;
/*
......@@ -1772,8 +1771,8 @@ static int atmel_startup(struct uart_port *port)
* Allocate the IRQ
*/
retval = request_irq(port->irq, atmel_interrupt,
IRQF_SHARED | IRQF_COND_SUSPEND,
tty ? tty->name : "atmel_serial", port);
IRQF_SHARED | IRQF_COND_SUSPEND,
dev_name(&pdev->dev), port);
if (retval) {
dev_err(port->dev, "atmel_startup - Can't get irq\n");
return retval;
......
......@@ -246,7 +246,6 @@ int __init of_setup_earlycon(const struct earlycon_id *match,
return -ENXIO;
}
port->mapbase = addr;
port->uartclk = BASE_BAUD * 16;
val = of_get_flat_dt_prop(node, "reg-offset", NULL);
if (val)
......@@ -281,6 +280,10 @@ int __init of_setup_earlycon(const struct earlycon_id *match,
if (val)
early_console_dev.baud = be32_to_cpu(*val);
val = of_get_flat_dt_prop(node, "clock-frequency", NULL);
if (val)
port->uartclk = be32_to_cpu(*val);
if (options) {
early_console_dev.baud = simple_strtoul(options, NULL, 0);
strlcpy(early_console_dev.options, options,
......
......@@ -1291,18 +1291,13 @@ static void imx_uart_enable_dma(struct imx_port *sport)
static void imx_uart_disable_dma(struct imx_port *sport)
{
u32 ucr1, ucr2;
u32 ucr1;
/* clear UCR1 */
ucr1 = imx_uart_readl(sport, UCR1);
ucr1 &= ~(UCR1_RXDMAEN | UCR1_TXDMAEN | UCR1_ATDMAEN);
imx_uart_writel(sport, ucr1, UCR1);
/* clear UCR2 */
ucr2 = imx_uart_readl(sport, UCR2);
ucr2 &= ~(UCR2_CTSC | UCR2_CTS | UCR2_ATEN);
imx_uart_writel(sport, ucr2, UCR2);
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
sport->dma_is_enabled = 0;
......@@ -1427,13 +1422,21 @@ static void imx_uart_shutdown(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
unsigned long flags;
u32 ucr1, ucr2;
u32 ucr1, ucr2, ucr4;
if (sport->dma_is_enabled) {
sport->dma_is_rxing = 0;
sport->dma_is_txing = 0;
dmaengine_terminate_sync(sport->dma_chan_tx);
if (sport->dma_is_txing) {
dma_unmap_sg(sport->port.dev, &sport->tx_sgl[0],
sport->dma_tx_nents, DMA_TO_DEVICE);
sport->dma_is_txing = 0;
}
dmaengine_terminate_sync(sport->dma_chan_rx);
if (sport->dma_is_rxing) {
dma_unmap_sg(sport->port.dev, &sport->rx_sgl,
1, DMA_FROM_DEVICE);
sport->dma_is_rxing = 0;
}
spin_lock_irqsave(&sport->port.lock, flags);
imx_uart_stop_tx(port);
......@@ -1449,6 +1452,10 @@ static void imx_uart_shutdown(struct uart_port *port)
ucr2 = imx_uart_readl(sport, UCR2);
ucr2 &= ~(UCR2_TXEN | UCR2_ATEN);
imx_uart_writel(sport, ucr2, UCR2);
ucr4 = imx_uart_readl(sport, UCR4);
ucr4 &= ~UCR4_OREN;
imx_uart_writel(sport, ucr4, UCR4);
spin_unlock_irqrestore(&sport->port.lock, flags);
/*
......@@ -2425,8 +2432,7 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
static int imx_uart_suspend_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
struct imx_port *sport = dev_get_drvdata(dev);
imx_uart_save_context(sport);
......@@ -2437,8 +2443,7 @@ static int imx_uart_suspend_noirq(struct device *dev)
static int imx_uart_resume_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
struct imx_port *sport = dev_get_drvdata(dev);
int ret;
ret = clk_enable(sport->clk_ipg);
......@@ -2452,8 +2457,7 @@ static int imx_uart_resume_noirq(struct device *dev)
static int imx_uart_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
struct imx_port *sport = dev_get_drvdata(dev);
int ret;
uart_suspend_port(&imx_uart_uart_driver, &sport->port);
......@@ -2471,8 +2475,7 @@ static int imx_uart_suspend(struct device *dev)
static int imx_uart_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
struct imx_port *sport = dev_get_drvdata(dev);
/* disable wakeup from i.MX UART */
imx_uart_enable_wakeup(sport, false);
......@@ -2487,8 +2490,7 @@ static int imx_uart_resume(struct device *dev)
static int imx_uart_freeze(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
struct imx_port *sport = dev_get_drvdata(dev);
uart_suspend_port(&imx_uart_uart_driver, &sport->port);
......@@ -2497,8 +2499,7 @@ static int imx_uart_freeze(struct device *dev)
static int imx_uart_thaw(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
struct imx_port *sport = dev_get_drvdata(dev);
uart_resume_port(&imx_uart_uart_driver, &sport->port);
......
......@@ -1812,11 +1812,34 @@ static const struct of_device_id msm_match_table[] = {
};
MODULE_DEVICE_TABLE(of, msm_match_table);
static int __maybe_unused msm_serial_suspend(struct device *dev)
{
struct msm_port *port = dev_get_drvdata(dev);
uart_suspend_port(&msm_uart_driver, &port->uart);
return 0;
}
static int __maybe_unused msm_serial_resume(struct device *dev)
{
struct msm_port *port = dev_get_drvdata(dev);
uart_resume_port(&msm_uart_driver, &port->uart);
return 0;
}
static const struct dev_pm_ops msm_serial_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(msm_serial_suspend, msm_serial_resume)
};
static struct platform_driver msm_platform_driver = {
.remove = msm_serial_remove,
.probe = msm_serial_probe,
.driver = {
.name = "msm_serial",
.pm = &msm_serial_dev_pm_ops,
.of_match_table = msm_match_table,
},
};
......
......@@ -71,6 +71,8 @@
#define UART_BRDV 0x10
#define BRDV_BAUD_MASK 0x3FF
#define UART_OSAMP 0x14
#define MVEBU_NR_UARTS 2
#define MVEBU_UART_TYPE "mvebu-uart"
......@@ -108,6 +110,17 @@ struct mvebu_uart_driver_data {
struct uart_flags flags;
};
/* Saved registers during suspend */
struct mvebu_uart_pm_regs {
unsigned int rbr;
unsigned int tsh;
unsigned int ctrl;
unsigned int intr;
unsigned int stat;
unsigned int brdv;
unsigned int osamp;
};
/* MVEBU UART driver structure */
struct mvebu_uart {
struct uart_port *port;
......@@ -115,6 +128,9 @@ struct mvebu_uart {
int irq[UART_IRQ_COUNT];
unsigned char __iomem *nb;
struct mvebu_uart_driver_data *data;
#if defined(CONFIG_PM)
struct mvebu_uart_pm_regs pm_regs;
#endif /* CONFIG_PM */
};
static struct mvebu_uart *to_mvuart(struct uart_port *port)
......@@ -718,6 +734,51 @@ static struct uart_driver mvebu_uart_driver = {
#endif
};
#if defined(CONFIG_PM)
static int mvebu_uart_suspend(struct device *dev)
{
struct mvebu_uart *mvuart = dev_get_drvdata(dev);
struct uart_port *port = mvuart->port;
uart_suspend_port(&mvebu_uart_driver, port);
mvuart->pm_regs.rbr = readl(port->membase + UART_RBR(port));
mvuart->pm_regs.tsh = readl(port->membase + UART_TSH(port));
mvuart->pm_regs.ctrl = readl(port->membase + UART_CTRL(port));
mvuart->pm_regs.intr = readl(port->membase + UART_INTR(port));
mvuart->pm_regs.stat = readl(port->membase + UART_STAT);
mvuart->pm_regs.brdv = readl(port->membase + UART_BRDV);
mvuart->pm_regs.osamp = readl(port->membase + UART_OSAMP);
device_set_wakeup_enable(dev, true);
return 0;
}
static int mvebu_uart_resume(struct device *dev)
{
struct mvebu_uart *mvuart = dev_get_drvdata(dev);
struct uart_port *port = mvuart->port;
writel(mvuart->pm_regs.rbr, port->membase + UART_RBR(port));
writel(mvuart->pm_regs.tsh, port->membase + UART_TSH(port));
writel(mvuart->pm_regs.ctrl, port->membase + UART_CTRL(port));
writel(mvuart->pm_regs.intr, port->membase + UART_INTR(port));
writel(mvuart->pm_regs.stat, port->membase + UART_STAT);
writel(mvuart->pm_regs.brdv, port->membase + UART_BRDV);
writel(mvuart->pm_regs.osamp, port->membase + UART_OSAMP);
uart_resume_port(&mvebu_uart_driver, port);
return 0;
}
static const struct dev_pm_ops mvebu_uart_pm_ops = {
.suspend = mvebu_uart_suspend,
.resume = mvebu_uart_resume,
};
#endif /* CONFIG_PM */
static const struct of_device_id mvebu_uart_of_match[];
/* Counter to keep track of each UART port id when not using CONFIG_OF */
......@@ -891,6 +952,9 @@ static struct platform_driver mvebu_uart_platform_driver = {
.name = "mvebu-uart",
.of_match_table = of_match_ptr(mvebu_uart_of_match),
.suppress_bind_attrs = true,
#if defined(CONFIG_PM)
.pm = &mvebu_uart_pm_ops,
#endif /* CONFIG_PM */
},
};
......
......@@ -98,14 +98,13 @@ struct qcom_geni_serial_port {
enum geni_se_xfer_mode xfer_mode;
bool setup;
int (*handle_rx)(struct uart_port *uport, u32 bytes, bool drop);
unsigned int xmit_size;
unsigned int baud;
unsigned int tx_bytes_pw;
unsigned int rx_bytes_pw;
bool brk;
};
static const struct uart_ops qcom_geni_serial_pops;
static const struct uart_ops qcom_geni_console_pops;
static struct uart_driver qcom_geni_console_driver;
static int handle_rx_console(struct uart_port *uport, u32 bytes, bool drop);
static unsigned int qcom_geni_serial_tx_empty(struct uart_port *port);
......@@ -118,7 +117,14 @@ static const unsigned long root_freq[] = {7372800, 14745600, 19200000, 29491200,
#define to_dev_port(ptr, member) \
container_of(ptr, struct qcom_geni_serial_port, member)
static struct qcom_geni_serial_port qcom_geni_console_port;
static struct qcom_geni_serial_port qcom_geni_console_port = {
.uport = {
.iotype = UPIO_MEM,
.ops = &qcom_geni_console_pops,
.flags = UPF_BOOT_AUTOCONF,
.line = 0,
},
};
static int qcom_geni_serial_request_port(struct uart_port *uport)
{
......@@ -189,8 +195,19 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
timeout_us = ((fifo_bits * USEC_PER_SEC) / baud) + 500;
}
return !readl_poll_timeout_atomic(uport->membase + offset, reg,
(bool)(reg & field) == set, 10, timeout_us);
/*
* Use custom implementation instead of readl_poll_atomic since ktimer
* is not ready at the time of early console.
*/
timeout_us = DIV_ROUND_UP(timeout_us, 10) * 10;
while (timeout_us) {
reg = readl_relaxed(uport->membase + offset);
if ((bool)(reg & field) == set)
return true;
udelay(10);
timeout_us -= 10;
}
return false;
}
static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size)
......@@ -286,6 +303,10 @@ __qcom_geni_serial_console_write(struct uart_port *uport, const char *s,
u32 bytes_to_send = count;
for (i = 0; i < count; i++) {
/*
* uart_console_write() adds a carriage return for each newline.
* Account for additional bytes to be written.
*/
if (s[i] == '\n')
bytes_to_send++;
}
......@@ -305,7 +326,7 @@ __qcom_geni_serial_console_write(struct uart_port *uport, const char *s,
if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_TX_FIFO_WATERMARK_EN, true))
break;
chars_to_write = min_t(size_t, (size_t)(count - i), avail / 2);
chars_to_write = min_t(size_t, count - i, avail / 2);
uart_console_write(uport, s + i, chars_to_write,
qcom_geni_serial_wr_char);
writel_relaxed(M_TX_FIFO_WATERMARK_EN, uport->membase +
......@@ -406,20 +427,18 @@ static void qcom_geni_serial_start_tx(struct uart_port *uport)
u32 status;
if (port->xfer_mode == GENI_SE_FIFO) {
status = readl_relaxed(uport->membase + SE_GENI_STATUS);
/*
* readl ensures reading & writing of IRQ_EN register
* is not re-ordered before checking the status of the
* Serial Engine.
*/
status = readl(uport->membase + SE_GENI_STATUS);
if (status & M_GENI_CMD_ACTIVE)
return;
if (!qcom_geni_serial_tx_empty(uport))
return;
/*
* Ensure writing to IRQ_EN & watermark registers are not
* re-ordered before checking the status of the Serial
* Engine and TX FIFO
*/
mb();
irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
......@@ -442,7 +461,6 @@ static void qcom_geni_serial_stop_tx(struct uart_port *uport)
writel_relaxed(0, uport->membase +
SE_GENI_TX_WATERMARK_REG);
}
port->xmit_size = 0;
writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
status = readl_relaxed(uport->membase + SE_GENI_STATUS);
/* Possible stop tx is called multiple times. */
......@@ -572,21 +590,14 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport)
chunk = uart_circ_chars_pending(xmit);
status = readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
/* Both FIFO and framework buffer are drained */
if (chunk == port->xmit_size && !status) {
port->xmit_size = 0;
uart_circ_clear(xmit);
if (!chunk && !status) {
qcom_geni_serial_stop_tx(uport);
goto out_write_wakeup;
}
chunk -= port->xmit_size;
avail = (port->tx_fifo_depth - port->tx_wm) * port->tx_bytes_pw;
tail = (xmit->tail + port->xmit_size) & (UART_XMIT_SIZE - 1);
if (chunk > (UART_XMIT_SIZE - tail))
chunk = UART_XMIT_SIZE - tail;
if (chunk > avail)
chunk = avail;
tail = xmit->tail;
chunk = min3((size_t)chunk, (size_t)(UART_XMIT_SIZE - tail), avail);
if (!chunk)
goto out_write_wakeup;
......@@ -595,24 +606,27 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport)
remaining = chunk;
for (i = 0; i < chunk; ) {
unsigned int tx_bytes;
unsigned int buf = 0;
u8 buf[sizeof(u32)];
int c;
tx_bytes = min_t(size_t, remaining, (size_t)port->tx_bytes_pw);
memset(buf, 0, ARRAY_SIZE(buf));
tx_bytes = min_t(size_t, remaining, port->tx_bytes_pw);
for (c = 0; c < tx_bytes ; c++)
buf |= (xmit->buf[tail + c] << (c * BITS_PER_BYTE));
buf[c] = xmit->buf[tail + c];
writel_relaxed(buf, uport->membase + SE_GENI_TX_FIFOn);
iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1);
i += tx_bytes;
tail = (tail + tx_bytes) & (UART_XMIT_SIZE - 1);
tail += tx_bytes;
uport->icount.tx += tx_bytes;
remaining -= tx_bytes;
}
xmit->tail = tail & (UART_XMIT_SIZE - 1);
qcom_geni_serial_poll_tx_done(uport);
port->xmit_size += chunk;
out_write_wakeup:
uart_write_wakeup(uport);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(uport);
}
static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
......@@ -627,7 +641,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
if (uport->suspended)
return IRQ_HANDLED;
return IRQ_NONE;
spin_lock_irqsave(&uport->lock, flags);
m_irq_status = readl_relaxed(uport->membase + SE_GENI_M_IRQ_STATUS);
......@@ -667,20 +681,16 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
return IRQ_HANDLED;
}
static int get_tx_fifo_size(struct qcom_geni_serial_port *port)
static void get_tx_fifo_size(struct qcom_geni_serial_port *port)
{
struct uart_port *uport;
if (!port)
return -ENODEV;
uport = &port->uport;
port->tx_fifo_depth = geni_se_get_tx_fifo_depth(&port->se);
port->tx_fifo_width = geni_se_get_tx_fifo_width(&port->se);
port->rx_fifo_depth = geni_se_get_rx_fifo_depth(&port->se);
uport->fifosize =
(port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE;
return 0;
}
static void set_rfr_wm(struct qcom_geni_serial_port *port)
......@@ -702,7 +712,6 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport)
/* Stop the console before stopping the current tx */
console_stop(uport->cons);
disable_irq(uport->irq);
free_irq(uport->irq, uport);
spin_lock_irqsave(&uport->lock, flags);
qcom_geni_serial_stop_tx(uport);
......@@ -892,7 +901,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
static unsigned int qcom_geni_serial_tx_empty(struct uart_port *uport)
{
return !readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
return !readl(uport->membase + SE_GENI_TX_FIFO_STATUS);
}
#ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
......@@ -910,7 +919,7 @@ static int __init qcom_geni_console_setup(struct console *co, char *options)
port = get_port_from_line(co->index);
if (IS_ERR(port)) {
pr_err("Invalid line %d(%d)\n", co->index, (int)PTR_ERR(port));
pr_err("Invalid line %d\n", co->index);
return PTR_ERR(port);
}
......@@ -942,6 +951,65 @@ static int __init qcom_geni_console_setup(struct console *co, char *options)
return uart_set_options(uport, co, baud, parity, bits, flow);
}
static void qcom_geni_serial_earlycon_write(struct console *con,
const char *s, unsigned int n)
{
struct earlycon_device *dev = con->data;
__qcom_geni_serial_console_write(&dev->port, s, n);
}
static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev,
const char *opt)
{
struct uart_port *uport = &dev->port;
u32 tx_trans_cfg;
u32 tx_parity_cfg = 0; /* Disable Tx Parity */
u32 rx_trans_cfg = 0;
u32 rx_parity_cfg = 0; /* Disable Rx Parity */
u32 stop_bit_len = 0; /* Default stop bit length - 1 bit */
u32 bits_per_char;
struct geni_se se;
if (!uport->membase)
return -EINVAL;
memset(&se, 0, sizeof(se));
se.base = uport->membase;
if (geni_se_read_proto(&se) != GENI_SE_UART)
return -ENXIO;
/*
* Ignore Flow control.
* n = 8.
*/
tx_trans_cfg = UART_CTS_MASK;
bits_per_char = BITS_PER_BYTE;
/*
* Make an unconditional cancel on the main sequencer to reset
* it else we could end up in data loss scenarios.
*/
qcom_geni_serial_poll_tx_done(uport);
qcom_geni_serial_abort_rx(uport);
geni_se_config_packing(&se, BITS_PER_BYTE, 1, false, true, false);
geni_se_init(&se, DEF_FIFO_DEPTH_WORDS / 2, DEF_FIFO_DEPTH_WORDS - 2);
geni_se_select_mode(&se, GENI_SE_FIFO);
writel_relaxed(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
writel_relaxed(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
writel_relaxed(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
writel_relaxed(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
writel_relaxed(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
writel_relaxed(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
writel_relaxed(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
dev->con->write = qcom_geni_serial_earlycon_write;
dev->con->setup = NULL;
return 0;
}
OF_EARLYCON_DECLARE(qcom_geni, "qcom,geni-debug-uart",
qcom_geni_serial_earlycon_setup);
static int __init console_register(struct uart_driver *drv)
{
return uart_register_driver(drv);
......@@ -1026,16 +1094,13 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (pdev->dev.of_node)
line = of_alias_get_id(pdev->dev.of_node, "serial");
else
line = pdev->id;
if (line < 0 || line >= GENI_UART_CONS_PORTS)
return -ENXIO;
port = get_port_from_line(line);
if (IS_ERR(port)) {
ret = PTR_ERR(port);
dev_err(&pdev->dev, "Invalid line %d(%d)\n", line, ret);
return ret;
dev_err(&pdev->dev, "Invalid line %d\n", line);
return PTR_ERR(port);
}
uport = &port->uport;
......@@ -1072,7 +1137,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
uport->private_data = &qcom_geni_console_driver;
platform_set_drvdata(pdev, port);
port->handle_rx = handle_rx_console;
port->setup = false;
return uart_add_one_port(&qcom_geni_console_driver, uport);
}
......@@ -1087,8 +1151,7 @@ static int qcom_geni_serial_remove(struct platform_device *pdev)
static int __maybe_unused qcom_geni_serial_sys_suspend_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
uart_suspend_port(uport->private_data, uport);
......@@ -1097,12 +1160,19 @@ static int __maybe_unused qcom_geni_serial_sys_suspend_noirq(struct device *dev)
static int __maybe_unused qcom_geni_serial_sys_resume_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
if (console_suspend_enabled && uport->suspended) {
uart_resume_port(uport->private_data, uport);
/*
* uart_suspend_port() invokes port shutdown which in turn
* frees the irq. uart_resume_port invokes port startup which
* performs request_irq. The request_irq auto-enables the IRQ.
* In addition, resume_noirq implicitly enables the IRQ and
* leads to an unbalanced IRQ enable warning. Disable the IRQ
* before returning so that the warning is suppressed.
*/
disable_irq(uport->irq);
}
return 0;
......@@ -1133,11 +1203,6 @@ static int __init qcom_geni_serial_init(void)
{
int ret;
qcom_geni_console_port.uport.iotype = UPIO_MEM;
qcom_geni_console_port.uport.ops = &qcom_geni_console_pops;
qcom_geni_console_port.uport.flags = UPF_BOOT_AUTOCONF;
qcom_geni_console_port.uport.line = 0;
ret = console_register(&qcom_geni_console_driver);
if (ret)
return ret;
......
......@@ -856,35 +856,54 @@ 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;
struct dma_slave_caps dma_caps;
const char *reason = NULL;
int ret;
/* Default slave configuration parameters */
dma->rx_conf.direction = DMA_DEV_TO_MEM;
dma->rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma->rx_conf.src_addr = p->port.mapbase + S3C2410_URXH;
dma->rx_conf.src_maxburst = 16;
dma->rx_conf.src_maxburst = 1;
dma->tx_conf.direction = DMA_MEM_TO_DEV;
dma->tx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma->tx_conf.dst_addr = p->port.mapbase + S3C2410_UTXH;
if (dma_get_cache_alignment() >= 16)
dma->tx_conf.dst_maxburst = 16;
else
dma->tx_conf.dst_maxburst = 1;
dma->tx_conf.dst_maxburst = 1;
dma->rx_chan = dma_request_chan(p->port.dev, "rx");
if (IS_ERR(dma->rx_chan))
return PTR_ERR(dma->rx_chan);
if (IS_ERR(dma->rx_chan)) {
reason = "DMA RX channel request failed";
ret = PTR_ERR(dma->rx_chan);
goto err_warn;
}
ret = dma_get_slave_caps(dma->rx_chan, &dma_caps);
if (ret < 0 ||
dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {
reason = "insufficient DMA RX engine capabilities";
ret = -EOPNOTSUPP;
goto err_release_rx;
}
dmaengine_slave_config(dma->rx_chan, &dma->rx_conf);
dma->tx_chan = dma_request_chan(p->port.dev, "tx");
if (IS_ERR(dma->tx_chan)) {
reason = "DMA TX channel request failed";
ret = PTR_ERR(dma->tx_chan);
goto err_release_rx;
}
ret = dma_get_slave_caps(dma->tx_chan, &dma_caps);
if (ret < 0 ||
dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {
reason = "insufficient DMA TX engine capabilities";
ret = -EOPNOTSUPP;
goto err_release_tx;
}
dmaengine_slave_config(dma->tx_chan, &dma->tx_conf);
/* RX buffer */
......@@ -899,6 +918,7 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
dma->rx_addr = dma_map_single(p->port.dev, dma->rx_buf,
dma->rx_size, DMA_FROM_DEVICE);
if (dma_mapping_error(p->port.dev, dma->rx_addr)) {
reason = "DMA mapping error for RX buffer";
ret = -EIO;
goto err_free_rx;
}
......@@ -907,6 +927,7 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
dma->tx_addr = dma_map_single(p->port.dev, p->port.state->xmit.buf,
UART_XMIT_SIZE, DMA_TO_DEVICE);
if (dma_mapping_error(p->port.dev, dma->tx_addr)) {
reason = "DMA mapping error for TX buffer";
ret = -EIO;
goto err_unmap_rx;
}
......@@ -922,6 +943,9 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
dma_release_channel(dma->tx_chan);
err_release_rx:
dma_release_channel(dma->rx_chan);
err_warn:
if (reason)
dev_warn(p->port.dev, "%s, DMA will not be used\n", reason);
return ret;
}
......@@ -1040,8 +1064,6 @@ static int s3c64xx_serial_startup(struct uart_port *port)
if (ourport->dma) {
ret = s3c24xx_serial_request_dma(ourport);
if (ret < 0) {
dev_warn(port->dev,
"DMA request failed, DMA will not be used\n");
devm_kfree(port->dev, ourport->dma);
ourport->dma = NULL;
}
......
......@@ -1168,7 +1168,10 @@ static int sc16is7xx_probe(struct device *dev,
else
return PTR_ERR(s->clk);
} else {
clk_prepare_enable(s->clk);
ret = clk_prepare_enable(s->clk);
if (ret)
return ret;
freq = clk_get_rate(s->clk);
}
......
......@@ -674,8 +674,8 @@ static void uart_send_xchar(struct tty_struct *tty, char ch)
static void uart_throttle(struct tty_struct *tty)
{
struct uart_state *state = tty->driver_data;
upstat_t mask = UPSTAT_SYNC_FIFO;
struct uart_port *port;
upstat_t mask = 0;
port = uart_port_ref(state);
if (!port)
......@@ -703,8 +703,8 @@ static void uart_throttle(struct tty_struct *tty)
static void uart_unthrottle(struct tty_struct *tty)
{
struct uart_state *state = tty->driver_data;
upstat_t mask = UPSTAT_SYNC_FIFO;
struct uart_port *port;
upstat_t mask = 0;
port = uart_port_ref(state);
if (!port)
......
......@@ -160,6 +160,7 @@ struct sci_port {
#define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
static struct sci_port sci_ports[SCI_NPORTS];
static unsigned long sci_ports_in_use;
static struct uart_driver sci_uart_driver;
static inline struct sci_port *
......@@ -2390,6 +2391,27 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
uart_update_timeout(port, termios->c_cflag, baud);
/* byte size and parity */
switch (termios->c_cflag & CSIZE) {
case CS5:
bits = 7;
break;
case CS6:
bits = 8;
break;
case CS7:
bits = 9;
break;
default:
bits = 10;
break;
}
if (termios->c_cflag & CSTOPB)
bits++;
if (termios->c_cflag & PARENB)
bits++;
if (best_clk >= 0) {
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
switch (srr + 1) {
......@@ -2406,8 +2428,27 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
serial_port_out(port, SCSCR, scr_val | s->hscif_tot);
serial_port_out(port, SCSMR, smr_val);
serial_port_out(port, SCBRR, brr);
if (sci_getreg(port, HSSRR)->size)
serial_port_out(port, HSSRR, srr | HSCIF_SRE);
if (sci_getreg(port, HSSRR)->size) {
unsigned int hssrr = srr | HSCIF_SRE;
/* Calculate deviation from intended rate at the
* center of the last stop bit in sampling clocks.
*/
int last_stop = bits * 2 - 1;
int deviation = min_err * srr * last_stop / 2 / baud;
if (abs(deviation) >= 2) {
/* At least two sampling clocks off at the
* last stop bit; we can increase the error
* margin by shifting the sampling point.
*/
int shift = min(-8, max(7, deviation / 2));
hssrr |= (shift << HSCIF_SRHP_SHIFT) &
HSCIF_SRHP_MASK;
hssrr |= HSCIF_SRDE;
}
serial_port_out(port, HSSRR, hssrr);
}
/* Wait one bit interval */
udelay((1000000 + (baud - 1)) / baud);
......@@ -2474,27 +2515,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
* value obtained by this formula is too small. Therefore, if the value
* is smaller than 20ms, use 20ms as the timeout value for DMA.
*/
/* byte size and parity */
switch (termios->c_cflag & CSIZE) {
case CS5:
bits = 7;
break;
case CS6:
bits = 8;
break;
case CS7:
bits = 9;
break;
default:
bits = 10;
break;
}
if (termios->c_cflag & CSTOPB)
bits++;
if (termios->c_cflag & PARENB)
bits++;
s->rx_frame = (10000 * bits) / (baud / 100);
#ifdef CONFIG_SERIAL_SH_SCI_DMA
s->rx_timeout = s->buf_len_rx * 2 * s->rx_frame;
......@@ -2890,16 +2910,15 @@ static void serial_console_write(struct console *co, const char *s,
unsigned long flags;
int locked = 1;
local_irq_save(flags);
#if defined(SUPPORT_SYSRQ)
if (port->sysrq)
locked = 0;
else
#endif
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);
/* first save SCSCR then disable interrupts, keep clock source */
ctrl = serial_port_in(port, SCSCR);
......@@ -2919,8 +2938,7 @@ static void serial_console_write(struct console *co, const char *s,
serial_port_out(port, SCSCR, ctrl);
if (locked)
spin_unlock(&port->lock);
local_irq_restore(flags);
spin_unlock_irqrestore(&port->lock, flags);
}
static int serial_console_setup(struct console *co, char *options)
......@@ -3026,6 +3044,7 @@ static int sci_remove(struct platform_device *dev)
{
struct sci_port *port = platform_get_drvdata(dev);
sci_ports_in_use &= ~BIT(port->port.line);
uart_remove_one_port(&sci_uart_driver, &port->port);
sci_cleanup_single(port);
......@@ -3107,6 +3126,8 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
/* Get the line number from the aliases node. */
id = of_alias_get_id(np, "serial");
if (id < 0 && ~sci_ports_in_use)
id = ffz(sci_ports_in_use);
if (id < 0) {
dev_err(&pdev->dev, "failed to get alias id (%d)\n", id);
return NULL;
......@@ -3141,6 +3162,9 @@ static int sci_probe_single(struct platform_device *dev,
dev_notice(&dev->dev, "Consider bumping CONFIG_SERIAL_SH_SCI_NR_UARTS!\n");
return -EINVAL;
}
BUILD_BUG_ON(SCI_NPORTS > sizeof(sci_ports_in_use) * 8);
if (sci_ports_in_use & BIT(index))
return -EBUSY;
mutex_lock(&sci_uart_registration_lock);
if (!sci_uart_driver.state) {
......@@ -3239,6 +3263,7 @@ static int sci_probe(struct platform_device *dev)
sh_bios_gdb_detach();
#endif
sci_ports_in_use |= BIT(dev_id);
return 0;
}
......
......@@ -130,6 +130,10 @@ enum {
/* HSSRR HSCIF */
#define HSCIF_SRE BIT(15) /* Sampling Rate Register Enable */
#define HSCIF_SRDE BIT(14) /* Sampling Point Register Enable */
#define HSCIF_SRHP_SHIFT 8
#define HSCIF_SRHP_MASK 0x0f00
/* SCPCR (Serial Port Control Register), SCIFA/SCIFB only */
#define SCPCR_RTSC BIT(4) /* Serial Port RTS# Pin / Output Pin */
......
......@@ -842,16 +842,14 @@ static int asc_serial_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int asc_serial_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct uart_port *port = platform_get_drvdata(pdev);
struct uart_port *port = dev_get_drvdata(dev);
return uart_suspend_port(&asc_uart_driver, port);
}
static int asc_serial_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct uart_port *port = platform_get_drvdata(pdev);
struct uart_port *port = dev_get_drvdata(dev);
return uart_resume_port(&asc_uart_driver, port);
}
......
......@@ -1097,45 +1097,6 @@ static const struct uart_ops cdns_uart_ops = {
#endif
};
static struct uart_port cdns_uart_port[CDNS_UART_NR_PORTS];
/**
* cdns_uart_get_port - Configure the port from platform device resource info
* @id: Port id
*
* Return: a pointer to a uart_port or NULL for failure
*/
static struct uart_port *cdns_uart_get_port(int id)
{
struct uart_port *port;
/* Try the given port id if failed use default method */
if (id < CDNS_UART_NR_PORTS && cdns_uart_port[id].mapbase != 0) {
/* Find the next unused port */
for (id = 0; id < CDNS_UART_NR_PORTS; id++)
if (cdns_uart_port[id].mapbase == 0)
break;
}
if (id >= CDNS_UART_NR_PORTS)
return NULL;
port = &cdns_uart_port[id];
/* At this point, we've got an empty uart_port struct, initialize it */
spin_lock_init(&port->lock);
port->membase = NULL;
port->irq = 0;
port->type = PORT_UNKNOWN;
port->iotype = UPIO_MEM32;
port->flags = UPF_BOOT_AUTOCONF;
port->ops = &cdns_uart_ops;
port->fifosize = CDNS_UART_FIFO_SIZE;
port->line = id;
port->dev = NULL;
return port;
}
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/**
* cdns_uart_console_wait_tx - Wait for the TX to be full
......@@ -1206,6 +1167,10 @@ OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p8", cdns_early_console_setup);
OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p12", cdns_early_console_setup);
OF_EARLYCON_DECLARE(cdns, "xlnx,zynqmp-uart", cdns_early_console_setup);
/* Static pointer to console port */
static struct uart_port *console_port;
/**
* cdns_uart_console_write - perform write operation
* @co: Console handle
......@@ -1215,7 +1180,7 @@ OF_EARLYCON_DECLARE(cdns, "xlnx,zynqmp-uart", cdns_early_console_setup);
static void cdns_uart_console_write(struct console *co, const char *s,
unsigned int count)
{
struct uart_port *port = &cdns_uart_port[co->index];
struct uart_port *port = console_port;
unsigned long flags;
unsigned int imr, ctrl;
int locked = 1;
......@@ -1261,15 +1226,13 @@ static void cdns_uart_console_write(struct console *co, const char *s,
*/
static int __init cdns_uart_console_setup(struct console *co, char *options)
{
struct uart_port *port = &cdns_uart_port[co->index];
struct uart_port *port = console_port;
int baud = 9600;
int bits = 8;
int parity = 'n';
int flow = 'n';
if (co->index < 0 || co->index >= CDNS_UART_NR_PORTS)
return -EINVAL;
if (!port->membase) {
pr_debug("console on " CDNS_UART_TTY_NAME "%i not present\n",
co->index);
......@@ -1293,20 +1256,6 @@ static struct console cdns_uart_console = {
.index = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */
.data = &cdns_uart_uart_driver,
};
/**
* cdns_uart_console_init - Initialization call
*
* Return: 0 on success, negative errno otherwise
*/
static int __init cdns_uart_console_init(void)
{
register_console(&cdns_uart_console);
return 0;
}
console_initcall(cdns_uart_console_init);
#endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */
static struct uart_driver cdns_uart_uart_driver = {
......@@ -1430,8 +1379,7 @@ static int cdns_uart_resume(struct device *device)
#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 uart_port *port = dev_get_drvdata(dev);
struct cdns_uart *cdns_uart = port->private_data;
clk_disable(cdns_uart->uartclk);
......@@ -1441,8 +1389,7 @@ static int __maybe_unused cdns_runtime_suspend(struct device *dev)
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 uart_port *port = dev_get_drvdata(dev);
struct cdns_uart *cdns_uart = port->private_data;
clk_enable(cdns_uart->pclk);
......@@ -1487,6 +1434,9 @@ static int cdns_uart_probe(struct platform_device *pdev)
GFP_KERNEL);
if (!cdns_uart_data)
return -ENOMEM;
port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
if (match && match->data) {
......@@ -1552,15 +1502,24 @@ static int cdns_uart_probe(struct platform_device *pdev)
if (id < 0)
id = 0;
/* Initialize the port structure */
port = cdns_uart_get_port(id);
if (!port) {
if (id >= CDNS_UART_NR_PORTS) {
dev_err(&pdev->dev, "Cannot get uart_port structure\n");
rc = -ENODEV;
goto err_out_notif_unreg;
}
/* At this point, we've got an empty uart_port struct, initialize it */
spin_lock_init(&port->lock);
port->membase = NULL;
port->irq = 0;
port->type = PORT_UNKNOWN;
port->iotype = UPIO_MEM32;
port->flags = UPF_BOOT_AUTOCONF;
port->ops = &cdns_uart_ops;
port->fifosize = CDNS_UART_FIFO_SIZE;
port->line = id;
port->dev = NULL;
/*
* Register the port.
* This function also registers this device with the tty layer
......@@ -1579,6 +1538,17 @@ static int cdns_uart_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/*
* If console hasn't been found yet try to assign this port
* because it is required to be assigned for console setup function.
* If register_console() don't assign value, then console_port pointer
* is cleanup.
*/
if (cdns_uart_uart_driver.cons->index == -1)
console_port = port;
#endif
rc = uart_add_one_port(&cdns_uart_uart_driver, port);
if (rc) {
dev_err(&pdev->dev,
......@@ -1586,6 +1556,12 @@ static int cdns_uart_probe(struct platform_device *pdev)
goto err_out_pm_disable;
}
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/* This is not port which is used for console that's why clean it up */
if (cdns_uart_uart_driver.cons->index == -1)
console_port = NULL;
#endif
return 0;
err_out_pm_disable:
......
......@@ -1178,15 +1178,8 @@ static void csi_J(struct vc_data *vc, int vpar)
count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
start = (unsigned short *)vc->vc_origin;
break;
case 3: /* erase scroll-back buffer (and whole display) */
scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
vc->vc_screenbuf_size);
flush_scrollback(vc);
set_origin(vc);
if (con_is_visible(vc))
update_screen(vc);
/* fall through */
case 2: /* erase whole display */
case 3: /* (and scrollback buffer later) */
count = vc->vc_cols * vc->vc_rows;
start = (unsigned short *)vc->vc_origin;
break;
......@@ -1194,7 +1187,12 @@ static void csi_J(struct vc_data *vc, int vpar)
return;
}
scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
if (con_should_update(vc))
if (vpar == 3) {
set_origin(vc);
flush_scrollback(vc);
if (con_is_visible(vc))
update_screen(vc);
} else if (con_should_update(vc))
do_update_region(vc, (unsigned long) start, count);
vc->vc_need_wrap = 0;
}
......
......@@ -163,6 +163,7 @@ extern void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl);
extern int fsl8250_handle_irq(struct uart_port *port);
int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr);
void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr);
void serial8250_tx_chars(struct uart_8250_port *up);
unsigned int serial8250_modem_status(struct uart_8250_port *up);
void serial8250_init_port(struct uart_8250_port *up);
......
......@@ -233,6 +233,7 @@ struct uart_port {
#define UPSTAT_AUTORTS ((__force upstat_t) (1 << 2))
#define UPSTAT_AUTOCTS ((__force upstat_t) (1 << 3))
#define UPSTAT_AUTOXOFF ((__force upstat_t) (1 << 4))
#define UPSTAT_SYNC_FIFO ((__force upstat_t) (1 << 5))
int hw_stopped; /* sw-assisted CTS flow state */
unsigned int mctrl; /* current modem ctrl settings */
......@@ -348,7 +349,8 @@ struct earlycon_device {
};
struct earlycon_id {
char name[16];
char name[15];
char name_term; /* In case compiler didn't '\0' term name */
char compatible[128];
int (*setup)(struct earlycon_device *, const char *options);
};
......
......@@ -13,7 +13,7 @@
*/
#define ASYNCB_HUP_NOTIFY 0 /* Notify getty on hangups and closes
* on the callout port */
#define ASYNCB_FOURPORT 1 /* Set OU1, OUT2 per AST Fourport settings */
#define ASYNCB_FOURPORT 1 /* Set OUT1, OUT2 per AST Fourport settings */
#define ASYNCB_SAK 2 /* Secure Attention Key (Orange book) */
#define ASYNCB_SPLIT_TERMIOS 3 /* [x] Separate termios for dialin/callout */
#define ASYNCB_SPD_HI 4 /* Use 57600 instead of 38400 bps */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册