aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/amiserial.c3
-rw-r--r--drivers/tty/n_tty.c27
-rw-r--r--drivers/tty/serial/8250/8250_dw.c8
-rw-r--r--drivers/tty/serial/8250/Kconfig2
-rw-r--r--drivers/tty/serial/pmac_zilog.c3
-rw-r--r--drivers/tty/serial/xilinx_uartps.c2
-rw-r--r--drivers/tty/tty_io.c1
-rw-r--r--drivers/tty/tty_ldsem.c16
8 files changed, 48 insertions, 14 deletions
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 2b86f8e0fb58..71630a2af42c 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1855,6 +1855,9 @@ static struct console sercons = {
1855 */ 1855 */
1856static int __init amiserial_console_init(void) 1856static int __init amiserial_console_init(void)
1857{ 1857{
1858 if (!MACH_IS_AMIGA)
1859 return -ENODEV;
1860
1858 register_console(&sercons); 1861 register_console(&sercons);
1859 return 0; 1862 return 0;
1860} 1863}
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 7cdd1eb9406c..34aacaaae14a 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -93,6 +93,7 @@ struct n_tty_data {
93 size_t canon_head; 93 size_t canon_head;
94 size_t echo_head; 94 size_t echo_head;
95 size_t echo_commit; 95 size_t echo_commit;
96 size_t echo_mark;
96 DECLARE_BITMAP(char_map, 256); 97 DECLARE_BITMAP(char_map, 256);
97 98
98 /* private to n_tty_receive_overrun (single-threaded) */ 99 /* private to n_tty_receive_overrun (single-threaded) */
@@ -336,6 +337,7 @@ static void reset_buffer_flags(struct n_tty_data *ldata)
336{ 337{
337 ldata->read_head = ldata->canon_head = ldata->read_tail = 0; 338 ldata->read_head = ldata->canon_head = ldata->read_tail = 0;
338 ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0; 339 ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0;
340 ldata->echo_mark = 0;
339 ldata->line_start = 0; 341 ldata->line_start = 0;
340 342
341 ldata->erasing = 0; 343 ldata->erasing = 0;
@@ -768,7 +770,7 @@ static size_t __process_echoes(struct tty_struct *tty)
768 * data at the tail to prevent a subsequent overrun */ 770 * data at the tail to prevent a subsequent overrun */
769 while (ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) { 771 while (ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) {
770 if (echo_buf(ldata, tail) == ECHO_OP_START) { 772 if (echo_buf(ldata, tail) == ECHO_OP_START) {
771 if (echo_buf(ldata, tail) == ECHO_OP_ERASE_TAB) 773 if (echo_buf(ldata, tail + 1) == ECHO_OP_ERASE_TAB)
772 tail += 3; 774 tail += 3;
773 else 775 else
774 tail += 2; 776 tail += 2;
@@ -787,6 +789,7 @@ static void commit_echoes(struct tty_struct *tty)
787 size_t head; 789 size_t head;
788 790
789 head = ldata->echo_head; 791 head = ldata->echo_head;
792 ldata->echo_mark = head;
790 old = ldata->echo_commit - ldata->echo_tail; 793 old = ldata->echo_commit - ldata->echo_tail;
791 794
792 /* Process committed echoes if the accumulated # of bytes 795 /* Process committed echoes if the accumulated # of bytes
@@ -810,10 +813,12 @@ static void process_echoes(struct tty_struct *tty)
810 struct n_tty_data *ldata = tty->disc_data; 813 struct n_tty_data *ldata = tty->disc_data;
811 size_t echoed; 814 size_t echoed;
812 815
813 if (!L_ECHO(tty) || ldata->echo_commit == ldata->echo_tail) 816 if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
817 ldata->echo_mark == ldata->echo_tail)
814 return; 818 return;
815 819
816 mutex_lock(&ldata->output_lock); 820 mutex_lock(&ldata->output_lock);
821 ldata->echo_commit = ldata->echo_mark;
817 echoed = __process_echoes(tty); 822 echoed = __process_echoes(tty);
818 mutex_unlock(&ldata->output_lock); 823 mutex_unlock(&ldata->output_lock);
819 824
@@ -821,11 +826,13 @@ static void process_echoes(struct tty_struct *tty)
821 tty->ops->flush_chars(tty); 826 tty->ops->flush_chars(tty);
822} 827}
823 828
829/* NB: echo_mark and echo_head should be equivalent here */
824static void flush_echoes(struct tty_struct *tty) 830static void flush_echoes(struct tty_struct *tty)
825{ 831{
826 struct n_tty_data *ldata = tty->disc_data; 832 struct n_tty_data *ldata = tty->disc_data;
827 833
828 if (!L_ECHO(tty) || ldata->echo_commit == ldata->echo_head) 834 if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
835 ldata->echo_commit == ldata->echo_head)
829 return; 836 return;
830 837
831 mutex_lock(&ldata->output_lock); 838 mutex_lock(&ldata->output_lock);
@@ -1998,7 +2005,10 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
1998 found = 1; 2005 found = 1;
1999 2006
2000 size = N_TTY_BUF_SIZE - tail; 2007 size = N_TTY_BUF_SIZE - tail;
2001 n = (found + eol + size) & (N_TTY_BUF_SIZE - 1); 2008 n = eol - tail;
2009 if (n > 4096)
2010 n += 4096;
2011 n += found;
2002 c = n; 2012 c = n;
2003 2013
2004 if (found && read_buf(ldata, eol) == __DISABLED_CHAR) { 2014 if (found && read_buf(ldata, eol) == __DISABLED_CHAR) {
@@ -2243,18 +2253,19 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
2243 if (time) 2253 if (time)
2244 timeout = time; 2254 timeout = time;
2245 } 2255 }
2246 mutex_unlock(&ldata->atomic_read_lock); 2256 n_tty_set_room(tty);
2247 remove_wait_queue(&tty->read_wait, &wait); 2257 up_read(&tty->termios_rwsem);
2248 2258
2259 remove_wait_queue(&tty->read_wait, &wait);
2249 if (!waitqueue_active(&tty->read_wait)) 2260 if (!waitqueue_active(&tty->read_wait))
2250 ldata->minimum_to_wake = minimum; 2261 ldata->minimum_to_wake = minimum;
2251 2262
2263 mutex_unlock(&ldata->atomic_read_lock);
2264
2252 __set_current_state(TASK_RUNNING); 2265 __set_current_state(TASK_RUNNING);
2253 if (b - buf) 2266 if (b - buf)
2254 retval = b - buf; 2267 retval = b - buf;
2255 2268
2256 n_tty_set_room(tty);
2257 up_read(&tty->termios_rwsem);
2258 return retval; 2269 return retval;
2259} 2270}
2260 2271
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 4658e3e0ec42..06525f10e364 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -96,7 +96,8 @@ static void dw8250_serial_out(struct uart_port *p, int offset, int value)
96 if (offset == UART_LCR) { 96 if (offset == UART_LCR) {
97 int tries = 1000; 97 int tries = 1000;
98 while (tries--) { 98 while (tries--) {
99 if (value == p->serial_in(p, UART_LCR)) 99 unsigned int lcr = p->serial_in(p, UART_LCR);
100 if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
100 return; 101 return;
101 dw8250_force_idle(p); 102 dw8250_force_idle(p);
102 writeb(value, p->membase + (UART_LCR << p->regshift)); 103 writeb(value, p->membase + (UART_LCR << p->regshift));
@@ -132,7 +133,8 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
132 if (offset == UART_LCR) { 133 if (offset == UART_LCR) {
133 int tries = 1000; 134 int tries = 1000;
134 while (tries--) { 135 while (tries--) {
135 if (value == p->serial_in(p, UART_LCR)) 136 unsigned int lcr = p->serial_in(p, UART_LCR);
137 if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
136 return; 138 return;
137 dw8250_force_idle(p); 139 dw8250_force_idle(p);
138 writel(value, p->membase + (UART_LCR << p->regshift)); 140 writel(value, p->membase + (UART_LCR << p->regshift));
@@ -455,6 +457,8 @@ MODULE_DEVICE_TABLE(of, dw8250_of_match);
455static const struct acpi_device_id dw8250_acpi_match[] = { 457static const struct acpi_device_id dw8250_acpi_match[] = {
456 { "INT33C4", 0 }, 458 { "INT33C4", 0 },
457 { "INT33C5", 0 }, 459 { "INT33C5", 0 },
460 { "INT3434", 0 },
461 { "INT3435", 0 },
458 { "80860F0A", 0 }, 462 { "80860F0A", 0 },
459 { }, 463 { },
460}; 464};
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index f3b306efaa59..23329918f229 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -41,7 +41,7 @@ config SERIAL_8250_DEPRECATED_OPTIONS
41 accept kernel parameters in both forms like 8250_core.nr_uarts=4 and 41 accept kernel parameters in both forms like 8250_core.nr_uarts=4 and
42 8250.nr_uarts=4. We now renamed the module back to 8250, but if 42 8250.nr_uarts=4. We now renamed the module back to 8250, but if
43 anybody noticed in 3.7 and changed their userspace we still have to 43 anybody noticed in 3.7 and changed their userspace we still have to
44 keep the 8350_core.* options around until they revert the changes 44 keep the 8250_core.* options around until they revert the changes
45 they already did. 45 they already did.
46 46
47 If 8250 is built as a module, this adds 8250_core alias instead. 47 If 8250 is built as a module, this adds 8250_core alias instead.
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 481b781b26e3..e9d420ff3931 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -2052,6 +2052,9 @@ static int __init pmz_console_init(void)
2052 /* Probe ports */ 2052 /* Probe ports */
2053 pmz_probe(); 2053 pmz_probe();
2054 2054
2055 if (pmz_ports_count == 0)
2056 return -ENODEV;
2057
2055 /* TODO: Autoprobe console based on OF */ 2058 /* TODO: Autoprobe console based on OF */
2056 /* pmz_console.index = i; */ 2059 /* pmz_console.index = i; */
2057 register_console(&pmz_console); 2060 register_console(&pmz_console);
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index e46e9f3f19b9..f619ad5b5eae 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -240,6 +240,7 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
240 continue; 240 continue;
241 } 241 }
242 242
243#ifdef SUPPORT_SYSRQ
243 /* 244 /*
244 * uart_handle_sysrq_char() doesn't work if 245 * uart_handle_sysrq_char() doesn't work if
245 * spinlocked, for some reason 246 * spinlocked, for some reason
@@ -253,6 +254,7 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id)
253 } 254 }
254 spin_lock(&port->lock); 255 spin_lock(&port->lock);
255 } 256 }
257#endif
256 258
257 port->icount.rx++; 259 port->icount.rx++;
258 260
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 3a1a01af9a80..c74a00ad7add 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2086,6 +2086,7 @@ retry_open:
2086 filp->f_op = &tty_fops; 2086 filp->f_op = &tty_fops;
2087 goto retry_open; 2087 goto retry_open;
2088 } 2088 }
2089 clear_bit(TTY_HUPPED, &tty->flags);
2089 tty_unlock(tty); 2090 tty_unlock(tty);
2090 2091
2091 2092
diff --git a/drivers/tty/tty_ldsem.c b/drivers/tty/tty_ldsem.c
index 22fad8ad5ac2..d8a55e87877f 100644
--- a/drivers/tty/tty_ldsem.c
+++ b/drivers/tty/tty_ldsem.c
@@ -86,11 +86,21 @@ static inline long ldsem_atomic_update(long delta, struct ld_semaphore *sem)
86 return atomic_long_add_return(delta, (atomic_long_t *)&sem->count); 86 return atomic_long_add_return(delta, (atomic_long_t *)&sem->count);
87} 87}
88 88
89/*
90 * ldsem_cmpxchg() updates @*old with the last-known sem->count value.
91 * Returns 1 if count was successfully changed; @*old will have @new value.
92 * Returns 0 if count was not changed; @*old will have most recent sem->count
93 */
89static inline int ldsem_cmpxchg(long *old, long new, struct ld_semaphore *sem) 94static inline int ldsem_cmpxchg(long *old, long new, struct ld_semaphore *sem)
90{ 95{
91 long tmp = *old; 96 long tmp = atomic_long_cmpxchg(&sem->count, *old, new);
92 *old = atomic_long_cmpxchg(&sem->count, *old, new); 97 if (tmp == *old) {
93 return *old == tmp; 98 *old = new;
99 return 1;
100 } else {
101 *old = tmp;
102 return 0;
103 }
94} 104}
95 105
96/* 106/*