summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-18 16:57:53 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-18 16:57:53 -0700
commit575a2929815bca197983a22fe6d072534d219be4 (patch)
tree77960b02f5ff4c43c29152119f82658c9bbd0b2d /drivers
parent7e55f81ecf592d269b9430d9c06db509fc3f19f9 (diff)
parent12de375ec493ab1767d4a07dde823e63ae5edc21 (diff)
Merge tag 'tty-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver fixes from Greg KH: "Here are a number of small tty/serial driver fixes for 3.15-rc2. Also in here are some Documentation file removals for drivers that we removed a long time ago, no need to keep it around any longer. All of these have been in linux-next for a bit" * tag 'tty-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: Revert "serial: 8250, disable "too much work" messages" serial: amba-pl011: fix regression, causing an Oops on rmmod tty: Fix help text of SYNCLINK_CS tty: fix memleak in alloc_pid ttyprintk: Allow built as a module ttyprintk: Fix wrong tty_unregister_driver() call in the error path serial: 8250, disable "too much work" messages Documentation/serial: Delete obsolete driver documentation serial: omap: Fix missing pm_runtime_resume handling by simplifying code serial_core: Fix pm imbalance on unbind serial: pl011: change Rx burst size to half of trigger level serial: timberdale: Depend on X86_32 serial: st-asc: Fix SysRq char handling Revert "serial: clps711x: Give a chance to perform useful tasks during wait loop" serial_core: Fix conditional start_tx on ring buffer not empty serial: efm32: use $vendor,$device scheme for compatible string serial: omap: free the wakeup settings in remove
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/pcmcia/Kconfig2
-rw-r--r--drivers/char/ttyprintk.c15
-rw-r--r--drivers/tty/serial/Kconfig1
-rw-r--r--drivers/tty/serial/amba-pl011.c8
-rw-r--r--drivers/tty/serial/clps711x.c20
-rw-r--r--drivers/tty/serial/efm32-uart.c3
-rw-r--r--drivers/tty/serial/omap-serial.c30
-rw-r--r--drivers/tty/serial/serial_core.c5
-rw-r--r--drivers/tty/serial/st-asc.c4
-rw-r--r--drivers/tty/tty_io.c4
11 files changed, 55 insertions, 39 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index fbae63e3d304..6e9f74a5c095 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -40,7 +40,7 @@ config SGI_MBCS
source "drivers/tty/serial/Kconfig"
config TTY_PRINTK
- bool "TTY driver to output user messages via printk"
+ tristate "TTY driver to output user messages via printk"
depends on EXPERT && TTY
default n
---help---
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig
index b27f5342fe76..8d3dfb0c8a26 100644
--- a/drivers/char/pcmcia/Kconfig
+++ b/drivers/char/pcmcia/Kconfig
@@ -15,7 +15,7 @@ config SYNCLINK_CS
This driver may be built as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
- The module will be called synclinkmp. If you want to do that, say M
+ The module will be called synclink_cs. If you want to do that, say M
here.
config CARDMAN_4000
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
index daea84c41743..a15ce4ef39cd 100644
--- a/drivers/char/ttyprintk.c
+++ b/drivers/char/ttyprintk.c
@@ -17,7 +17,7 @@
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
-#include <linux/export.h>
+#include <linux/module.h>
struct ttyprintk_port {
struct tty_port port;
@@ -210,10 +210,19 @@ static int __init ttyprintk_init(void)
return 0;
error:
- tty_unregister_driver(ttyprintk_driver);
put_tty_driver(ttyprintk_driver);
tty_port_destroy(&tpk_port.port);
- ttyprintk_driver = NULL;
return ret;
}
+
+static void __exit ttyprintk_exit(void)
+{
+ tty_unregister_driver(ttyprintk_driver);
+ put_tty_driver(ttyprintk_driver);
+ tty_port_destroy(&tpk_port.port);
+}
+
device_initcall(ttyprintk_init);
+module_exit(ttyprintk_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 2e6d8ddc4425..5d9b01aa54f4 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1226,6 +1226,7 @@ config SERIAL_BFIN_SPORT3_UART_CTSRTS
config SERIAL_TIMBERDALE
tristate "Support for timberdale UART"
select SERIAL_CORE
+ depends on X86_32 || COMPILE_TEST
---help---
Add support for UART controller on timberdale.
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index d4eda24aa68b..dacf0a09ab24 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -318,7 +318,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *
.src_addr = uap->port.mapbase + UART01x_DR,
.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.direction = DMA_DEV_TO_MEM,
- .src_maxburst = uap->fifosize >> 1,
+ .src_maxburst = uap->fifosize >> 2,
.device_fc = false,
};
@@ -2176,6 +2176,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
static int pl011_remove(struct amba_device *dev)
{
struct uart_amba_port *uap = amba_get_drvdata(dev);
+ bool busy = false;
int i;
uart_remove_one_port(&amba_reg, &uap->port);
@@ -2183,9 +2184,12 @@ static int pl011_remove(struct amba_device *dev)
for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
if (amba_ports[i] == uap)
amba_ports[i] = NULL;
+ else if (amba_ports[i])
+ busy = true;
pl011_dma_remove(uap);
- uart_unregister_driver(&amba_reg);
+ if (!busy)
+ uart_unregister_driver(&amba_reg);
return 0;
}
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index 5e6fdb1ea73b..14aaea0d4131 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -368,16 +368,12 @@ static const struct uart_ops uart_clps711x_ops = {
static void uart_clps711x_console_putchar(struct uart_port *port, int ch)
{
struct clps711x_port *s = dev_get_drvdata(port->dev);
+ u32 sysflg = 0;
/* Wait for FIFO is not full */
- while (1) {
- u32 sysflg = 0;
-
+ do {
regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
- if (!(sysflg & SYSFLG_UTXFF))
- break;
- cond_resched();
- }
+ } while (sysflg & SYSFLG_UTXFF);
writew(ch, port->membase + UARTDR_OFFSET);
}
@@ -387,18 +383,14 @@ static void uart_clps711x_console_write(struct console *co, const char *c,
{
struct uart_port *port = clps711x_uart.state[co->index].uart_port;
struct clps711x_port *s = dev_get_drvdata(port->dev);
+ u32 sysflg = 0;
uart_console_write(port, c, n, uart_clps711x_console_putchar);
/* Wait for transmitter to become empty */
- while (1) {
- u32 sysflg = 0;
-
+ do {
regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
- if (!(sysflg & SYSFLG_UBUSY))
- break;
- cond_resched();
- }
+ } while (sysflg & SYSFLG_UBUSY);
}
static int uart_clps711x_console_setup(struct console *co, char *options)
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c
index 028582e924a5..c167a710dc39 100644
--- a/drivers/tty/serial/efm32-uart.c
+++ b/drivers/tty/serial/efm32-uart.c
@@ -798,6 +798,9 @@ static int efm32_uart_remove(struct platform_device *pdev)
static const struct of_device_id efm32_uart_dt_ids[] = {
{
+ .compatible = "energymicro,efm32-uart",
+ }, {
+ /* doesn't follow the "vendor,device" scheme, don't use */
.compatible = "efm32,uart",
}, {
/* sentinel */
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index dd8b1a5458ff..08b6b9419f0d 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -225,14 +225,19 @@ static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up,
if (enable)
enable_irq(up->wakeirq);
else
- disable_irq(up->wakeirq);
+ disable_irq_nosync(up->wakeirq);
}
static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
{
struct omap_uart_port_info *pdata = dev_get_platdata(up->dev);
+ if (enable == up->wakeups_enabled)
+ return;
+
serial_omap_enable_wakeirq(up, enable);
+ up->wakeups_enabled = enable;
+
if (!pdata || !pdata->enable_wakeup)
return;
@@ -1495,6 +1500,11 @@ static int serial_omap_suspend(struct device *dev)
uart_suspend_port(&serial_omap_reg, &up->port);
flush_work(&up->qos_work);
+ if (device_may_wakeup(dev))
+ serial_omap_enable_wakeup(up, true);
+ else
+ serial_omap_enable_wakeup(up, false);
+
return 0;
}
@@ -1502,6 +1512,9 @@ static int serial_omap_resume(struct device *dev)
{
struct uart_omap_port *up = dev_get_drvdata(dev);
+ if (device_may_wakeup(dev))
+ serial_omap_enable_wakeup(up, false);
+
uart_resume_port(&serial_omap_reg, &up->port);
return 0;
@@ -1789,6 +1802,7 @@ static int serial_omap_remove(struct platform_device *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);
return 0;
}
@@ -1877,17 +1891,7 @@ static int serial_omap_runtime_suspend(struct device *dev)
up->context_loss_cnt = serial_omap_get_context_loss_count(up);
- if (device_may_wakeup(dev)) {
- if (!up->wakeups_enabled) {
- serial_omap_enable_wakeup(up, true);
- up->wakeups_enabled = true;
- }
- } else {
- if (up->wakeups_enabled) {
- serial_omap_enable_wakeup(up, false);
- up->wakeups_enabled = false;
- }
- }
+ serial_omap_enable_wakeup(up, true);
up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
schedule_work(&up->qos_work);
@@ -1901,6 +1905,8 @@ static int serial_omap_runtime_resume(struct device *dev)
int loss_cnt = serial_omap_get_context_loss_count(up);
+ serial_omap_enable_wakeup(up, false);
+
if (loss_cnt < 0) {
dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n",
loss_cnt);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 2cf5649a6dc0..f26834d262b3 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -89,8 +89,7 @@ static void __uart_start(struct tty_struct *tty)
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->uart_port;
- if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&
- !tty->stopped && !tty->hw_stopped)
+ if (!tty->stopped && !tty->hw_stopped)
port->ops->start_tx(port);
}
@@ -1452,6 +1451,8 @@ static void uart_hangup(struct tty_struct *tty)
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
spin_unlock_irqrestore(&port->lock, flags);
tty_port_tty_set(port, NULL);
+ if (!uart_console(state->uart_port))
+ uart_change_pm(state, UART_PM_STATE_OFF);
wake_up_interruptible(&port->open_wait);
wake_up_interruptible(&port->delta_msr_wait);
}
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index 21e6e84c0df8..dd3a96e07026 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -295,7 +295,7 @@ static void asc_receive_chars(struct uart_port *port)
status & ASC_STA_OE) {
if (c & ASC_RXBUF_FE) {
- if (c == ASC_RXBUF_FE) {
+ if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) {
port->icount.brk++;
if (uart_handle_break(port))
continue;
@@ -325,7 +325,7 @@ static void asc_receive_chars(struct uart_port *port)
flag = TTY_FRAME;
}
- if (uart_handle_sysrq_char(port, c))
+ if (uart_handle_sysrq_char(port, c & 0xff))
continue;
uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index d3448a90f0f9..34110719fe03 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -878,9 +878,8 @@ void disassociate_ctty(int on_exit)
spin_lock_irq(&current->sighand->siglock);
put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
- spin_unlock_irq(&current->sighand->siglock);
- tty = get_current_tty();
+ tty = tty_kref_get(current->signal->tty);
if (tty) {
unsigned long flags;
spin_lock_irqsave(&tty->ctrl_lock, flags);
@@ -897,6 +896,7 @@ void disassociate_ctty(int on_exit)
#endif
}
+ spin_unlock_irq(&current->sighand->siglock);
/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
session_clear_tty(task_session(current));