aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-25 17:58:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-25 17:58:40 -0500
commit473721f9c6494c04991b9a4cb787361d941d0d7d (patch)
tree71dee151cdf33852560a147b594490cab02cefb3 /drivers
parentb48cef32b6a5103dddf52aadbeda90ab0f7ef673 (diff)
parent815d835b7ba46685c316b000013367dacb2b461b (diff)
Merge tag 'tty-5.0-rc4' 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 core and serial driver fixes for 5.0-rc4 to resolve some reported issues. Nothing major, the small serial driver fixes, a tty core fixup for a crash that was reported, and some good vt fixes from Nicolas Pitre as he seems to be auditing that chunk of code a lot lately. All of these have been in linux-next for a while with no reported issues" * tag 'tty-5.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: serial: fsl_lpuart: fix maximum acceptable baud rate with over-sampling tty: serial: qcom_geni_serial: Allow mctrl when flow control is disabled tty: Handle problem if line discipline does not have receive_buf vgacon: unconfuse vc_origin when using soft scrollback vt: invoke notifier on screen size change vt: always call notifier with the console lock held vt: make vt_console_print() compatible with the unicode screen buffer tty/n_hdlc: fix __might_sleep warning serial: 8250: Fix serial8250 initialization crash uart: Fix crash in uart_write and uart_put_char
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/n_hdlc.c1
-rw-r--r--drivers/tty/serial/8250/8250_core.c17
-rw-r--r--drivers/tty/serial/fsl_lpuart.c2
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c4
-rw-r--r--drivers/tty/serial/serial_core.c12
-rw-r--r--drivers/tty/tty_io.c3
-rw-r--r--drivers/tty/vt/vt.c50
-rw-r--r--drivers/video/console/vgacon.c7
8 files changed, 44 insertions, 52 deletions
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c
index 4164414d4c64..8bdf42bc8fc8 100644
--- a/drivers/tty/n_hdlc.c
+++ b/drivers/tty/n_hdlc.c
@@ -597,6 +597,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
597 /* too large for caller's buffer */ 597 /* too large for caller's buffer */
598 ret = -EOVERFLOW; 598 ret = -EOVERFLOW;
599 } else { 599 } else {
600 __set_current_state(TASK_RUNNING);
600 if (copy_to_user(buf, rbuf->buf, rbuf->count)) 601 if (copy_to_user(buf, rbuf->buf, rbuf->count))
601 ret = -EFAULT; 602 ret = -EFAULT;
602 else 603 else
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 189ab1212d9a..e441221e04b9 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1070,15 +1070,16 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
1070 1070
1071 ret = 0; 1071 ret = 0;
1072 } 1072 }
1073 }
1074 1073
1075 /* Initialise interrupt backoff work if required */ 1074 /* Initialise interrupt backoff work if required */
1076 if (up->overrun_backoff_time_ms > 0) { 1075 if (up->overrun_backoff_time_ms > 0) {
1077 uart->overrun_backoff_time_ms = up->overrun_backoff_time_ms; 1076 uart->overrun_backoff_time_ms =
1078 INIT_DELAYED_WORK(&uart->overrun_backoff, 1077 up->overrun_backoff_time_ms;
1079 serial_8250_overrun_backoff_work); 1078 INIT_DELAYED_WORK(&uart->overrun_backoff,
1080 } else { 1079 serial_8250_overrun_backoff_work);
1081 uart->overrun_backoff_time_ms = 0; 1080 } else {
1081 uart->overrun_backoff_time_ms = 0;
1082 }
1082 } 1083 }
1083 1084
1084 mutex_unlock(&serial_mutex); 1085 mutex_unlock(&serial_mutex);
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 241a48e5052c..debdd1b9e01a 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1697,7 +1697,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
1697 } 1697 }
1698 1698
1699 /* ask the core to calculate the divisor */ 1699 /* ask the core to calculate the divisor */
1700 baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); 1700 baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 4);
1701 1701
1702 spin_lock_irqsave(&sport->port.lock, flags); 1702 spin_lock_irqsave(&sport->port.lock, flags);
1703 1703
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index a72d6d9fb983..38016609c7fa 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -225,7 +225,7 @@ static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport)
225 unsigned int mctrl = TIOCM_DSR | TIOCM_CAR; 225 unsigned int mctrl = TIOCM_DSR | TIOCM_CAR;
226 u32 geni_ios; 226 u32 geni_ios;
227 227
228 if (uart_console(uport) || !uart_cts_enabled(uport)) { 228 if (uart_console(uport)) {
229 mctrl |= TIOCM_CTS; 229 mctrl |= TIOCM_CTS;
230 } else { 230 } else {
231 geni_ios = readl_relaxed(uport->membase + SE_GENI_IOS); 231 geni_ios = readl_relaxed(uport->membase + SE_GENI_IOS);
@@ -241,7 +241,7 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport,
241{ 241{
242 u32 uart_manual_rfr = 0; 242 u32 uart_manual_rfr = 0;
243 243
244 if (uart_console(uport) || !uart_cts_enabled(uport)) 244 if (uart_console(uport))
245 return; 245 return;
246 246
247 if (!(mctrl & TIOCM_RTS)) 247 if (!(mctrl & TIOCM_RTS))
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index d4cca5bdaf1c..5c01bb6d1c24 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -550,10 +550,12 @@ static int uart_put_char(struct tty_struct *tty, unsigned char c)
550 int ret = 0; 550 int ret = 0;
551 551
552 circ = &state->xmit; 552 circ = &state->xmit;
553 if (!circ->buf) 553 port = uart_port_lock(state, flags);
554 if (!circ->buf) {
555 uart_port_unlock(port, flags);
554 return 0; 556 return 0;
557 }
555 558
556 port = uart_port_lock(state, flags);
557 if (port && uart_circ_chars_free(circ) != 0) { 559 if (port && uart_circ_chars_free(circ) != 0) {
558 circ->buf[circ->head] = c; 560 circ->buf[circ->head] = c;
559 circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); 561 circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
@@ -586,11 +588,13 @@ static int uart_write(struct tty_struct *tty,
586 return -EL3HLT; 588 return -EL3HLT;
587 } 589 }
588 590
591 port = uart_port_lock(state, flags);
589 circ = &state->xmit; 592 circ = &state->xmit;
590 if (!circ->buf) 593 if (!circ->buf) {
594 uart_port_unlock(port, flags);
591 return 0; 595 return 0;
596 }
592 597
593 port = uart_port_lock(state, flags);
594 while (port) { 598 while (port) {
595 c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); 599 c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
596 if (count < c) 600 if (count < c)
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 23c6fd238422..21ffcce16927 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2189,7 +2189,8 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
2189 ld = tty_ldisc_ref_wait(tty); 2189 ld = tty_ldisc_ref_wait(tty);
2190 if (!ld) 2190 if (!ld)
2191 return -EIO; 2191 return -EIO;
2192 ld->ops->receive_buf(tty, &ch, &mbz, 1); 2192 if (ld->ops->receive_buf)
2193 ld->ops->receive_buf(tty, &ch, &mbz, 1);
2193 tty_ldisc_deref(ld); 2194 tty_ldisc_deref(ld);
2194 return 0; 2195 return 0;
2195} 2196}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 41ec8e5010f3..bba75560d11e 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1272,6 +1272,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
1272 if (con_is_visible(vc)) 1272 if (con_is_visible(vc))
1273 update_screen(vc); 1273 update_screen(vc);
1274 vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num); 1274 vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
1275 notify_update(vc);
1275 return err; 1276 return err;
1276} 1277}
1277 1278
@@ -2764,8 +2765,8 @@ rescan_last_byte:
2764 con_flush(vc, draw_from, draw_to, &draw_x); 2765 con_flush(vc, draw_from, draw_to, &draw_x);
2765 vc_uniscr_debug_check(vc); 2766 vc_uniscr_debug_check(vc);
2766 console_conditional_schedule(); 2767 console_conditional_schedule();
2767 console_unlock();
2768 notify_update(vc); 2768 notify_update(vc);
2769 console_unlock();
2769 return n; 2770 return n;
2770} 2771}
2771 2772
@@ -2884,8 +2885,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
2884 unsigned char c; 2885 unsigned char c;
2885 static DEFINE_SPINLOCK(printing_lock); 2886 static DEFINE_SPINLOCK(printing_lock);
2886 const ushort *start; 2887 const ushort *start;
2887 ushort cnt = 0; 2888 ushort start_x, cnt;
2888 ushort myx;
2889 int kmsg_console; 2889 int kmsg_console;
2890 2890
2891 /* console busy or not yet initialized */ 2891 /* console busy or not yet initialized */
@@ -2898,10 +2898,6 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
2898 if (kmsg_console && vc_cons_allocated(kmsg_console - 1)) 2898 if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
2899 vc = vc_cons[kmsg_console - 1].d; 2899 vc = vc_cons[kmsg_console - 1].d;
2900 2900
2901 /* read `x' only after setting currcons properly (otherwise
2902 the `x' macro will read the x of the foreground console). */
2903 myx = vc->vc_x;
2904
2905 if (!vc_cons_allocated(fg_console)) { 2901 if (!vc_cons_allocated(fg_console)) {
2906 /* impossible */ 2902 /* impossible */
2907 /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */ 2903 /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
@@ -2916,53 +2912,41 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
2916 hide_cursor(vc); 2912 hide_cursor(vc);
2917 2913
2918 start = (ushort *)vc->vc_pos; 2914 start = (ushort *)vc->vc_pos;
2919 2915 start_x = vc->vc_x;
2920 /* Contrived structure to try to emulate original need_wrap behaviour 2916 cnt = 0;
2921 * Problems caused when we have need_wrap set on '\n' character */
2922 while (count--) { 2917 while (count--) {
2923 c = *b++; 2918 c = *b++;
2924 if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) { 2919 if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
2925 if (cnt > 0) { 2920 if (cnt && con_is_visible(vc))
2926 if (con_is_visible(vc)) 2921 vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
2927 vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x); 2922 cnt = 0;
2928 vc->vc_x += cnt;
2929 if (vc->vc_need_wrap)
2930 vc->vc_x--;
2931 cnt = 0;
2932 }
2933 if (c == 8) { /* backspace */ 2923 if (c == 8) { /* backspace */
2934 bs(vc); 2924 bs(vc);
2935 start = (ushort *)vc->vc_pos; 2925 start = (ushort *)vc->vc_pos;
2936 myx = vc->vc_x; 2926 start_x = vc->vc_x;
2937 continue; 2927 continue;
2938 } 2928 }
2939 if (c != 13) 2929 if (c != 13)
2940 lf(vc); 2930 lf(vc);
2941 cr(vc); 2931 cr(vc);
2942 start = (ushort *)vc->vc_pos; 2932 start = (ushort *)vc->vc_pos;
2943 myx = vc->vc_x; 2933 start_x = vc->vc_x;
2944 if (c == 10 || c == 13) 2934 if (c == 10 || c == 13)
2945 continue; 2935 continue;
2946 } 2936 }
2937 vc_uniscr_putc(vc, c);
2947 scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos); 2938 scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
2948 notify_write(vc, c); 2939 notify_write(vc, c);
2949 cnt++; 2940 cnt++;
2950 if (myx == vc->vc_cols - 1) { 2941 if (vc->vc_x == vc->vc_cols - 1) {
2951 vc->vc_need_wrap = 1;
2952 continue;
2953 }
2954 vc->vc_pos += 2;
2955 myx++;
2956 }
2957 if (cnt > 0) {
2958 if (con_is_visible(vc))
2959 vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
2960 vc->vc_x += cnt;
2961 if (vc->vc_x == vc->vc_cols) {
2962 vc->vc_x--;
2963 vc->vc_need_wrap = 1; 2942 vc->vc_need_wrap = 1;
2943 } else {
2944 vc->vc_pos += 2;
2945 vc->vc_x++;
2964 } 2946 }
2965 } 2947 }
2948 if (cnt && con_is_visible(vc))
2949 vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
2966 set_cursor(vc); 2950 set_cursor(vc);
2967 notify_update(vc); 2951 notify_update(vc);
2968 2952
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 09731b2f6815..c6b3bdbbdbc9 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -271,6 +271,7 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
271 271
272static void vgacon_restore_screen(struct vc_data *c) 272static void vgacon_restore_screen(struct vc_data *c)
273{ 273{
274 c->vc_origin = c->vc_visible_origin;
274 vgacon_scrollback_cur->save = 0; 275 vgacon_scrollback_cur->save = 0;
275 276
276 if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { 277 if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
@@ -287,8 +288,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
287 int start, end, count, soff; 288 int start, end, count, soff;
288 289
289 if (!lines) { 290 if (!lines) {
290 c->vc_visible_origin = c->vc_origin; 291 vgacon_restore_screen(c);
291 vga_set_mem_top(c);
292 return; 292 return;
293 } 293 }
294 294
@@ -298,6 +298,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
298 if (!vgacon_scrollback_cur->save) { 298 if (!vgacon_scrollback_cur->save) {
299 vgacon_cursor(c, CM_ERASE); 299 vgacon_cursor(c, CM_ERASE);
300 vgacon_save_screen(c); 300 vgacon_save_screen(c);
301 c->vc_origin = (unsigned long)c->vc_screenbuf;
301 vgacon_scrollback_cur->save = 1; 302 vgacon_scrollback_cur->save = 1;
302 } 303 }
303 304
@@ -335,7 +336,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
335 int copysize; 336 int copysize;
336 337
337 int diff = c->vc_rows - count; 338 int diff = c->vc_rows - count;
338 void *d = (void *) c->vc_origin; 339 void *d = (void *) c->vc_visible_origin;
339 void *s = (void *) c->vc_screenbuf; 340 void *s = (void *) c->vc_screenbuf;
340 341
341 count *= c->vc_size_row; 342 count *= c->vc_size_row;