summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-06-05 20:28:59 +1000
committerDave Airlie <airlied@redhat.com>2014-06-05 20:28:59 +1000
commit8d4ad9d4bb0a618c975a32d77087694ec6336f68 (patch)
treed18d12688174a623e3503b11118e44ef8186c90b /drivers/tty
parent5ea1f752ae04be403a3dc8ec876a60d7f5f6990a (diff)
parent9e9a928eed8796a0a1aaed7e0b676db86ba84594 (diff)
Merge commit '9e9a928eed8796a0a1aaed7e0b676db86ba84594' into drm-next
Merge drm-fixes into drm-next. Both i915 and radeon need this done for later patches. Conflicts: drivers/gpu/drm/drm_crtc_helper.c drivers/gpu/drm/i915/i915_drv.h drivers/gpu/drm/i915/i915_gem.c drivers/gpu/drm/i915/i915_gem_execbuffer.c drivers/gpu/drm/i915/i915_gem_gtt.c
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/hvc/hvc_console.c2
-rw-r--r--drivers/tty/n_tty.c4
-rw-r--r--drivers/tty/serial/8250/8250_core.c2
-rw-r--r--drivers/tty/tty_buffer.c31
4 files changed, 22 insertions, 17 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 94f9e3a38412..0ff7fda0742f 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -190,7 +190,7 @@ static struct tty_driver *hvc_console_device(struct console *c, int *index)
return hvc_driver;
}
-static int __init hvc_console_setup(struct console *co, char *options)
+static int hvc_console_setup(struct console *co, char *options)
{
if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
return -ENODEV;
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 41fe8a047d37..fe9d129c8735 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -2353,8 +2353,12 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
if (tty->ops->flush_chars)
tty->ops->flush_chars(tty);
} else {
+ struct n_tty_data *ldata = tty->disc_data;
+
while (nr > 0) {
+ mutex_lock(&ldata->output_lock);
c = tty->ops->write(tty, b, nr);
+ mutex_unlock(&ldata->output_lock);
if (c < 0) {
retval = c;
goto break_out;
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 0e1bf8858431..2d4bd3929e50 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -555,7 +555,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
*/
if ((p->port.type == PORT_XR17V35X) ||
(p->port.type == PORT_XR17D15X)) {
- serial_out(p, UART_EXAR_SLEEP, 0xff);
+ serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0);
return;
}
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index f1d30f6945af..143deb62467d 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -60,6 +60,7 @@ void tty_buffer_lock_exclusive(struct tty_port *port)
atomic_inc(&buf->priority);
mutex_lock(&buf->lock);
}
+EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive);
void tty_buffer_unlock_exclusive(struct tty_port *port)
{
@@ -73,6 +74,7 @@ void tty_buffer_unlock_exclusive(struct tty_port *port)
if (restart)
queue_work(system_unbound_wq, &buf->work);
}
+EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive);
/**
* tty_buffer_space_avail - return unused buffer space
@@ -255,16 +257,15 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size,
if (change || left < size) {
/* This is the slow path - looking for new buffers to use */
if ((n = tty_buffer_alloc(port, size)) != NULL) {
- unsigned long iflags;
-
n->flags = flags;
buf->tail = n;
-
- spin_lock_irqsave(&buf->flush_lock, iflags);
b->commit = b->used;
+ /* paired w/ barrier in flush_to_ldisc(); ensures the
+ * latest commit value can be read before the head is
+ * advanced to the next buffer
+ */
+ smp_wmb();
b->next = n;
- spin_unlock_irqrestore(&buf->flush_lock, iflags);
-
} else if (change)
size = 0;
else
@@ -448,27 +449,28 @@ static void flush_to_ldisc(struct work_struct *work)
mutex_lock(&buf->lock);
while (1) {
- unsigned long flags;
struct tty_buffer *head = buf->head;
+ struct tty_buffer *next;
int count;
/* Ldisc or user is trying to gain exclusive access */
if (atomic_read(&buf->priority))
break;
- spin_lock_irqsave(&buf->flush_lock, flags);
+ next = head->next;
+ /* paired w/ barrier in __tty_buffer_request_room();
+ * ensures commit value read is not stale if the head
+ * is advancing to the next buffer
+ */
+ smp_rmb();
count = head->commit - head->read;
if (!count) {
- if (head->next == NULL) {
- spin_unlock_irqrestore(&buf->flush_lock, flags);
+ if (next == NULL)
break;
- }
- buf->head = head->next;
- spin_unlock_irqrestore(&buf->flush_lock, flags);
+ buf->head = next;
tty_buffer_free(port, head);
continue;
}
- spin_unlock_irqrestore(&buf->flush_lock, flags);
count = receive_buf(tty, head, count);
if (!count)
@@ -523,7 +525,6 @@ void tty_buffer_init(struct tty_port *port)
struct tty_bufhead *buf = &port->buf;
mutex_init(&buf->lock);
- spin_lock_init(&buf->flush_lock);
tty_buffer_reset(&buf->sentinel, 0);
buf->head = &buf->sentinel;
buf->tail = &buf->sentinel;