Skip to content

Commit

Permalink
Merge tag 'tty-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/tty

Pull tty/serial driver updates from Greg KH:
 "Here's the big tty/serial driver update for 3.13-rc1.

  There's some more minor n_tty work here, but nothing like previous
  kernel releases.  Also some new driver ids, driver updates for new
  hardware, and other small things.

  All of this has been in linux-next for a while with no issues"

* tag 'tty-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (84 commits)
  serial: omap: fix missing comma
  serial: sh-sci: Enable the driver on all ARM platforms
  serial: mfd: Staticize local symbols
  serial: omap: fix a few checkpatch warnings
  serial: omap: improve RS-485 performance
  mrst_max3110: fix unbalanced IRQ issue during resume
  serial: omap: Add support for optional wake-up
  serial: sirf: remove duplicate defines
  tty: xuartps: Fix build error when COMMON_CLK is not set
  tty: xuartps: Fix build error due to missing forward declaration
  tty: xuartps: Fix "may be used uninitialized" build warning
  serial: 8250_pci: add Pericom PCIe Serial board Support (12d8:7952/4/8) - Chip PI7C9X7952/4/8
  tty: xuartps: Update copyright information
  tty: xuartps: Implement suspend/resume callbacks
  tty: xuartps: Dynamically adjust to input frequency changes
  tty: xuartps: Updating set_baud_rate()
  tty: xuartps: Force enable the UART in xuartps_console_write
  tty: xuartps: support 64 byte FIFO size
  tty: xuartps: Add polled mode support for xuartps
  tty: xuartps: Implement BREAK detection, add SYSRQ support
  ...
  • Loading branch information
Linus Torvalds committed Nov 7, 2013
2 parents 0324e74 + 80d8611 commit 56edff7
Show file tree
Hide file tree
Showing 53 changed files with 1,200 additions and 364 deletions.
4 changes: 0 additions & 4 deletions Documentation/serial/driver
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,6 @@ hardware.
Locking: none.
Interrupts: caller dependent.

set_wake(port,state)
Enable/disable power management wakeup on serial activity. Not
currently implemented.

type(port)
Return a pointer to a string constant describing the specified
port, or return NULL, in which case the string 'unknown' is
Expand Down
28 changes: 15 additions & 13 deletions Documentation/sysrq.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,29 @@ regardless of whatever else it is doing, unless it is completely locked up.
You need to say "yes" to 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' when
configuring the kernel. When running a kernel with SysRq compiled in,
/proc/sys/kernel/sysrq controls the functions allowed to be invoked via
the SysRq key. By default the file contains 1 which means that every
possible SysRq request is allowed (in older versions SysRq was disabled
by default, and you were required to specifically enable it at run-time
but this is not the case any more). Here is the list of possible values
in /proc/sys/kernel/sysrq:
the SysRq key. The default value in this file is set by the
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE config symbol, which itself defaults
to 1. Here is the list of possible values in /proc/sys/kernel/sysrq:
0 - disable sysrq completely
1 - enable all functions of sysrq
>1 - bitmask of allowed sysrq functions (see below for detailed function
description):
2 - enable control of console logging level
4 - enable control of keyboard (SAK, unraw)
8 - enable debugging dumps of processes etc.
16 - enable sync command
32 - enable remount read-only
64 - enable signalling of processes (term, kill, oom-kill)
128 - allow reboot/poweroff
256 - allow nicing of all RT tasks
2 = 0x2 - enable control of console logging level
4 = 0x4 - enable control of keyboard (SAK, unraw)
8 = 0x8 - enable debugging dumps of processes etc.
16 = 0x10 - enable sync command
32 = 0x20 - enable remount read-only
64 = 0x40 - enable signalling of processes (term, kill, oom-kill)
128 = 0x80 - allow reboot/poweroff
256 = 0x100 - allow nicing of all RT tasks

You can set the value in the file by the following command:
echo "number" >/proc/sys/kernel/sysrq

The number may be written here either as decimal or as hexadecimal
with the 0x prefix. CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE must always be
written in hexadecimal.

Note that the value of /proc/sys/kernel/sysrq influences only the invocation
via a keyboard. Invocation of any operation via /proc/sysrq-trigger is always
allowed (by a user with admin privileges).
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/bfin_jtag_comm.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ bfin_jc_early_write(struct console *co, const char *buf, unsigned int count)
bfin_jc_straight_buffer_write(buf, count);
}

static struct __initdata console bfin_jc_early_console = {
static struct console bfin_jc_early_console __initdata = {
.name = "early_BFJC",
.write = bfin_jc_early_write,
.flags = CON_ANYTIME | CON_PRINTBUFFER,
Expand Down
21 changes: 21 additions & 0 deletions drivers/tty/hvc/hvc_dcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,41 @@ static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
return i;
}

static bool hvc_dcc_check(void)
{
unsigned long time = jiffies + (HZ / 10);

/* Write a test character to check if it is handled */
__dcc_putchar('\n');

while (time_is_after_jiffies(time)) {
if (!(__dcc_getstatus() & DCC_STATUS_TX))
return true;
}

return false;
}

static const struct hv_ops hvc_dcc_get_put_ops = {
.get_chars = hvc_dcc_get_chars,
.put_chars = hvc_dcc_put_chars,
};

static int __init hvc_dcc_console_init(void)
{
if (!hvc_dcc_check())
return -ENODEV;

hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
return 0;
}
console_initcall(hvc_dcc_console_init);

static int __init hvc_dcc_init(void)
{
if (!hvc_dcc_check())
return -ENODEV;

hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
return 0;
}
Expand Down
5 changes: 4 additions & 1 deletion drivers/tty/hvc/hvc_vio.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <asm/prom.h>
#include <asm/hvsi.h>
#include <asm/udbg.h>
#include <asm/machdep.h>

#include "hvc_console.h"

Expand Down Expand Up @@ -457,7 +458,9 @@ void __init hvc_vio_init_early(void)
if (hvterm_priv0.proto == HV_PROTOCOL_HVSI)
goto out;
#endif
add_preferred_console("hvc", 0, NULL);
/* Check whether the user has requested a different console. */
if (!strstr(cmd_line, "console="))
add_preferred_console("hvc", 0, NULL);
hvc_instantiate(0, 0, ops);
out:
of_node_put(stdout_node);
Expand Down
13 changes: 3 additions & 10 deletions drivers/tty/n_tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ static size_t __process_echoes(struct tty_struct *tty)
* of echo overrun before the next commit), then discard enough
* data at the tail to prevent a subsequent overrun */
while (ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) {
if (echo_buf(ldata, tail == ECHO_OP_START)) {
if (echo_buf(ldata, tail) == ECHO_OP_START) {
if (echo_buf(ldata, tail) == ECHO_OP_ERASE_TAB)
tail += 3;
else
Expand Down Expand Up @@ -1752,20 +1752,14 @@ int is_ignored(int sig)
static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
{
struct n_tty_data *ldata = tty->disc_data;
int canon_change = 1;

if (old)
canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON;
if (canon_change) {
if (!old || (old->c_lflag ^ tty->termios.c_lflag) & ICANON) {
bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
ldata->line_start = ldata->canon_head = ldata->read_tail;
ldata->erasing = 0;
ldata->lnext = 0;
}

if (canon_change && !L_ICANON(tty) && read_cnt(ldata))
wake_up_interruptible(&tty->read_wait);

ldata->icanon = (L_ICANON(tty) != 0);

if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
Expand Down Expand Up @@ -1820,9 +1814,8 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
* Fix tty hang when I_IXON(tty) is cleared, but the tty
* been stopped by STOP_CHAR(tty) before it.
*/
if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) {
if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped)
start_tty(tty);
}

/* The termios change make the tty ready for I/O */
wake_up_interruptible(&tty->write_wait);
Expand Down
6 changes: 3 additions & 3 deletions drivers/tty/nozomi.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,7 @@ static int receive_flow_control(struct nozomi *dc)
dev_err(&dc->pdev->dev,
"ERROR: flow control received for non-existing port\n");
return 0;
};
}

DBG1("0x%04X->0x%04X", *((u16 *)&dc->port[port].ctrl_dl),
*((u16 *)&ctrl_dl));
Expand Down Expand Up @@ -1025,7 +1025,7 @@ static enum ctrl_port_type port2ctrl(enum port_type port,
dev_err(&dc->pdev->dev,
"ERROR: send flow control " \
"received for non-existing port\n");
};
}
return CTRL_ERROR;
}

Expand Down Expand Up @@ -1805,7 +1805,7 @@ static int ntty_ioctl(struct tty_struct *tty,
default:
DBG1("ERR: 0x%08X, %d", cmd, cmd);
break;
};
}

return rval;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/serial/8250/8250_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2322,7 +2322,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,

if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
fcr = uart_config[port->type].fcr;
if (baud < 2400 || fifo_bug) {
if ((baud < 2400 && !up->dma) || fifo_bug) {
fcr &= ~UART_FCR_TRIGGER_MASK;
fcr |= UART_FCR_TRIGGER_1;
}
Expand Down
76 changes: 57 additions & 19 deletions drivers/tty/serial/8250/8250_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@


struct dw8250_data {
int last_lcr;
int last_mcr;
int line;
struct clk *clk;
u8 usr_reg;
u8 usr_reg;
int last_mcr;
int line;
struct clk *clk;
struct uart_8250_dma dma;
};

static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
Expand All @@ -76,17 +76,33 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
return value;
}

static void dw8250_force_idle(struct uart_port *p)
{
serial8250_clear_and_reinit_fifos(container_of
(p, struct uart_8250_port, port));
(void)p->serial_in(p, UART_RX);
}

static void dw8250_serial_out(struct uart_port *p, int offset, int value)
{
struct dw8250_data *d = p->private_data;

if (offset == UART_LCR)
d->last_lcr = value;

if (offset == UART_MCR)
d->last_mcr = value;

writeb(value, p->membase + (offset << p->regshift));

/* Make sure LCR write wasn't ignored */
if (offset == UART_LCR) {
int tries = 1000;
while (tries--) {
if (value == p->serial_in(p, UART_LCR))
return;
dw8250_force_idle(p);
writeb(value, p->membase + (UART_LCR << p->regshift));
}
dev_err(p->dev, "Couldn't set LCR to %d\n", value);
}
}

static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
Expand All @@ -107,13 +123,22 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
{
struct dw8250_data *d = p->private_data;

if (offset == UART_LCR)
d->last_lcr = value;

if (offset == UART_MCR)
d->last_mcr = value;

writel(value, p->membase + (offset << p->regshift));

/* Make sure LCR write wasn't ignored */
if (offset == UART_LCR) {
int tries = 1000;
while (tries--) {
if (value == p->serial_in(p, UART_LCR))
return;
dw8250_force_idle(p);
writel(value, p->membase + (UART_LCR << p->regshift));
}
dev_err(p->dev, "Couldn't set LCR to %d\n", value);
}
}

static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
Expand All @@ -131,9 +156,8 @@ static int dw8250_handle_irq(struct uart_port *p)
if (serial8250_handle_irq(p, iir)) {
return 1;
} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
/* Clear the USR and write the LCR again. */
/* Clear the USR */
(void)p->serial_in(p, d->usr_reg);
p->serial_out(p, UART_LCR, d->last_lcr);

return 1;
}
Expand All @@ -153,6 +177,14 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
pm_runtime_put_sync_suspend(port->dev);
}

static bool dw8250_dma_filter(struct dma_chan *chan, void *param)
{
struct dw8250_data *data = param;

return chan->chan_id == data->dma.tx_chan_id ||
chan->chan_id == data->dma.rx_chan_id;
}

static void dw8250_setup_port(struct uart_8250_port *up)
{
struct uart_port *p = &up->port;
Expand Down Expand Up @@ -241,7 +273,8 @@ static int dw8250_probe_of(struct uart_port *p,
}

#ifdef CONFIG_ACPI
static int dw8250_probe_acpi(struct uart_8250_port *up)
static int dw8250_probe_acpi(struct uart_8250_port *up,
struct dw8250_data *data)
{
const struct acpi_device_id *id;
struct uart_port *p = &up->port;
Expand All @@ -260,17 +293,16 @@ static int dw8250_probe_acpi(struct uart_8250_port *up)
if (!p->uartclk)
p->uartclk = (unsigned int)id->driver_data;

up->dma = devm_kzalloc(p->dev, sizeof(*up->dma), GFP_KERNEL);
if (!up->dma)
return -ENOMEM;
up->dma = &data->dma;

up->dma->rxconf.src_maxburst = p->fifosize / 4;
up->dma->txconf.dst_maxburst = p->fifosize / 4;

return 0;
}
#else
static inline int dw8250_probe_acpi(struct uart_8250_port *up)
static inline int dw8250_probe_acpi(struct uart_8250_port *up,
struct dw8250_data *data)
{
return -ENODEV;
}
Expand Down Expand Up @@ -314,6 +346,12 @@ static int dw8250_probe(struct platform_device *pdev)
uart.port.uartclk = clk_get_rate(data->clk);
}

data->dma.rx_chan_id = -1;
data->dma.tx_chan_id = -1;
data->dma.rx_param = data;
data->dma.tx_param = data;
data->dma.fn = dw8250_dma_filter;

uart.port.iotype = UPIO_MEM;
uart.port.serial_in = dw8250_serial_in;
uart.port.serial_out = dw8250_serial_out;
Expand All @@ -324,7 +362,7 @@ static int dw8250_probe(struct platform_device *pdev)
if (err)
return err;
} else if (ACPI_HANDLE(&pdev->dev)) {
err = dw8250_probe_acpi(&uart);
err = dw8250_probe_acpi(&uart, data);
if (err)
return err;
} else {
Expand Down
6 changes: 3 additions & 3 deletions drivers/tty/serial/8250/8250_em.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static int serial8250_em_probe(struct platform_device *pdev)
up.port.dev = &pdev->dev;
up.port.private_data = priv;

clk_enable(priv->sclk);
clk_prepare_enable(priv->sclk);
up.port.uartclk = clk_get_rate(priv->sclk);

up.port.iotype = UPIO_MEM32;
Expand All @@ -134,7 +134,7 @@ static int serial8250_em_probe(struct platform_device *pdev)
ret = serial8250_register_8250_port(&up);
if (ret < 0) {
dev_err(&pdev->dev, "unable to register 8250 port\n");
clk_disable(priv->sclk);
clk_disable_unprepare(priv->sclk);
return ret;
}

Expand All @@ -148,7 +148,7 @@ static int serial8250_em_remove(struct platform_device *pdev)
struct serial8250_em_priv *priv = platform_get_drvdata(pdev);

serial8250_unregister_port(priv->line);
clk_disable(priv->sclk);
clk_disable_unprepare(priv->sclk);
return 0;
}

Expand Down
Loading

0 comments on commit 56edff7

Please sign in to comment.