From a42a9f6a9bbc0d3894fc8ceaa714f5c5d9f4d96b Mon Sep 17 00:00:00 2001 From: Allen Pais Date: Mon, 17 Aug 2020 14:29:18 +0530 Subject: [PATCH 01/79] tty: ipwireless: convert tasklets to use new tasklet_setup() API In preparation for unconditionally passing the struct tasklet_struct pointer to all tasklet callbacks, switch to using the new tasklet_setup() and from_tasklet() to pass the tasklet pointer explicitly. Signed-off-by: Romain Perier Signed-off-by: Allen Pais Link: https://lore.kernel.org/r/20200817085921.26033-2-allen.cryptic@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/ipwireless/hardware.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index 6bbf35682d53..f5d3e68f5750 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c @@ -1006,9 +1006,9 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) /* * Send and receive all queued packets. */ -static void ipwireless_do_tasklet(unsigned long hw_) +static void ipwireless_do_tasklet(struct tasklet_struct *t) { - struct ipw_hardware *hw = (struct ipw_hardware *) hw_; + struct ipw_hardware *hw = from_tasklet(hw, t, tasklet); unsigned long flags; spin_lock_irqsave(&hw->lock, flags); @@ -1635,7 +1635,7 @@ struct ipw_hardware *ipwireless_hardware_create(void) INIT_LIST_HEAD(&hw->rx_queue); INIT_LIST_HEAD(&hw->rx_pool); spin_lock_init(&hw->lock); - tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw); + tasklet_setup(&hw->tasklet, ipwireless_do_tasklet); INIT_WORK(&hw->work_rx, ipw_receive_data_work); timer_setup(&hw->setup_timer, ipwireless_setup_timer, 0); From 41e85e44edea0ba1a1601ed2a099d236c7f738bf Mon Sep 17 00:00:00 2001 From: Allen Pais Date: Mon, 17 Aug 2020 14:29:19 +0530 Subject: [PATCH 02/79] tty: atmel_serial: convert tasklets to use new tasklet_setup() API In preparation for unconditionally passing the struct tasklet_struct pointer to all tasklet callbacks, switch to using the new tasklet_setup() and from_tasklet() to pass the tasklet pointer explicitly. Signed-off-by: Romain Perier Signed-off-by: Allen Pais Link: https://lore.kernel.org/r/20200817085921.26033-3-allen.cryptic@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index e43471b33710..a9c47f56e994 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1722,10 +1722,11 @@ static int atmel_prepare_rx_pdc(struct uart_port *port) /* * tasklet handling tty stuff outside the interrupt handler. */ -static void atmel_tasklet_rx_func(unsigned long data) +static void atmel_tasklet_rx_func(struct tasklet_struct *t) { - struct uart_port *port = (struct uart_port *)data; - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + struct atmel_uart_port *atmel_port = from_tasklet(atmel_port, t, + tasklet_rx); + struct uart_port *port = &atmel_port->uart; /* The interrupt handler does not take the lock */ spin_lock(&port->lock); @@ -1733,10 +1734,11 @@ static void atmel_tasklet_rx_func(unsigned long data) spin_unlock(&port->lock); } -static void atmel_tasklet_tx_func(unsigned long data) +static void atmel_tasklet_tx_func(struct tasklet_struct *t) { - struct uart_port *port = (struct uart_port *)data; - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + struct atmel_uart_port *atmel_port = from_tasklet(atmel_port, t, + tasklet_tx); + struct uart_port *port = &atmel_port->uart; /* The interrupt handler does not take the lock */ spin_lock(&port->lock); @@ -1911,10 +1913,8 @@ static int atmel_startup(struct uart_port *port) } atomic_set(&atmel_port->tasklet_shutdown, 0); - tasklet_init(&atmel_port->tasklet_rx, atmel_tasklet_rx_func, - (unsigned long)port); - tasklet_init(&atmel_port->tasklet_tx, atmel_tasklet_tx_func, - (unsigned long)port); + tasklet_setup(&atmel_port->tasklet_rx, atmel_tasklet_rx_func); + tasklet_setup(&atmel_port->tasklet_tx, atmel_tasklet_tx_func); /* * Initialize DMA (if necessary) From d77e24f21df1da4ddd7a6fb185105c4ad3d86a86 Mon Sep 17 00:00:00 2001 From: Allen Pais Date: Mon, 17 Aug 2020 14:29:20 +0530 Subject: [PATCH 03/79] tty: ifx6x60: convert tasklets to use new tasklet_setup() API In preparation for unconditionally passing the struct tasklet_struct pointer to all tasklet callbacks, switch to using the new tasklet_setup() and from_tasklet() to pass the tasklet pointer explicitly. Signed-off-by: Romain Perier Signed-off-by: Allen Pais Link: https://lore.kernel.org/r/20200817085921.26033-4-allen.cryptic@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 7d16fe41932f..37d5b8516880 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -725,10 +725,11 @@ complete_exit: * Queue data for transmission if possible and then kick off the * transfer. */ -static void ifx_spi_io(unsigned long data) +static void ifx_spi_io(struct tasklet_struct *t) { int retval; - struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data; + struct ifx_spi_device *ifx_dev = from_tasklet(ifx_dev, t, + io_work_tasklet); if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) && test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) { @@ -1067,8 +1068,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi) init_waitqueue_head(&ifx_dev->mdm_reset_wait); spi_set_drvdata(spi, ifx_dev); - tasklet_init(&ifx_dev->io_work_tasklet, ifx_spi_io, - (unsigned long)ifx_dev); + tasklet_setup(&ifx_dev->io_work_tasklet, ifx_spi_io); set_bit(IFX_SPI_STATE_PRESENT, &ifx_dev->flags); From 2b2dd9c6ac41cc975fedc82fc871cbff1fb7f711 Mon Sep 17 00:00:00 2001 From: Allen Pais Date: Mon, 17 Aug 2020 14:29:21 +0530 Subject: [PATCH 04/79] tty: timbuart: convert tasklets to use new tasklet_setup() API In preparation for unconditionally passing the struct tasklet_struct pointer to all tasklet callbacks, switch to using the new tasklet_setup() and from_tasklet() to pass the tasklet pointer explicitly. Signed-off-by: Romain Perier Signed-off-by: Allen Pais Link: https://lore.kernel.org/r/20200817085921.26033-5-allen.cryptic@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/timbuart.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 19d38b504e27..2126e6e6dfd1 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c @@ -172,9 +172,9 @@ static void timbuart_handle_rx_port(struct uart_port *port, u32 isr, u32 *ier) dev_dbg(port->dev, "%s - leaving\n", __func__); } -static void timbuart_tasklet(unsigned long arg) +static void timbuart_tasklet(struct tasklet_struct *t) { - struct timbuart_port *uart = (struct timbuart_port *)arg; + struct timbuart_port *uart = from_tasklet(uart, t, tasklet); u32 isr, ier = 0; spin_lock(&uart->port.lock); @@ -451,7 +451,7 @@ static int timbuart_probe(struct platform_device *dev) } uart->port.irq = irq; - tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart); + tasklet_setup(&uart->tasklet, timbuart_tasklet); err = uart_register_driver(&timbuart_driver); if (err) From d73568c4ccb01d01e20cd23fefbff8e4a05ddfac Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:51 +0200 Subject: [PATCH 05/79] vt: make vc_data pointers const in selection.h There are many functions declared in selection.h which only read from struct vc_data passed as a parameter. Make all those uses const to hint the compiler a bit. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/consolemap.c | 2 +- drivers/tty/vt/vt.c | 15 ++++++++------- drivers/video/console/sticon.c | 2 +- drivers/video/fbdev/core/fbcon.c | 2 +- include/linux/console.h | 2 +- include/linux/consolemap.h | 3 ++- include/linux/selection.h | 14 ++++++++------ 7 files changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 5947b54d92be..5d5a5fd2dce7 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -268,7 +268,7 @@ unsigned short *set_translate(int m, struct vc_data *vc) * was active. * Still, it is now possible to a certain extent to cut and paste non-ASCII. */ -u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode) +u16 inverse_translate(const struct vc_data *conp, int glyph, int use_unicode) { struct uni_pagedir *p; int m; diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index ccb533fd00a2..8f283221330e 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -283,7 +283,8 @@ static inline bool con_should_update(const struct vc_data *vc) return con_is_visible(vc) && !console_blanked; } -static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed) +static inline unsigned short *screenpos(const struct vc_data *vc, int offset, + int viewed) { unsigned short *p; @@ -543,7 +544,7 @@ int vc_uniscr_check(struct vc_data *vc) * This must be preceded by a successful call to vc_uniscr_check() once * the console lock has been taken. */ -void vc_uniscr_copy_line(struct vc_data *vc, void *dest, int viewed, +void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, int viewed, unsigned int row, unsigned int col, unsigned int nr) { struct uni_screen *uniscr = get_vc_uniscr(vc); @@ -4740,7 +4741,7 @@ int con_font_op(struct vc_data *vc, struct console_font_op *op) */ /* used by selection */ -u16 screen_glyph(struct vc_data *vc, int offset) +u16 screen_glyph(const struct vc_data *vc, int offset) { u16 w = scr_readw(screenpos(vc, offset, 1)); u16 c = w & 0xff; @@ -4751,7 +4752,7 @@ u16 screen_glyph(struct vc_data *vc, int offset) } EXPORT_SYMBOL_GPL(screen_glyph); -u32 screen_glyph_unicode(struct vc_data *vc, int n) +u32 screen_glyph_unicode(const struct vc_data *vc, int n) { struct uni_screen *uniscr = get_vc_uniscr(vc); @@ -4762,13 +4763,13 @@ u32 screen_glyph_unicode(struct vc_data *vc, int n) EXPORT_SYMBOL_GPL(screen_glyph_unicode); /* used by vcs - note the word offset */ -unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed) +unsigned short *screen_pos(const struct vc_data *vc, int w_offset, int viewed) { return screenpos(vc, 2 * w_offset, viewed); } EXPORT_SYMBOL_GPL(screen_pos); -void getconsxy(struct vc_data *vc, unsigned char *p) +void getconsxy(const struct vc_data *vc, unsigned char *p) { /* clamp values if they don't fit */ p[0] = min(vc->state.x, 0xFFu); @@ -4782,7 +4783,7 @@ void putconsxy(struct vc_data *vc, unsigned char *p) set_cursor(vc); } -u16 vcs_scr_readw(struct vc_data *vc, const u16 *org) +u16 vcs_scr_readw(const struct vc_data *vc, const u16 *org) { if ((unsigned long)org == vc->vc_pos && softcursor_original != -1) return softcursor_original; diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 21a5c280c8c9..e21147e8a14e 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -236,7 +236,7 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch) return 1; } -static u16 *sticon_screen_pos(struct vc_data *conp, int offset) +static u16 *sticon_screen_pos(const struct vc_data *conp, int offset) { int line; unsigned long p; diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 8a31fc2b2258..6068845d98f2 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2765,7 +2765,7 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table) fb_set_cmap(&palette_cmap, info); } -static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) +static u16 *fbcon_screen_pos(const struct vc_data *vc, int offset) { unsigned long p; int line; diff --git a/include/linux/console.h b/include/linux/console.h index 0670d3491e0e..4b1e26c4cb42 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -74,7 +74,7 @@ struct consw { enum vc_intensity intensity, bool blink, bool underline, bool reverse, bool italic); void (*con_invert_region)(struct vc_data *vc, u16 *p, int count); - u16 *(*con_screen_pos)(struct vc_data *vc, int offset); + u16 *(*con_screen_pos)(const struct vc_data *vc, int offset); unsigned long (*con_getxy)(struct vc_data *vc, unsigned long position, int *px, int *py); /* diff --git a/include/linux/consolemap.h b/include/linux/consolemap.h index 254246673390..bcfce748c9d8 100644 --- a/include/linux/consolemap.h +++ b/include/linux/consolemap.h @@ -17,7 +17,8 @@ #ifdef CONFIG_CONSOLE_TRANSLATIONS struct vc_data; -extern u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode); +extern u16 inverse_translate(const struct vc_data *conp, int glyph, + int use_unicode); extern unsigned short *set_translate(int m, struct vc_data *vc); extern int conv_uni_to_pc(struct vc_data *conp, long ucs); extern u32 conv_8bit_to_uni(unsigned char c); diff --git a/include/linux/selection.h b/include/linux/selection.h index 5b890ef5b59f..34404a019ebf 100644 --- a/include/linux/selection.h +++ b/include/linux/selection.h @@ -33,21 +33,23 @@ extern unsigned char default_red[]; extern unsigned char default_grn[]; extern unsigned char default_blu[]; -extern unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed); -extern u16 screen_glyph(struct vc_data *vc, int offset); -extern u32 screen_glyph_unicode(struct vc_data *vc, int offset); +extern unsigned short *screen_pos(const struct vc_data *vc, int w_offset, + int viewed); +extern u16 screen_glyph(const struct vc_data *vc, int offset); +extern u32 screen_glyph_unicode(const struct vc_data *vc, int offset); extern void complement_pos(struct vc_data *vc, int offset); extern void invert_screen(struct vc_data *vc, int offset, int count, int shift); -extern void getconsxy(struct vc_data *vc, unsigned char *p); +extern void getconsxy(const struct vc_data *vc, unsigned char *p); extern void putconsxy(struct vc_data *vc, unsigned char *p); -extern u16 vcs_scr_readw(struct vc_data *vc, const u16 *org); +extern u16 vcs_scr_readw(const struct vc_data *vc, const u16 *org); extern void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org); extern void vcs_scr_updated(struct vc_data *vc); extern int vc_uniscr_check(struct vc_data *vc); -extern void vc_uniscr_copy_line(struct vc_data *vc, void *dest, int viewed, +extern void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, + int viewed, unsigned int row, unsigned int col, unsigned int nr); From a5c6bd806dd626103db38dee77796fe758c8df94 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:52 +0200 Subject: [PATCH 06/79] vt: declare xy for get/putconsxy properly That is: 1) call the parameter 'xy' to denote what it really is, not generic 'p' 2) tell the compiler and users that we expect an array: * with at least 2 chars (static 2) * which we don't modify in putconsxy (const) Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 10 +++++----- include/linux/selection.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 8f283221330e..a0da7771c327 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4769,17 +4769,17 @@ unsigned short *screen_pos(const struct vc_data *vc, int w_offset, int viewed) } EXPORT_SYMBOL_GPL(screen_pos); -void getconsxy(const struct vc_data *vc, unsigned char *p) +void getconsxy(const struct vc_data *vc, unsigned char xy[static 2]) { /* clamp values if they don't fit */ - p[0] = min(vc->state.x, 0xFFu); - p[1] = min(vc->state.y, 0xFFu); + xy[0] = min(vc->state.x, 0xFFu); + xy[1] = min(vc->state.y, 0xFFu); } -void putconsxy(struct vc_data *vc, unsigned char *p) +void putconsxy(struct vc_data *vc, unsigned char xy[static const 2]) { hide_cursor(vc); - gotoxy(vc, p[0], p[1]); + gotoxy(vc, xy[0], xy[1]); set_cursor(vc); } diff --git a/include/linux/selection.h b/include/linux/selection.h index 34404a019ebf..15e36e7ef869 100644 --- a/include/linux/selection.h +++ b/include/linux/selection.h @@ -40,8 +40,8 @@ extern u32 screen_glyph_unicode(const struct vc_data *vc, int offset); extern void complement_pos(struct vc_data *vc, int offset); extern void invert_screen(struct vc_data *vc, int offset, int count, int shift); -extern void getconsxy(const struct vc_data *vc, unsigned char *p); -extern void putconsxy(struct vc_data *vc, unsigned char *p); +extern void getconsxy(const struct vc_data *vc, unsigned char xy[static 2]); +extern void putconsxy(struct vc_data *vc, unsigned char xy[static const 2]); extern u16 vcs_scr_readw(const struct vc_data *vc, const u16 *org); extern void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org); From b8209f694f7f4256181deea92d30eedb908d6788 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:53 +0200 Subject: [PATCH 07/79] vc: propagate "viewed as bool" from screenpos up viewed is used as a flag, i.e. bool. So treat is as such in most of the places. vcs_vc is handled in the next patch. Note: the last parameter of invert_screen was misnamed in the declaration since 1.1.92. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/main.c | 4 ++-- drivers/tty/vt/selection.c | 2 +- drivers/tty/vt/vt.c | 18 ++++++++++-------- include/linux/selection.h | 6 +++--- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/accessibility/speakup/main.c b/drivers/accessibility/speakup/main.c index ddfd12afe3b9..be79b2135fac 100644 --- a/drivers/accessibility/speakup/main.c +++ b/drivers/accessibility/speakup/main.c @@ -257,7 +257,7 @@ static struct notifier_block vt_notifier_block = { static unsigned char get_attributes(struct vc_data *vc, u16 *pos) { - pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, 1); + pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, true); return (scr_readw(pos) & ~vc->vc_hi_font_mask) >> 8; } @@ -465,7 +465,7 @@ static u16 get_char(struct vc_data *vc, u16 *pos, u_char *attribs) u16 w; u16 c; - pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, 1); + pos = screen_pos(vc, pos - (u16 *)vc->vc_origin, true); w = scr_readw(pos); c = w & 0xff; diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 8e74654c1b27..f245a5acf7e9 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -54,7 +54,7 @@ static struct vc_selection { /* set reverse video on characters s-e of console with selection. */ static inline void highlight(const int s, const int e) { - invert_screen(vc_sel.cons, s, e-s+2, 1); + invert_screen(vc_sel.cons, s, e-s+2, true); } /* use complementary color to show the pointer */ diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index a0da7771c327..0f7064d41e92 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -284,7 +284,7 @@ static inline bool con_should_update(const struct vc_data *vc) } static inline unsigned short *screenpos(const struct vc_data *vc, int offset, - int viewed) + bool viewed) { unsigned short *p; @@ -544,7 +544,7 @@ int vc_uniscr_check(struct vc_data *vc) * This must be preceded by a successful call to vc_uniscr_check() once * the console lock has been taken. */ -void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, int viewed, +void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, bool viewed, unsigned int row, unsigned int col, unsigned int nr) { struct uni_screen *uniscr = get_vc_uniscr(vc); @@ -753,7 +753,7 @@ static void update_attr(struct vc_data *vc) } /* Note: inverting the screen twice should revert to the original state */ -void invert_screen(struct vc_data *vc, int offset, int count, int viewed) +void invert_screen(struct vc_data *vc, int offset, int count, bool viewed) { unsigned short *p; @@ -812,7 +812,7 @@ void complement_pos(struct vc_data *vc, int offset) if (old_offset != -1 && old_offset >= 0 && old_offset < vc->vc_screenbuf_size) { - scr_writew(old, screenpos(vc, old_offset, 1)); + scr_writew(old, screenpos(vc, old_offset, true)); if (con_should_update(vc)) vc->vc_sw->con_putc(vc, old, oldy, oldx); notify_update(vc); @@ -824,7 +824,7 @@ void complement_pos(struct vc_data *vc, int offset) offset < vc->vc_screenbuf_size) { unsigned short new; unsigned short *p; - p = screenpos(vc, offset, 1); + p = screenpos(vc, offset, true); old = scr_readw(p); new = old ^ vc->vc_complement_mask; scr_writew(new, p); @@ -1885,7 +1885,9 @@ static void set_mode(struct vc_data *vc, int on_off) case 5: /* Inverted screen on/off */ if (vc->vc_decscnm != on_off) { vc->vc_decscnm = on_off; - invert_screen(vc, 0, vc->vc_screenbuf_size, 0); + invert_screen(vc, 0, + vc->vc_screenbuf_size, + false); update_attr(vc); } break; @@ -4743,7 +4745,7 @@ int con_font_op(struct vc_data *vc, struct console_font_op *op) /* used by selection */ u16 screen_glyph(const struct vc_data *vc, int offset) { - u16 w = scr_readw(screenpos(vc, offset, 1)); + u16 w = scr_readw(screenpos(vc, offset, true)); u16 c = w & 0xff; if (w & vc->vc_hi_font_mask) @@ -4763,7 +4765,7 @@ u32 screen_glyph_unicode(const struct vc_data *vc, int n) EXPORT_SYMBOL_GPL(screen_glyph_unicode); /* used by vcs - note the word offset */ -unsigned short *screen_pos(const struct vc_data *vc, int w_offset, int viewed) +unsigned short *screen_pos(const struct vc_data *vc, int w_offset, bool viewed) { return screenpos(vc, 2 * w_offset, viewed); } diff --git a/include/linux/selection.h b/include/linux/selection.h index 15e36e7ef869..170ef28ff26b 100644 --- a/include/linux/selection.h +++ b/include/linux/selection.h @@ -34,11 +34,11 @@ extern unsigned char default_grn[]; extern unsigned char default_blu[]; extern unsigned short *screen_pos(const struct vc_data *vc, int w_offset, - int viewed); + bool viewed); extern u16 screen_glyph(const struct vc_data *vc, int offset); extern u32 screen_glyph_unicode(const struct vc_data *vc, int offset); extern void complement_pos(struct vc_data *vc, int offset); -extern void invert_screen(struct vc_data *vc, int offset, int count, int shift); +extern void invert_screen(struct vc_data *vc, int offset, int count, bool viewed); extern void getconsxy(const struct vc_data *vc, unsigned char xy[static 2]); extern void putconsxy(struct vc_data *vc, unsigned char xy[static const 2]); @@ -49,7 +49,7 @@ extern void vcs_scr_updated(struct vc_data *vc); extern int vc_uniscr_check(struct vc_data *vc); extern void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, - int viewed, + bool viewed, unsigned int row, unsigned int col, unsigned int nr); From 7d62549a22ee500ea2ad764b9d04b87c6bbcd75f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:54 +0200 Subject: [PATCH 08/79] vc_screen: document and cleanup vcs_vc Document parameters of vcs_vc and make viewed a bool. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 778f83ea2249..adc3c786b621 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -177,12 +177,14 @@ vcs_poll_data_get(struct file *file) return poll; } -/* - * Returns VC for inode. +/** + * vcs_vc -- return VC for @inode + * @inode: inode for which to return a VC + * @viewed: returns whether this console is currently foreground (viewed) + * * Must be called with console_lock. */ -static struct vc_data* -vcs_vc(struct inode *inode, int *viewed) +static struct vc_data *vcs_vc(struct inode *inode, bool *viewed) { unsigned int currcons = console(inode); @@ -191,11 +193,11 @@ vcs_vc(struct inode *inode, int *viewed) if (currcons == 0) { currcons = fg_console; if (viewed) - *viewed = 1; + *viewed = true; } else { currcons--; if (viewed) - *viewed = 0; + *viewed = false; } return vc_cons[currcons].d; } @@ -247,10 +249,11 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) struct vc_data *vc; struct vcs_poll_data *poll; long pos, read; - int attr, uni_mode, row, col, maxcol, viewed; + int attr, uni_mode, row, col, maxcol; unsigned short *org = NULL; ssize_t ret; char *con_buf; + bool viewed; con_buf = (char *) __get_free_page(GFP_KERNEL); if (!con_buf) @@ -451,10 +454,11 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) long pos; long attr, size, written; char *con_buf0; - int col, maxcol, viewed; + int col, maxcol; u16 *org0 = NULL, *org = NULL; size_t ret; char *con_buf; + bool viewed; if (use_unicode(inode)) return -EOPNOTSUPP; From 71d4abfab322e827a75304431fe0fad3c805cb80 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:55 +0200 Subject: [PATCH 09/79] vc_screen: rewrite vcs_size to accept vc, not inode It is weird to fetch the information from the inode over and over. Read and write already have the needed information, so rewrite vcs_size to accept a vc, attr and unicode and adapt vcs_lseek to that. Also make sure all sites check the return value of vcs_size for errors. And document it using kernel-doc. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-5-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 46 ++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index adc3c786b621..8aa0d50bcac7 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -202,39 +202,47 @@ static struct vc_data *vcs_vc(struct inode *inode, bool *viewed) return vc_cons[currcons].d; } -/* - * Returns size for VC carried by inode. +/** + * vcs_size -- return size for a VC in @vc + * @vc: which VC + * @attr: does it use attributes? + * @unicode: is it unicode? + * * Must be called with console_lock. */ -static int -vcs_size(struct inode *inode) +static int vcs_size(const struct vc_data *vc, bool attr, bool unicode) { int size; - struct vc_data *vc; WARN_CONSOLE_UNLOCKED(); - vc = vcs_vc(inode, NULL); - if (!vc) - return -ENXIO; - size = vc->vc_rows * vc->vc_cols; - if (use_attributes(inode)) { - if (use_unicode(inode)) + if (attr) { + if (unicode) return -EOPNOTSUPP; - size = 2*size + HEADER_SIZE; - } else if (use_unicode(inode)) + + size = 2 * size + HEADER_SIZE; + } else if (unicode) size *= 4; + return size; } static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) { + struct inode *inode = file_inode(file); + struct vc_data *vc; int size; console_lock(); - size = vcs_size(file_inode(file)); + vc = vcs_vc(inode, NULL); + if (!vc) { + console_unlock(); + return -ENXIO; + } + + size = vcs_size(vc, use_attributes(inode), use_unicode(inode)); console_unlock(); if (size < 0) return size; @@ -295,7 +303,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) * as copy_to_user at the end of this loop * could sleep. */ - size = vcs_size(inode); + size = vcs_size(vc, attr, uni_mode); if (size < 0) { if (read) break; @@ -480,7 +488,11 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) if (!vc) goto unlock_out; - size = vcs_size(inode); + size = vcs_size(vc, attr, false); + if (size < 0) { + ret = size; + goto unlock_out; + } ret = -EINVAL; if (pos < 0 || pos > size) goto unlock_out; @@ -519,7 +531,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) * the user buffer, so recheck. * Return data written up to now on failure. */ - size = vcs_size(inode); + size = vcs_size(vc, attr, false); if (size < 0) { if (written) break; From 2665bef49f96df1a541b4e71e7b27bf631f7667c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:56 +0200 Subject: [PATCH 10/79] vc_screen: sanitize types in vcs_write * ret can carry error codes, so make it signed, i.e. ssize_t * pos is derived from the passed ppos, so make it long enough, i.e. loff_t * attr is a boolean, so... * size is limited by vcs_size() which returns an int * written, p, orig_count and this_round are always ">= 0" and "< size", so uint is enough * col and max_col are derived from vc->vc_cols (uint) and p, so make them uint too * place con_buf0 and con_buf declaration to a single line Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-6-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 8aa0d50bcac7..2571d9067b08 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -459,14 +459,13 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct inode *inode = file_inode(file); struct vc_data *vc; - long pos; - long attr, size, written; - char *con_buf0; - int col, maxcol; + char *con_buf0, *con_buf; u16 *org0 = NULL, *org = NULL; - size_t ret; - char *con_buf; - bool viewed; + unsigned int written, col, maxcol; + int size; + ssize_t ret; + loff_t pos; + bool viewed, attr; if (use_unicode(inode)) return -EOPNOTSUPP; @@ -500,9 +499,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) count = size - pos; written = 0; while (count) { - long this_round = count; - size_t orig_count; - long p; + unsigned int orig_count, p, this_round = count; if (this_round > CON_BUF_SIZE) this_round = CON_BUF_SIZE; From 9e6363784e3f1e90416b81c0d0cd16f6bfb304af Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:57 +0200 Subject: [PATCH 11/79] vc_screen: extract vcs_write_buf_noattr vcs_write is too long to be readable. Extract buffer handling w/o attributes from there to a separate function. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-7-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 55 +++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 2571d9067b08..62e6d240f0dd 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -454,6 +454,33 @@ unlock_out: return ret; } +static u16 *vcs_write_buf_noattr(struct vc_data *vc, const char *con_buf, + unsigned int pos, unsigned int count, bool viewed, u16 **org0) +{ + u16 *org; + unsigned int col, maxcol = vc->vc_cols; + + *org0 = org = screen_pos(vc, pos, viewed); + col = pos % maxcol; + pos += maxcol - col; + + while (count > 0) { + unsigned char c = *con_buf++; + + count--; + vcs_scr_writew(vc, + (vcs_scr_readw(vc, org) & 0xff00) | c, org); + org++; + if (++col == maxcol) { + org = screen_pos(vc, pos, viewed); + col = 0; + pos += maxcol; + } + } + + return org; +} + static ssize_t vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -544,29 +571,15 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) * under the lock using the local kernel buffer. */ - con_buf0 = con_buf; - orig_count = this_round; - maxcol = vc->vc_cols; - p = pos; if (!attr) { - org0 = org = screen_pos(vc, p, viewed); - col = p % maxcol; - p += maxcol - col; - - while (this_round > 0) { - unsigned char c = *con_buf0++; - - this_round--; - vcs_scr_writew(vc, - (vcs_scr_readw(vc, org) & 0xff00) | c, org); - org++; - if (++col == maxcol) { - org = screen_pos(vc, p, viewed); - col = 0; - p += maxcol; - } - } + org = vcs_write_buf_noattr(vc, con_buf, pos, this_round, + viewed, &org0); } else { + con_buf0 = con_buf; + orig_count = this_round; + maxcol = vc->vc_cols; + p = pos; + if (p < HEADER_SIZE) { char header[HEADER_SIZE]; From 95e0d57fd49780db89193bc2df67b9eec640c4be Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:58 +0200 Subject: [PATCH 12/79] vc_screen: extract vcs_write_buf This is the counterpart of the previous patch: here, we extract buffer writing with attributes from vcs_write. Now, there is no need for org to be initialized to NULL. The org0 check before update_region() confuses compilers, so check org instead. It provides the same semantics. And it also eliminates the need for initialization of org0. We switch the branches of the attr 'if' too, as the inversion brings only confusion now. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-8-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 168 ++++++++++++++++++++----------------- 1 file changed, 92 insertions(+), 76 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 62e6d240f0dd..10a26fd5f1b7 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -481,14 +481,93 @@ static u16 *vcs_write_buf_noattr(struct vc_data *vc, const char *con_buf, return org; } +static u16 *vcs_write_buf(struct vc_data *vc, const char *con_buf, + unsigned int pos, unsigned int count, bool viewed, u16 **org0) +{ + u16 *org; + unsigned int col, maxcol = vc->vc_cols; + unsigned char c; + + /* header */ + if (pos < HEADER_SIZE) { + char header[HEADER_SIZE]; + + getconsxy(vc, header + 2); + while (pos < HEADER_SIZE && count > 0) { + count--; + header[pos++] = *con_buf++; + } + if (!viewed) + putconsxy(vc, header + 2); + } + + if (!count) + return NULL; + + pos -= HEADER_SIZE; + col = (pos/2) % maxcol; + + *org0 = org = screen_pos(vc, pos/2, viewed); + + /* odd pos -- the first single character */ + if (pos & 1) { + count--; + c = *con_buf++; +#ifdef __BIG_ENDIAN + vcs_scr_writew(vc, c | + (vcs_scr_readw(vc, org) & 0xff00), org); +#else + vcs_scr_writew(vc, (c << 8) | + (vcs_scr_readw(vc, org) & 0xff), org); +#endif + org++; + pos++; + if (++col == maxcol) { + org = screen_pos(vc, pos/2, viewed); + col = 0; + } + } + + pos /= 2; + pos += maxcol - col; + + /* even pos -- handle attr+character pairs */ + while (count > 1) { + unsigned short w; + + w = get_unaligned(((unsigned short *)con_buf)); + vcs_scr_writew(vc, w, org++); + con_buf += 2; + count -= 2; + if (++col == maxcol) { + org = screen_pos(vc, pos, viewed); + col = 0; + pos += maxcol; + } + } + + if (!count) + return org; + + /* odd pos -- the remaining character */ + c = *con_buf++; +#ifdef __BIG_ENDIAN + vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org); +#else + vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org); +#endif + + return org; +} + static ssize_t vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct inode *inode = file_inode(file); struct vc_data *vc; - char *con_buf0, *con_buf; - u16 *org0 = NULL, *org = NULL; - unsigned int written, col, maxcol; + char *con_buf; + u16 *org0, *org; + unsigned int written; int size; ssize_t ret; loff_t pos; @@ -526,7 +605,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) count = size - pos; written = 0; while (count) { - unsigned int orig_count, p, this_round = count; + unsigned int this_round = count; if (this_round > CON_BUF_SIZE) this_round = CON_BUF_SIZE; @@ -571,81 +650,18 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) * under the lock using the local kernel buffer. */ - if (!attr) { + if (attr) + org = vcs_write_buf(vc, con_buf, pos, this_round, + viewed, &org0); + else org = vcs_write_buf_noattr(vc, con_buf, pos, this_round, viewed, &org0); - } else { - con_buf0 = con_buf; - orig_count = this_round; - maxcol = vc->vc_cols; - p = pos; - if (p < HEADER_SIZE) { - char header[HEADER_SIZE]; - - getconsxy(vc, header + 2); - while (p < HEADER_SIZE && this_round > 0) { - this_round--; - header[p++] = *con_buf0++; - } - if (!viewed) - putconsxy(vc, header + 2); - } - p -= HEADER_SIZE; - col = (p/2) % maxcol; - if (this_round > 0) { - org0 = org = screen_pos(vc, p/2, viewed); - if ((p & 1) && this_round > 0) { - char c; - - this_round--; - c = *con_buf0++; -#ifdef __BIG_ENDIAN - vcs_scr_writew(vc, c | - (vcs_scr_readw(vc, org) & 0xff00), org); -#else - vcs_scr_writew(vc, (c << 8) | - (vcs_scr_readw(vc, org) & 0xff), org); -#endif - org++; - p++; - if (++col == maxcol) { - org = screen_pos(vc, p/2, viewed); - col = 0; - } - } - p /= 2; - p += maxcol - col; - } - while (this_round > 1) { - unsigned short w; - - w = get_unaligned(((unsigned short *)con_buf0)); - vcs_scr_writew(vc, w, org++); - con_buf0 += 2; - this_round -= 2; - if (++col == maxcol) { - org = screen_pos(vc, p, viewed); - col = 0; - p += maxcol; - } - } - if (this_round > 0) { - unsigned char c; - - c = *con_buf0++; -#ifdef __BIG_ENDIAN - vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org); -#else - vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org); -#endif - } - } - count -= orig_count; - written += orig_count; - buf += orig_count; - pos += orig_count; - if (org0) + count -= this_round; + written += this_round; + buf += this_round; + pos += this_round; + if (org) update_region(vc, (unsigned long)(org0), org - org0); } *ppos += written; From d7c91c50815beebe14905292404b048a26147c07 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:59 +0200 Subject: [PATCH 13/79] vc_screen: eliminate ifdefs from vcs_write_buf Introduce a new inline function called vc_compile_le16 and do the shifts and ORs there. Depending on LE x BE. I tried cpu_to_le16, but it ends up with worse assembly on BE for whatever reason -- the compiler seems to be unable to optimize the swap. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-9-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 10a26fd5f1b7..36b967825f68 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -481,6 +481,19 @@ static u16 *vcs_write_buf_noattr(struct vc_data *vc, const char *con_buf, return org; } +/* + * Compilers (gcc 10) are unable to optimize the swap in cpu_to_le16. So do it + * the poor man way. + */ +static inline u16 vc_compile_le16(u8 hi, u8 lo) +{ +#ifdef __BIG_ENDIAN + return (lo << 8u) | hi; +#else + return (hi << 8u) | lo; +#endif +} + static u16 *vcs_write_buf(struct vc_data *vc, const char *con_buf, unsigned int pos, unsigned int count, bool viewed, u16 **org0) { @@ -513,13 +526,8 @@ static u16 *vcs_write_buf(struct vc_data *vc, const char *con_buf, if (pos & 1) { count--; c = *con_buf++; -#ifdef __BIG_ENDIAN - vcs_scr_writew(vc, c | - (vcs_scr_readw(vc, org) & 0xff00), org); -#else - vcs_scr_writew(vc, (c << 8) | - (vcs_scr_readw(vc, org) & 0xff), org); -#endif + vcs_scr_writew(vc, vc_compile_le16(c, vcs_scr_readw(vc, org)), + org); org++; pos++; if (++col == maxcol) { @@ -551,11 +559,8 @@ static u16 *vcs_write_buf(struct vc_data *vc, const char *con_buf, /* odd pos -- the remaining character */ c = *con_buf++; -#ifdef __BIG_ENDIAN - vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org); -#else - vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org); -#endif + vcs_scr_writew(vc, vc_compile_le16(vcs_scr_readw(vc, org) >> 8, c), + org); return org; } From 36c39220129e4048b6810dc732b49b4f23f2dcee Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:57:00 +0200 Subject: [PATCH 14/79] vc_screen: sanitize types in vcs_read * pos is derived from the passed ppos, so make it long enough, i.e. loff_t * attr and uni_mode are booleans, so... * size is limited by vcs_size() which returns an int * read, p, orig_count and this_round are always ">= 0" and "< size", so uint is enough * row, col, and max_col are derived from vc->vc_cols (uint) and p, so make them uint too * tmp_count is derived from this_round, so make it an uint too. * use u16 * for org (instead of unsigned short *). No need to initialize org too. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-10-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 36b967825f68..c62c590ed816 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -256,12 +256,12 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) struct inode *inode = file_inode(file); struct vc_data *vc; struct vcs_poll_data *poll; - long pos, read; - int attr, uni_mode, row, col, maxcol; - unsigned short *org = NULL; + u16 *org; + unsigned int read, row, col, maxcol; ssize_t ret; char *con_buf; - bool viewed; + loff_t pos; + bool viewed, attr, uni_mode; con_buf = (char *) __get_free_page(GFP_KERNEL); if (!con_buf) @@ -295,9 +295,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) ret = 0; while (count) { char *con_buf0, *con_buf_start; - long this_round, size; - ssize_t orig_count; - long p = pos; + unsigned int this_round, orig_count, p = pos; + int size; /* Check whether we are above size each round, * as copy_to_user at the end of this loop @@ -362,7 +361,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) } } else { if (p < HEADER_SIZE) { - size_t tmp_count; + unsigned int tmp_count; /* clamp header values if they don't fit */ con_buf0[0] = min(vc->vc_rows, 0xFFu); From 6d507c75e0cd359e4cede48230fb7e7a45c9bb74 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:57:01 +0200 Subject: [PATCH 15/79] vs_screen: kill tmp_count from vcs_read Both tmp_count computations and the single use can be eliminated using min(). Do so. Side note: we need HEADER_SIZE to be unsigned for min() not to complain. Fix that too as all its other uses do not mind. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-11-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index c62c590ed816..8ebb6724a804 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -53,7 +53,7 @@ #undef attr #undef org #undef addr -#define HEADER_SIZE 4 +#define HEADER_SIZE 4u #define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE) @@ -361,8 +361,6 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) } } else { if (p < HEADER_SIZE) { - unsigned int tmp_count; - /* clamp header values if they don't fit */ con_buf0[0] = min(vc->vc_rows, 0xFFu); con_buf0[1] = min(vc->vc_cols, 0xFFu); @@ -375,12 +373,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) orig_count = this_round - p; } - tmp_count = HEADER_SIZE; - if (tmp_count > this_round) - tmp_count = this_round; - /* Advance state pointers and move on. */ - this_round -= tmp_count; + this_round -= min(HEADER_SIZE, this_round); p = HEADER_SIZE; con_buf0 = con_buf + HEADER_SIZE; /* If this_round >= 0, then p is even... */ From 0f66eee346c1672bdb538031a5fe03ea1e0c626f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:57:02 +0200 Subject: [PATCH 16/79] vc_screen: extract vcs_read_buf_uni The same as making write more readable, extract unicode handling from vcs_read. The other two cases (w/ and w/o attributes) will follow. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-12-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 49 +++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 8ebb6724a804..91d2e0148a67 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -249,6 +249,33 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) return fixed_size_llseek(file, offset, orig, size); } +static int vcs_read_buf_uni(struct vc_data *vc, char *con_buf, + unsigned int pos, unsigned int count, bool viewed) +{ + unsigned int nr, row, col, maxcol = vc->vc_cols; + int ret; + + ret = vc_uniscr_check(vc); + if (ret) + return ret; + + pos /= 4; + row = pos / maxcol; + col = pos % maxcol; + nr = maxcol - col; + do { + if (nr > count / 4) + nr = count / 4; + vc_uniscr_copy_line(vc, con_buf, viewed, row, col, nr); + con_buf += nr * 4; + count -= nr * 4; + row++; + col = 0; + nr = maxcol; + } while (count); + + return 0; +} static ssize_t vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) @@ -257,7 +284,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) struct vc_data *vc; struct vcs_poll_data *poll; u16 *org; - unsigned int read, row, col, maxcol; + unsigned int read, col, maxcol; ssize_t ret; char *con_buf; loff_t pos; @@ -327,26 +354,10 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) orig_count = this_round; maxcol = vc->vc_cols; if (uni_mode) { - unsigned int nr; - - ret = vc_uniscr_check(vc); + ret = vcs_read_buf_uni(vc, con_buf, pos, this_round, + viewed); if (ret) break; - p /= 4; - row = p / vc->vc_cols; - col = p % maxcol; - nr = maxcol - col; - do { - if (nr > this_round/4) - nr = this_round/4; - vc_uniscr_copy_line(vc, con_buf0, viewed, - row, col, nr); - con_buf0 += nr * 4; - this_round -= nr * 4; - row++; - col = 0; - nr = maxcol; - } while (this_round); } else if (!attr) { org = screen_pos(vc, p, viewed); col = p % maxcol; From 5a52baaab029e38e919efff2abc0d4e89338d464 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:57:03 +0200 Subject: [PATCH 17/79] vc_screen: extract vcs_read_buf_noattr Now, move the code for no-attributes handling to a separate function. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-13-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 91d2e0148a67..ad015cd4e82f 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -277,6 +277,26 @@ static int vcs_read_buf_uni(struct vc_data *vc, char *con_buf, return 0; } +static void vcs_read_buf_noattr(const struct vc_data *vc, char *con_buf, + unsigned int pos, unsigned int count, bool viewed) +{ + u16 *org; + unsigned int col, maxcol = vc->vc_cols; + + org = screen_pos(vc, pos, viewed); + col = pos % maxcol; + pos += maxcol - col; + + while (count-- > 0) { + *con_buf++ = (vcs_scr_readw(vc, org++) & 0xff); + if (++col == maxcol) { + org = screen_pos(vc, pos, viewed); + col = 0; + pos += maxcol; + } + } +} + static ssize_t vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -359,17 +379,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) if (ret) break; } else if (!attr) { - org = screen_pos(vc, p, viewed); - col = p % maxcol; - p += maxcol - col; - while (this_round-- > 0) { - *con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff); - if (++col == maxcol) { - org = screen_pos(vc, p, viewed); - col = 0; - p += maxcol; - } - } + vcs_read_buf_noattr(vc, con_buf, pos, this_round, + viewed); } else { if (p < HEADER_SIZE) { /* clamp header values if they don't fit */ From 6a6b76cc44c98a39d3e718aa2056e2e12b609615 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:57:04 +0200 Subject: [PATCH 18/79] vc_screen: extract vcs_read_buf And finally, move the attributes buffer handling to a separate function. Leaving vcs_read quite compact. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-14-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 146 ++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 68 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index ad015cd4e82f..c178a1611223 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -297,14 +297,81 @@ static void vcs_read_buf_noattr(const struct vc_data *vc, char *con_buf, } } +static unsigned int vcs_read_buf(const struct vc_data *vc, char *con_buf, + unsigned int pos, unsigned int count, bool viewed, + unsigned int *skip) +{ + u16 *org, *con_buf16; + unsigned int col, maxcol = vc->vc_cols; + unsigned int filled = count; + + if (pos < HEADER_SIZE) { + /* clamp header values if they don't fit */ + con_buf[0] = min(vc->vc_rows, 0xFFu); + con_buf[1] = min(vc->vc_cols, 0xFFu); + getconsxy(vc, con_buf + 2); + + *skip += pos; + count += pos; + if (count > CON_BUF_SIZE) { + count = CON_BUF_SIZE; + filled = count - pos; + } + + /* Advance state pointers and move on. */ + count -= min(HEADER_SIZE, count); + pos = HEADER_SIZE; + con_buf += HEADER_SIZE; + /* If count >= 0, then pos is even... */ + } else if (pos & 1) { + /* + * Skip first byte for output if start address is odd. Update + * region sizes up/down depending on free space in buffer. + */ + (*skip)++; + if (count < CON_BUF_SIZE) + count++; + else + filled--; + } + + if (!count) + return filled; + + pos -= HEADER_SIZE; + pos /= 2; + col = pos % maxcol; + + org = screen_pos(vc, pos, viewed); + pos += maxcol - col; + + /* + * Buffer has even length, so we can always copy character + attribute. + * We do not copy last byte to userspace if count is odd. + */ + count = (count + 1) / 2; + con_buf16 = (u16 *)con_buf; + + while (count) { + *con_buf16++ = vcs_scr_readw(vc, org++); + count--; + if (++col == maxcol) { + org = screen_pos(vc, pos, viewed); + col = 0; + pos += maxcol; + } + } + + return filled; +} + static ssize_t vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct inode *inode = file_inode(file); struct vc_data *vc; struct vcs_poll_data *poll; - u16 *org; - unsigned int read, col, maxcol; + unsigned int read; ssize_t ret; char *con_buf; loff_t pos; @@ -341,8 +408,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) read = 0; ret = 0; while (count) { - char *con_buf0, *con_buf_start; - unsigned int this_round, orig_count, p = pos; + unsigned int this_round, skip = 0; int size; /* Check whether we are above size each round, @@ -370,9 +436,6 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) * attempt to move it to userspace. */ - con_buf_start = con_buf0 = con_buf; - orig_count = this_round; - maxcol = vc->vc_cols; if (uni_mode) { ret = vcs_read_buf_uni(vc, con_buf, pos, this_round, viewed); @@ -382,61 +445,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) vcs_read_buf_noattr(vc, con_buf, pos, this_round, viewed); } else { - if (p < HEADER_SIZE) { - /* clamp header values if they don't fit */ - con_buf0[0] = min(vc->vc_rows, 0xFFu); - con_buf0[1] = min(vc->vc_cols, 0xFFu); - getconsxy(vc, con_buf0 + 2); - - con_buf_start += p; - this_round += p; - if (this_round > CON_BUF_SIZE) { - this_round = CON_BUF_SIZE; - orig_count = this_round - p; - } - - /* Advance state pointers and move on. */ - this_round -= min(HEADER_SIZE, this_round); - p = HEADER_SIZE; - con_buf0 = con_buf + HEADER_SIZE; - /* If this_round >= 0, then p is even... */ - } else if (p & 1) { - /* Skip first byte for output if start address is odd - * Update region sizes up/down depending on free - * space in buffer. - */ - con_buf_start++; - if (this_round < CON_BUF_SIZE) - this_round++; - else - orig_count--; - } - if (this_round > 0) { - unsigned short *tmp_buf = (unsigned short *)con_buf0; - - p -= HEADER_SIZE; - p /= 2; - col = p % maxcol; - - org = screen_pos(vc, p, viewed); - p += maxcol - col; - - /* Buffer has even length, so we can always copy - * character + attribute. We do not copy last byte - * to userspace if this_round is odd. - */ - this_round = (this_round + 1) >> 1; - - while (this_round) { - *tmp_buf++ = vcs_scr_readw(vc, org++); - this_round --; - if (++col == maxcol) { - org = screen_pos(vc, p, viewed); - col = 0; - p += maxcol; - } - } - } + this_round = vcs_read_buf(vc, con_buf, pos, this_round, + viewed, &skip); } /* Finally, release the console semaphore while we push @@ -447,18 +457,18 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) */ console_unlock(); - ret = copy_to_user(buf, con_buf_start, orig_count); + ret = copy_to_user(buf, con_buf + skip, this_round); console_lock(); if (ret) { - read += (orig_count - ret); + read += this_round - ret; ret = -EFAULT; break; } - buf += orig_count; - pos += orig_count; - read += orig_count; - count -= orig_count; + buf += this_round; + pos += this_round; + read += this_round; + count -= this_round; } *ppos += read; if (read) From b1c32fcfadf5593ab7a63261cc8a5747c36e627e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:57:05 +0200 Subject: [PATCH 19/79] vc_screen: extract vcs_read_buf_header The attribute header handling is terrible in vcs_read_buf. Separate it to a new function and simply do memmove (of up to 4 bytes) to the start of the con_buf -- if user seeked. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-15-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index c178a1611223..9d68c6b36ddf 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -297,6 +297,22 @@ static void vcs_read_buf_noattr(const struct vc_data *vc, char *con_buf, } } +static unsigned int vcs_read_buf_header(const struct vc_data *vc, char *con_buf, + unsigned int pos, unsigned int count) +{ + count = min(HEADER_SIZE - pos, count); + + /* clamp header values if they don't fit */ + con_buf[0] = min(vc->vc_rows, 0xFFu); + con_buf[1] = min(vc->vc_cols, 0xFFu); + getconsxy(vc, con_buf + 2); + + if (pos) + memmove(con_buf, con_buf + pos, count); + + return count; +} + static unsigned int vcs_read_buf(const struct vc_data *vc, char *con_buf, unsigned int pos, unsigned int count, bool viewed, unsigned int *skip) @@ -306,22 +322,11 @@ static unsigned int vcs_read_buf(const struct vc_data *vc, char *con_buf, unsigned int filled = count; if (pos < HEADER_SIZE) { - /* clamp header values if they don't fit */ - con_buf[0] = min(vc->vc_rows, 0xFFu); - con_buf[1] = min(vc->vc_cols, 0xFFu); - getconsxy(vc, con_buf + 2); + count -= vcs_read_buf_header(vc, con_buf, pos, count); - *skip += pos; - count += pos; - if (count > CON_BUF_SIZE) { - count = CON_BUF_SIZE; - filled = count - pos; - } - - /* Advance state pointers and move on. */ - count -= min(HEADER_SIZE, count); pos = HEADER_SIZE; con_buf += HEADER_SIZE; + /* If count >= 0, then pos is even... */ } else if (pos & 1) { /* From a89313825b0657273e1938aea7f13afe9abb44e8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:57:06 +0200 Subject: [PATCH 20/79] vc_screen: prune macros Do not undefine random words. I guess this was here as there were macros with such generic names somewhere. I very doubt they still exist. So drop these. And remove a spare blank line. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085706.12163-16-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 9d68c6b36ddf..3e3a6a9a7f44 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -50,11 +50,7 @@ #include #include -#undef attr -#undef org -#undef addr #define HEADER_SIZE 4u - #define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE) /* From a579767c1f4e3270818504843a86ba3277127152 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:48 +0200 Subject: [PATCH 21/79] tty: n_gsm, eliminate indirection for gsm->{output,error}() gsm->output and ->error are set only to gsmld_output and gsm_error, respectively. Call these functions directly and remove error and output function pointers from struct gsm_mux completely. Note: we need a forward declaration of gsmld_output now. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085655.12071-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 0a29a94ec438..10f8fc07f23c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -222,11 +222,8 @@ struct gsm_mux { u8 received_fcs; u8 *txframe; /* TX framing buffer */ - /* Methods for the receiver side */ + /* Method for the receiver side */ void (*receive)(struct gsm_mux *gsm, u8 ch); - void (*error)(struct gsm_mux *gsm, u8 ch, u8 flag); - /* And transmit side */ - int (*output)(struct gsm_mux *mux, u8 *data, int len); /* Link Layer */ unsigned int mru; @@ -366,6 +363,8 @@ static const u8 gsm_fcs8[256] = { #define INIT_FCS 0xFF #define GOOD_FCS 0xCF +static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len); + /** * gsm_fcs_add - update FCS * @fcs: Current FCS @@ -587,7 +586,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control) WARN_ON(1); return; } - gsm->output(gsm, cbuf, len); + gsmld_output(gsm, cbuf, len); gsm_print_packet("-->", addr, cr, control, NULL, 0); } @@ -687,7 +686,7 @@ static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci) print_hex_dump_bytes("gsm_data_kick: ", DUMP_PREFIX_OFFSET, gsm->txframe, len); - if (gsm->output(gsm, gsm->txframe, len) < 0) + if (gsmld_output(gsm, gsm->txframe, len) < 0) break; /* FIXME: Can eliminate one SOF in many more cases */ gsm->tx_bytes -= msg->len; @@ -2128,7 +2127,6 @@ static int gsm_activate_mux(struct gsm_mux *gsm) gsm->receive = gsm0_receive; else gsm->receive = gsm1_receive; - gsm->error = gsm_error; spin_lock(&gsm_mux_lock); for (i = 0; i < MAX_MUX; i++) { @@ -2378,7 +2376,6 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) int ret, i; gsm->tty = tty_kref_get(tty); - gsm->output = gsmld_output; ret = gsm_activate_mux(gsm); if (ret != 0) tty_kref_put(gsm->tty); @@ -2438,7 +2435,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, case TTY_BREAK: case TTY_PARITY: case TTY_FRAME: - gsm->error(gsm, *dp, flags); + gsm_error(gsm, *dp, flags); break; default: WARN_ONCE(1, "%s: unknown flag %d\n", From e18d918bd2ccd725ac574f7d126ed0856fe794e3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:49 +0200 Subject: [PATCH 22/79] newport_con: fix no return statement in newport_show_logo When CONFIG_LOGO_SGI_CLUT224 is unset, newport_show_logo contains no return, despite it should return a pointer. Add one returning NULL to fix a compiler warning: drivers/video/console/newport_con.c: In function 'newport_show_logo': drivers/video/console/newport_con.c:132:1: warning: no return statement in function returning non-void Note that the caller expects NULL from the function already. Signed-off-by: Jiri Slaby Cc: Bartlomiej Zolnierkiewicz Cc: dri-devel@lists.freedesktop.org Cc: linux-fbdev@vger.kernel.org Cc: linux-mips@vger.kernel.org Link: https://lore.kernel.org/r/20200818085655.12071-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/newport_con.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 72f146d047d9..4d9110393479 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -131,6 +131,8 @@ static const struct linux_logo *newport_show_logo(void) npregs->go.hostrw0 = *data++ << 24; return logo; +#else + return NULL; #endif /* CONFIG_LOGO_SGI_CLUT224 */ } From 9b07655c7740a97b918ebe7dc59447e29e22a957 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:50 +0200 Subject: [PATCH 23/79] newport_con: make module's init & exit static using module_driver The compiler complains that newport_console_init and newport_console_exit are not declared: drivers/video/console/newport_con.c:745:12: warning: no previous prototype for 'newport_console_init' drivers/video/console/newport_con.c:750:13: warning: no previous prototype for 'newport_console_exit' Here, it translates into: they should be marked static. Do so by converting the simple un/registration to module_driver(). Signed-off-by: Jiri Slaby Cc: Bartlomiej Zolnierkiewicz Cc: dri-devel@lists.freedesktop.org Cc: linux-fbdev@vger.kernel.org Cc: linux-mips@vger.kernel.org Link: https://lore.kernel.org/r/20200818085655.12071-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/newport_con.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 4d9110393479..0d0989040c58 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -751,18 +751,6 @@ static struct gio_driver newport_driver = { .probe = newport_probe, .remove = newport_remove, }; - -int __init newport_console_init(void) -{ - return gio_register_driver(&newport_driver); -} - -void __exit newport_console_exit(void) -{ - gio_unregister_driver(&newport_driver); -} - -module_init(newport_console_init); -module_exit(newport_console_exit); +module_driver(newport_driver, gio_register_driver, gio_unregister_driver); MODULE_LICENSE("GPL"); From fa44195455c42de656bf5040a80d482526f45c8e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:51 +0200 Subject: [PATCH 24/79] tty: fix kernel-doc With W=1, the kernel-doc checker complains quite a lot in the tty layer. Over the time, many documented parameters were renamed, removed or switched from tty to tty_port and similar. Some were mistyped in the doc too. So fix all these in the tty core. (But do not add the missing ones which the checker complains about too. Not now.) The rest in the tty layer will follow in the next patches. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085655.12071-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 2 +- drivers/tty/tty_baudrate.c | 6 +++--- drivers/tty/tty_buffer.c | 14 +++++++------- drivers/tty/tty_io.c | 26 ++++++++++++-------------- drivers/tty/tty_jobctrl.c | 4 ++-- drivers/tty/tty_ldisc.c | 3 +-- 6 files changed, 26 insertions(+), 29 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 00099a8439d2..b6d8cc7f0f16 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -100,7 +100,7 @@ static void pty_unthrottle(struct tty_struct *tty) * pty_write - write to a pty * @tty: the tty we write from * @buf: kernel buffer of data - * @count: bytes to write + * @c: bytes to write * * Our "hardware" write method. Data is coming from the ldisc which * may be in a non sleeping state. We simply throw this at the other diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c index 40207cab3b2a..84fec3c62d6a 100644 --- a/drivers/tty/tty_baudrate.c +++ b/drivers/tty/tty_baudrate.c @@ -119,8 +119,8 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); /** * tty_termios_encode_baud_rate * @termios: ktermios structure holding user requested state - * @ispeed: input speed - * @ospeed: output speed + * @ibaud: input speed + * @obaud: output speed * * Encode the speeds set into the passed termios structure. This is * used as a library helper for drivers so that they can report back @@ -223,7 +223,7 @@ EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); /** * tty_encode_baud_rate - set baud rate of the tty * @ibaud: input baud rate - * @obad: output baud rate + * @obaud: output baud rate * * Update the current termios data for the tty with the new speed * settings. The caller must hold the termios_rwsem for the tty in diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index ec145a59f199..bd2d91546e32 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -42,7 +42,7 @@ * tty_buffer_lock_exclusive - gain exclusive access to buffer * tty_buffer_unlock_exclusive - release exclusive access * - * @port - tty_port owning the flip buffer + * @port: tty port owning the flip buffer * * Guarantees safe use of the line discipline's receive_buf() method by * excluding the buffer work and any pending flush from using the flip @@ -78,7 +78,7 @@ EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive); /** * tty_buffer_space_avail - return unused buffer space - * @port - tty_port owning the flip buffer + * @port: tty port owning the flip buffer * * Returns the # of bytes which can be written by the driver without * reaching the buffer limit. @@ -107,7 +107,7 @@ static void tty_buffer_reset(struct tty_buffer *p, size_t size) /** * tty_buffer_free_all - free buffers used by a tty - * @tty: tty to free from + * @port: tty port to free from * * Remove all the buffers pending on a tty whether queued with data * or in the free ring. Must be called when the tty is no longer in use @@ -142,7 +142,7 @@ void tty_buffer_free_all(struct tty_port *port) /** * tty_buffer_alloc - allocate a tty buffer - * @tty: tty device + * @port: tty port * @size: desired size (characters) * * Allocate a new tty buffer to hold the desired number of characters. @@ -184,7 +184,7 @@ found: /** * tty_buffer_free - free a tty buffer - * @tty: tty owning the buffer + * @port: tty port owning the buffer * @b: the buffer to free * * Free a tty buffer, or add it to the free list according to our @@ -243,7 +243,7 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld) /** * tty_buffer_request_room - grow tty buffer if needed - * @tty: tty structure + * @port: tty port * @size: size desired * @flags: buffer flags if new buffer allocated (default = 0) * @@ -559,7 +559,7 @@ EXPORT_SYMBOL(tty_flip_buffer_push); /** * tty_buffer_init - prepare a tty buffer structure - * @tty: tty to initialise + * @port: tty port to initialise * * Set up the initial state of the buffer management for a tty device. * Must be called before the other tty buffer functions are used. diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ceed72c9a88f..7a4c02548fb3 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -307,7 +307,7 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) /** * get_tty_driver - find device of a tty - * @dev_t: device identifier + * @device: device identifier * @index: returns the index of the tty * * This routine returns a tty driver structure, given a device number @@ -544,7 +544,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); /** * __tty_hangup - actual handler for hangup events - * @work: tty device + * @tty: tty device * * This can be called by a "kworker" kernel thread. That is process * synchronous but doesn't hold any locks, so we need to make sure we @@ -1232,7 +1232,7 @@ static int tty_driver_install_tty(struct tty_driver *driver, /** * tty_driver_remove_tty() - remove a tty from the driver tables * @driver: the driver for the tty - * @idx: the minor number + * @tty: tty to remove * * Remvoe a tty object from the driver tables. The tty->index field * will be set by the time this is called. @@ -1247,9 +1247,9 @@ static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct * driver->ttys[tty->index] = NULL; } -/* - * tty_reopen() - fast re-open of an open tty - * @tty - the tty to open +/** + * tty_reopen() - fast re-open of an open tty + * @tty: the tty to open * * Return 0 on success, -errno on error. * Re-opens on master ptys are not allowed and return -EIO. @@ -1295,7 +1295,6 @@ static int tty_reopen(struct tty_struct *tty) * tty_init_dev - initialise a tty device * @driver: tty driver we are opening a device on * @idx: device index - * @ret_tty: returned tty structure * * Prepare a tty device. This may not be a "new" clean device but * could also be an active device. The pty drivers require special @@ -1313,6 +1312,8 @@ static int tty_reopen(struct tty_struct *tty) * failed open. The new code protects the open with a mutex, so it's * really quite straightforward. The mutex locking can probably be * relaxed for the (most common) case of reopening a tty. + * + * Return: returned tty structure */ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) @@ -1432,7 +1433,7 @@ static void tty_flush_works(struct tty_struct *tty) /** * release_one_tty - release tty structure memory - * @kref: kref of tty we are obliterating + * @work: work of tty we are obliterating * * Releases memory associated with a tty structure, and clears out the * driver table slots. This function is called when a device is no longer @@ -1528,7 +1529,6 @@ static void release_tty(struct tty_struct *tty, int idx) /** * tty_release_checks - check a tty before real release * @tty: tty to check - * @o_tty: link of @tty (if any) * @idx: index of the tty * * Performs some paranoid checking before true release of the @tty. @@ -2200,7 +2200,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p) /** * tiocgwinsz - implement window query ioctl - * @tty; tty + * @tty: tty * @arg: user buffer for result * * Copies the kernel idea of the window size into the user buffer. @@ -2223,8 +2223,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) /** * tty_do_resize - resize event * @tty: tty being resized - * @rows: rows (character) - * @cols: cols (character) + * @ws: new dimensions * * Update the termios variables and send the necessary signals to * peform a terminal resize correctly @@ -2254,7 +2253,7 @@ EXPORT_SYMBOL(tty_do_resize); /** * tiocswinsz - implement window size set ioctl - * @tty; tty side of tty + * @tty: tty side of tty * @arg: user buffer for result * * Copies the user idea of the window size to the kernel. Traditionally @@ -2402,7 +2401,6 @@ out: /** * tty_tiocmget - get modem status * @tty: tty device - * @file: user file pointer * @p: pointer to result * * Obtain the modem status bits from the tty driver if the feature diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c index f8ed50a16848..28a23a0fef21 100644 --- a/drivers/tty/tty_jobctrl.c +++ b/drivers/tty/tty_jobctrl.c @@ -178,8 +178,8 @@ void session_clear_tty(struct pid *session) /** * tty_signal_session_leader - sends SIGHUP to session leader - * @tty controlling tty - * @exit_session if non-zero, signal all foreground group processes + * @tty: controlling tty + * @exit_session: if non-zero, signal all foreground group processes * * Send SIGHUP and SIGCONT to the session leader and its process group. * Optionally, signal all processes in the foreground process group. diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index ec1f6a48121e..fe37ec331289 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -79,7 +79,6 @@ EXPORT_SYMBOL(tty_register_ldisc); /** * tty_unregister_ldisc - unload a line discipline * @disc: ldisc number - * @new_ldisc: pointer to the ldisc object * * Remove a line discipline from the kernel providing it is not * currently in use. @@ -542,7 +541,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) /** * tty_set_ldisc - set line discipline * @tty: the terminal to set - * @ldisc: the line discipline + * @disc: the line discipline number * * Set the discipline of a tty line. Must be called from a process * context. The ldisc change logic has to protect itself against any From 724ac070ffc7a1e7526be4408edbd324a4163e15 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:52 +0200 Subject: [PATCH 25/79] tty: ldiscs, fix kernel-doc As in the previous patch, fix kernel-doc in line disciplines. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085655.12071-5-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 23 +++++++------- drivers/tty/n_hdlc.c | 72 ++++++++++++++++++++++---------------------- drivers/tty/n_tty.c | 4 +-- 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 10f8fc07f23c..67baa884b0c5 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -76,10 +76,9 @@ module_param(debug, int, 0600); /** * struct gsm_mux_net - network interface - * @struct gsm_dlci* dlci * * Created when net interface is initialized. - **/ + */ struct gsm_mux_net { struct kref ref; struct gsm_dlci *dlci; @@ -399,7 +398,7 @@ static inline u8 gsm_fcs_add_block(u8 fcs, u8 *c, int len) /** * gsm_read_ea - read a byte into an EA * @val: variable holding value - * c: byte going into the EA + * @c: byte going into the EA * * Processes one byte of an EA. Updates the passed variable * and returns 1 if the EA is now completely read @@ -513,8 +512,8 @@ static void gsm_print_packet(const char *hdr, int addr, int cr, /** * gsm_stuff_packet - bytestuff a packet - * @ibuf: input - * @obuf: output + * @input: input buffer + * @output: output buffer * @len: length of input * * Expand a buffer by bytestuffing it. The worst case size change @@ -1304,7 +1303,7 @@ static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl) /** * gsm_control_retransmit - retransmit a control frame - * @data: pointer to our gsm object + * @t: timer contained in our gsm object * * Called off the T2 timer expiry in order to retransmit control frames * that have been lost in the system somewhere. The control_lock protects @@ -1341,7 +1340,7 @@ static void gsm_control_retransmit(struct timer_list *t) * @gsm: the GSM channel * @command: command to send including CR bit * @data: bytes of data (must be kmalloced) - * @len: length of the block to send + * @clen: length of the block to send * * Queue and dispatch a control command. Only one command can be * active at a time. In theory more can be outstanding but the matching @@ -1453,7 +1452,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) /** * gsm_dlci_t1 - T1 timer expiry - * @dlci: DLCI that opened + * @t: timer contained in the DLCI that opened * * The T1 timer handles retransmits of control frames (essentially of * SABM and DISC). We resend the command until the retry count runs out @@ -1549,7 +1548,7 @@ static void gsm_dlci_begin_close(struct gsm_dlci *dlci) * gsm_dlci_data - data arrived * @dlci: channel * @data: block of bytes received - * @len: length of received block + * @clen: length of received block * * A UI or UIH frame has arrived which contains data for a channel * other than the control channel. If the relevant virtual tty is @@ -1671,7 +1670,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) /** * gsm_dlci_free - free DLCI - * @dlci: DLCI to free + * @port: tty port for DLCI to free * * Free up a DLCI. * @@ -2149,7 +2148,7 @@ static int gsm_activate_mux(struct gsm_mux *gsm) /** * gsm_free_mux - free up a mux - * @mux: mux to free + * @gsm: mux to free * * Dispose of allocated resources for a dead mux */ @@ -2162,7 +2161,7 @@ static void gsm_free_mux(struct gsm_mux *gsm) /** * gsm_free_muxr - free up a mux - * @mux: mux to free + * @ref: kreference to the mux to free * * Dispose of allocated resources for a dead mux */ diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index b09eac4b6d64..9ba967f8b7ca 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -123,13 +123,13 @@ struct n_hdlc_buf_list { /** * struct n_hdlc - per device instance data structure - * @magic - magic value for structure - * @tbusy - reentrancy flag for tx wakeup code - * @woke_up - tx wakeup needs to be run again as it was called while @tbusy - * @tx_buf_list - list of pending transmit frame buffers - * @rx_buf_list - list of received frame buffers - * @tx_free_buf_list - list unused transmit frame buffers - * @rx_free_buf_list - list unused received frame buffers + * @magic: magic value for structure + * @tbusy: reentrancy flag for tx wakeup code + * @woke_up: tx wakeup needs to be run again as it was called while @tbusy + * @tx_buf_list: list of pending transmit frame buffers + * @rx_buf_list: list of received frame buffers + * @tx_free_buf_list: list unused transmit frame buffers + * @rx_free_buf_list: list unused received frame buffers */ struct n_hdlc { int magic; @@ -187,7 +187,7 @@ static void n_hdlc_free_buf_list(struct n_hdlc_buf_list *list) /** * n_hdlc_tty_close - line discipline close - * @tty - pointer to tty info structure + * @tty: pointer to tty info structure * * Called when the line discipline is changed to something * else, the tty is closed, or the tty detects a hangup. @@ -218,7 +218,7 @@ static void n_hdlc_tty_close(struct tty_struct *tty) /** * n_hdlc_tty_open - called when line discipline changed to n_hdlc - * @tty - pointer to tty info structure + * @tty: pointer to tty info structure * * Returns 0 if success, otherwise error code */ @@ -255,8 +255,8 @@ static int n_hdlc_tty_open(struct tty_struct *tty) /** * n_hdlc_send_frames - send frames on pending send buffer list - * @n_hdlc - pointer to ldisc instance data - * @tty - pointer to tty instance data + * @n_hdlc: pointer to ldisc instance data + * @tty: pointer to tty instance data * * Send frames on pending send buffer list until the driver does not accept a * frame (busy) this function is called after adding a frame to the send buffer @@ -335,7 +335,7 @@ check_again: /** * n_hdlc_tty_wakeup - Callback for transmit wakeup - * @tty - pointer to associated tty instance data + * @tty: pointer to associated tty instance data * * Called when low level device driver can accept more send data. */ @@ -348,10 +348,10 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) /** * n_hdlc_tty_receive - Called by tty driver when receive data is available - * @tty - pointer to tty instance data - * @data - pointer to received data - * @flags - pointer to flags for data - * @count - count of received data in bytes + * @tty: pointer to tty instance data + * @data: pointer to received data + * @flags: pointer to flags for data + * @count: count of received data in bytes * * Called by tty low level driver when receive data is available. Data is * interpreted as one HDLC frame. @@ -408,10 +408,10 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, /** * n_hdlc_tty_read - Called to retrieve one frame of data (if available) - * @tty - pointer to tty instance data - * @file - pointer to open file object - * @buf - pointer to returned data buffer - * @nr - size of returned data buffer + * @tty: pointer to tty instance data + * @file: pointer to open file object + * @buf: pointer to returned data buffer + * @nr: size of returned data buffer * * Returns the number of bytes returned or error code. */ @@ -479,10 +479,10 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, /** * n_hdlc_tty_write - write a single frame of data to device - * @tty - pointer to associated tty device instance data - * @file - pointer to file object data - * @data - pointer to transmit data (one frame) - * @count - size of transmit frame in bytes + * @tty: pointer to associated tty device instance data + * @file: pointer to file object data + * @data: pointer to transmit data (one frame) + * @count: size of transmit frame in bytes * * Returns the number of bytes written (or error code). */ @@ -546,10 +546,10 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, /** * n_hdlc_tty_ioctl - process IOCTL system call for the tty device. - * @tty - pointer to tty instance data - * @file - pointer to open file object for device - * @cmd - IOCTL command code - * @arg - argument for IOCTL call (cmd dependent) + * @tty: pointer to tty instance data + * @file: pointer to open file object for device + * @cmd: IOCTL command code + * @arg: argument for IOCTL call (cmd dependent) * * Returns command dependent result. */ @@ -614,9 +614,9 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, /** * n_hdlc_tty_poll - TTY callback for poll system call - * @tty - pointer to tty instance data - * @filp - pointer to open file object for device - * @poll_table - wait queue for operations + * @tty: pointer to tty instance data + * @filp: pointer to open file object for device + * @wait: wait queue for operations * * Determine which operations (read/write) will not block and return info * to caller. @@ -703,8 +703,8 @@ static struct n_hdlc *n_hdlc_alloc(void) /** * n_hdlc_buf_return - put the HDLC buffer after the head of the specified list - * @buf_list - pointer to the buffer list - * @buf - pointer to the buffer + * @buf_list: pointer to the buffer list + * @buf: pointer to the buffer */ static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list, struct n_hdlc_buf *buf) @@ -721,8 +721,8 @@ static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list, /** * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list - * @buf_list - pointer to buffer list - * @buf - pointer to buffer + * @buf_list: pointer to buffer list + * @buf: pointer to buffer */ static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list, struct n_hdlc_buf *buf) @@ -739,7 +739,7 @@ static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list, /** * n_hdlc_buf_get - remove and return an HDLC buffer from list - * @buf_list - pointer to HDLC buffer list + * @buf_list: pointer to HDLC buffer list * * Remove and return an HDLC buffer from the head of the specified HDLC buffer * list. diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 1794d84e7bf6..7e5e36315260 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -322,7 +322,7 @@ static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata) /** * reset_buffer_flags - reset buffer state - * @tty: terminal to reset + * @ldata: line disc data to reset * * Reset the read buffer counters and clear the flags. * Called from n_tty_open() and n_tty_flush_buffer(). @@ -906,7 +906,7 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab, /** * echo_char_raw - echo a character raw * @c: unicode byte to echo - * @tty: terminal device + * @ldata: line disc data * * Echo user input back onto the screen. This must be called only when * L_ECHO(tty) is true. Called from the driver receive_buf path. From ea239f1e32af046f826d816b75599b7608eaa542 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:53 +0200 Subject: [PATCH 26/79] tty: vt, fix kernel-doc As in the previous patches, fix kernel-doc in vt. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085655.12071-6-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/consolemap.c | 2 +- drivers/tty/vt/vt.c | 7 ++++--- drivers/tty/vt/vt_ioctl.c | 3 +-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 5d5a5fd2dce7..5d778c0aa009 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -708,7 +708,7 @@ EXPORT_SYMBOL(con_set_default_unimap); /** * con_copy_unimap - copy unimap between two vts * @dst_vc: target - * @src_vt: source + * @src_vc: source * * The caller must hold the console lock when invoking this method */ diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 0f7064d41e92..71f972675fee 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1181,7 +1181,6 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, /** * vc_do_resize - resizing method for the tty * @tty: tty being resized - * @real_tty: real tty (different to tty if a pty/tty pair) * @vc: virtual console private data * @cols: columns * @lines: lines @@ -2607,6 +2606,9 @@ static inline int vc_sanitize_unicode(const int c) /** * vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char + * @vc: virtual console + * @c: character to translate + * @rescan: we return true if we need more (continuation) data * * @vc_utf_char is the being-constructed unicode character. * @vc_utf_count is the number of continuation bytes still expected to arrive. @@ -3982,7 +3984,7 @@ EXPORT_SYMBOL(con_is_visible); /** * con_debug_enter - prepare the console for the kernel debugger - * @sw: console driver + * @vc: virtual console * * Called when the console is taken over by the kernel debugger, this * function needs to save the current console state, then put the console @@ -4040,7 +4042,6 @@ EXPORT_SYMBOL_GPL(con_debug_enter); /** * con_debug_leave - restore console state - * @sw: console driver * * Restore the console state to what it was before the kernel debugger * was invoked. diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 91c301775047..7726df6b9b6f 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -181,7 +181,7 @@ static void vt_event_wait(struct vt_event_wait *vw) /** * vt_event_wait_ioctl - event ioctl handler - * @arg: argument to ioctl + * @event: argument to ioctl (the event) * * Implement the VT_WAITEVENT ioctl using the VT event interface */ @@ -208,7 +208,6 @@ static int vt_event_wait_ioctl(struct vt_event __user *event) /** * vt_waitactive - active console wait - * @event: event code * @n: new console * * Helper for event waits. Used to implement the legacy From 87d03a940be5e6da7b8c6c618d0c51800d4a161b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:54 +0200 Subject: [PATCH 27/79] tty: synclink, fix kernel-doc As in the previous patches, fix kernel-doc in synclink drivers. This is done separately from others, as kernel-doc comments were heavily broken in these drivers. Convert them to proper ones. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085655.12071-7-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink.c | 82 +++++++++++++++++++------------------- drivers/tty/synclink_gt.c | 81 ++++++++++++++++++-------------------- drivers/tty/synclinkmp.c | 83 +++++++++++++++++++-------------------- 3 files changed, 119 insertions(+), 127 deletions(-) diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 0dba40eace46..c8324d58ef56 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -942,7 +942,7 @@ static inline int mgsl_paranoia_check(struct mgsl_struct *info, return 0; } -/** +/* * line discipline callback wrappers * * The wrappers maintain line discipline references @@ -7419,14 +7419,14 @@ static int usc_loopmode_active( struct mgsl_struct * info) #if SYNCLINK_GENERIC_HDLC /** - * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) - * set encoding and frame check sequence (FCS) options + * hdlcdev_attach - called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) + * @dev: pointer to network device structure + * @encoding: serial encoding setting + * @parity: FCS setting * - * dev pointer to network device structure - * encoding serial encoding setting - * parity FCS setting + * Set encoding and frame check sequence (FCS) options. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, unsigned short parity) @@ -7468,10 +7468,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, } /** - * called by generic HDLC layer to send frame - * - * skb socket buffer containing HDLC frame - * dev pointer to network device structure + * hdlcdev_xmit - called by generic HDLC layer to send a frame + * @skb: socket buffer containing HDLC frame + * @dev: pointer to network device structure */ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) @@ -7509,12 +7508,12 @@ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, } /** - * called by network layer when interface enabled - * claim resources and initialize hardware + * hdlcdev_open - called by network layer when interface enabled + * @dev: pointer to network device structure * - * dev pointer to network device structure + * Claim resources and initialize hardware. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_open(struct net_device *dev) { @@ -7568,12 +7567,12 @@ static int hdlcdev_open(struct net_device *dev) } /** - * called by network layer when interface is disabled - * shutdown hardware and release resources + * hdlcdev_close - called by network layer when interface is disabled + * @dev: pointer to network device structure * - * dev pointer to network device structure + * Shutdown hardware and release resources. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_close(struct net_device *dev) { @@ -7598,13 +7597,12 @@ static int hdlcdev_close(struct net_device *dev) } /** - * called by network layer to process IOCTL call to network device + * hdlcdev_ioctl - called by network layer to process IOCTL call to network device + * @dev: pointer to network device structure + * @ifr: pointer to network interface request structure + * @cmd: IOCTL command code * - * dev pointer to network device structure - * ifr pointer to network interface request structure - * cmd IOCTL command code - * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -7702,9 +7700,9 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } /** - * called by network layer when transmit timeout is detected + * hdlcdev_tx_timeout - called by network layer when transmit timeout is detected * - * dev pointer to network device structure + * @dev: pointer to network device structure */ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue) { @@ -7725,10 +7723,10 @@ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue) } /** - * called by device driver when transmit completes - * reenable network layer transmit if stopped + * hdlcdev_tx_done - called by device driver when transmit completes + * @info: pointer to device instance information * - * info pointer to device instance information + * Reenable network layer transmit if stopped. */ static void hdlcdev_tx_done(struct mgsl_struct *info) { @@ -7737,12 +7735,12 @@ static void hdlcdev_tx_done(struct mgsl_struct *info) } /** - * called by device driver when frame received - * pass frame to network layer + * hdlcdev_rx - called by device driver when frame received + * @info: pointer to device instance information + * @buf: pointer to buffer contianing frame data + * @size: count of data bytes in buf * - * info pointer to device instance information - * buf pointer to buffer contianing frame data - * size count of data bytes in buf + * Pass frame to network layer. */ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size) { @@ -7778,12 +7776,12 @@ static const struct net_device_ops hdlcdev_ops = { }; /** - * called by device driver when adding device instance - * do generic HDLC initialization + * hdlcdev_init - called by device driver when adding device instance + * @info: pointer to device instance information * - * info pointer to device instance information + * Do generic HDLC initialization. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_init(struct mgsl_struct *info) { @@ -7827,10 +7825,10 @@ static int hdlcdev_init(struct mgsl_struct *info) } /** - * called by device driver when removing device instance - * do generic HDLC cleanup + * hdlcdev_exit - called by device driver when removing device instance + * @info: pointer to device instance information * - * info pointer to device instance information + * Do generic HDLC cleanup. */ static void hdlcdev_exit(struct mgsl_struct *info) { diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index b794177ccfb9..917cc611ad25 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -1395,14 +1395,14 @@ static int set_break(struct tty_struct *tty, int break_state) #if SYNCLINK_GENERIC_HDLC /** - * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) - * set encoding and frame check sequence (FCS) options + * hdlcdev_attach - called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) + * @dev: pointer to network device structure + * @encoding: serial encoding setting + * @parity: FCS setting * - * dev pointer to network device structure - * encoding serial encoding setting - * parity FCS setting + * Set encoding and frame check sequence (FCS) options. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, unsigned short parity) @@ -1446,10 +1446,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, } /** - * called by generic HDLC layer to send frame - * - * skb socket buffer containing HDLC frame - * dev pointer to network device structure + * hdlcdev_xmit - called by generic HDLC layer to send a frame + * @skb: socket buffer containing HDLC frame + * @dev: pointer to network device structure */ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) @@ -1483,12 +1482,12 @@ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, } /** - * called by network layer when interface enabled - * claim resources and initialize hardware + * hdlcdev_open - called by network layer when interface enabled + * @dev: pointer to network device structure * - * dev pointer to network device structure + * Claim resources and initialize hardware. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_open(struct net_device *dev) { @@ -1544,12 +1543,12 @@ static int hdlcdev_open(struct net_device *dev) } /** - * called by network layer when interface is disabled - * shutdown hardware and release resources + * hdlcdev_close - called by network layer when interface is disabled + * @dev: pointer to network device structure * - * dev pointer to network device structure + * Shutdown hardware and release resources. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_close(struct net_device *dev) { @@ -1574,13 +1573,12 @@ static int hdlcdev_close(struct net_device *dev) } /** - * called by network layer to process IOCTL call to network device + * hdlcdev_ioctl - called by network layer to process IOCTL call to network device + * @dev: pointer to network device structure + * @ifr: pointer to network interface request structure + * @cmd: IOCTL command code * - * dev pointer to network device structure - * ifr pointer to network interface request structure - * cmd IOCTL command code - * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -1678,9 +1676,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } /** - * called by network layer when transmit timeout is detected - * - * dev pointer to network device structure + * hdlcdev_tx_timeout - called by network layer when transmit timeout is detected + * @dev: pointer to network device structure */ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue) { @@ -1700,10 +1697,10 @@ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue) } /** - * called by device driver when transmit completes - * reenable network layer transmit if stopped + * hdlcdev_tx_done - called by device driver when transmit completes + * @info: pointer to device instance information * - * info pointer to device instance information + * Reenable network layer transmit if stopped. */ static void hdlcdev_tx_done(struct slgt_info *info) { @@ -1712,12 +1709,12 @@ static void hdlcdev_tx_done(struct slgt_info *info) } /** - * called by device driver when frame received - * pass frame to network layer + * hdlcdev_rx - called by device driver when frame received + * @info: pointer to device instance information + * @buf: pointer to buffer contianing frame data + * @size: count of data bytes in buf * - * info pointer to device instance information - * buf pointer to buffer contianing frame data - * size count of data bytes in buf + * Pass frame to network layer. */ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size) { @@ -1751,12 +1748,12 @@ static const struct net_device_ops hdlcdev_ops = { }; /** - * called by device driver when adding device instance - * do generic HDLC initialization + * hdlcdev_init - called by device driver when adding device instance + * @info: pointer to device instance information * - * info pointer to device instance information + * Do generic HDLC initialization. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_init(struct slgt_info *info) { @@ -1800,10 +1797,10 @@ static int hdlcdev_init(struct slgt_info *info) } /** - * called by device driver when removing device instance - * do generic HDLC cleanup + * hdlcdev_exit - called by device driver when removing device instance + * @info: pointer to device instance information * - * info pointer to device instance information + * Do generic HDLC cleanup. */ static void hdlcdev_exit(struct slgt_info *info) { diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 33ff2dbb6650..ce08c5ec331c 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -685,7 +685,7 @@ static inline int sanity_check(SLMP_INFO *info, return 0; } -/** +/* * line discipline callback wrappers * * The wrappers maintain line discipline references @@ -1520,14 +1520,14 @@ static int set_break(struct tty_struct *tty, int break_state) #if SYNCLINK_GENERIC_HDLC /** - * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) - * set encoding and frame check sequence (FCS) options + * hdlcdev_attach - called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) + * @dev: pointer to network device structure + * @encoding: serial encoding setting + * @parity: FCS setting * - * dev pointer to network device structure - * encoding serial encoding setting - * parity FCS setting + * Set encoding and frame check sequence (FCS) options. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, unsigned short parity) @@ -1569,10 +1569,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, } /** - * called by generic HDLC layer to send frame - * - * skb socket buffer containing HDLC frame - * dev pointer to network device structure + * hdlcdev_xmit - called by generic HDLC layer to send frame + * @skb: socket buffer containing HDLC frame + * @dev: pointer to network device structure */ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) @@ -1610,12 +1609,12 @@ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, } /** - * called by network layer when interface enabled - * claim resources and initialize hardware + * hdlcdev_open - called by network layer when interface enabled + * @dev: pointer to network device structure * - * dev pointer to network device structure + * Claim resources and initialize hardware. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_open(struct net_device *dev) { @@ -1669,12 +1668,12 @@ static int hdlcdev_open(struct net_device *dev) } /** - * called by network layer when interface is disabled - * shutdown hardware and release resources + * hdlcdev_close - called by network layer when interface is disabled + * @dev: pointer to network device structure * - * dev pointer to network device structure + * Shutdown hardware and release resources. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_close(struct net_device *dev) { @@ -1699,13 +1698,12 @@ static int hdlcdev_close(struct net_device *dev) } /** - * called by network layer to process IOCTL call to network device + * hdlcdev_ioctl - called by network layer to process IOCTL call to network device + * @dev: pointer to network device structure + * @ifr: pointer to network interface request structure + * @cmd: IOCTL command code * - * dev pointer to network device structure - * ifr pointer to network interface request structure - * cmd IOCTL command code - * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -1803,9 +1801,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } /** - * called by network layer when transmit timeout is detected - * - * dev pointer to network device structure + * hdlcdev_tx_timeout - called by network layer when transmit timeout is detected + * @dev: pointer to network device structure */ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue) { @@ -1826,10 +1823,10 @@ static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue) } /** - * called by device driver when transmit completes - * reenable network layer transmit if stopped + * hdlcdev_tx_done - called by device driver when transmit completes + * @info: pointer to device instance information * - * info pointer to device instance information + * Reenable network layer transmit if stopped. */ static void hdlcdev_tx_done(SLMP_INFO *info) { @@ -1838,12 +1835,12 @@ static void hdlcdev_tx_done(SLMP_INFO *info) } /** - * called by device driver when frame received - * pass frame to network layer + * hdlcdev_rx - called by device driver when frame received + * @info: pointer to device instance information + * @buf: pointer to buffer contianing frame data + * @size: count of data bytes in buf * - * info pointer to device instance information - * buf pointer to buffer contianing frame data - * size count of data bytes in buf + * Pass frame to network layer. */ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size) { @@ -1879,12 +1876,12 @@ static const struct net_device_ops hdlcdev_ops = { }; /** - * called by device driver when adding device instance - * do generic HDLC initialization + * hdlcdev_init - called by device driver when adding device instance + * @info: pointer to device instance information * - * info pointer to device instance information + * Do generic HDLC initialization. * - * returns 0 if success, otherwise error code + * Return: 0 if success, otherwise error code */ static int hdlcdev_init(SLMP_INFO *info) { @@ -1928,10 +1925,10 @@ static int hdlcdev_init(SLMP_INFO *info) } /** - * called by device driver when removing device instance - * do generic HDLC cleanup + * hdlcdev_exit - called by device driver when removing device instance + * @info: pointer to device instance information * - * info pointer to device instance information + * Do generic HDLC cleanup. */ static void hdlcdev_exit(SLMP_INFO *info) { From 145f5646be67eb5613d9606c5cb5139bb00df8b9 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 18 Aug 2020 10:56:55 +0200 Subject: [PATCH 28/79] tty: serial, fix kernel-doc As in the previous patches, fix kernel-doc in serial drivers. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20200818085655.12071-8-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 7 +++---- drivers/tty/serial/men_z135_uart.c | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 37d5b8516880..21d519c804cb 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -257,7 +257,7 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev) /** * ifx_spi_timeout - SPI timeout - * @arg: our SPI device + * @t: timer in our SPI device * * The SPI has timed out: hang up the tty. Users will then see a hangup * and error events. @@ -277,7 +277,6 @@ static void ifx_spi_timeout(struct timer_list *t) /** * ifx_spi_tiocmget - get modem lines * @tty: our tty device - * @filp: file handle issuing the request * * Map the signal state into Linux modem flags and report the value * in Linux terms @@ -531,7 +530,7 @@ static int ifx_spi_chars_in_buffer(struct tty_struct *tty) /** * ifx_port_hangup - * @port: our tty port + * @tty: our tty * * tty port hang up. Called when tty_hangup processing is invoked either * by loss of carrier, or by software (eg vhangup). Serialized against @@ -611,7 +610,7 @@ static const struct tty_operations ifx_spi_serial_ops = { /** * ifx_spi_insert_fip_string - queue received data - * @ifx_ser: our SPI device + * @ifx_dev: our SPI device * @chars: buffer we have received * @size: number of chars reeived * diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index 4f53a4caabf6..9acae5f8fc32 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -173,7 +173,7 @@ static void men_z135_reg_clr(struct men_z135_port *uart, /** * men_z135_handle_modem_status() - Handle change of modem status - * @port: The UART port + * @uart: The UART port * * Handle change of modem status register. This is done by reading the "delta" * versions of DCD (Data Carrier Detect) and CTS (Clear To Send). @@ -236,7 +236,7 @@ static u16 get_rx_fifo_content(struct men_z135_port *uart) /** * men_z135_handle_rx() - RX tasklet routine - * @arg: Pointer to struct men_z135_port + * @uart: Pointer to struct men_z135_port * * Copy from RX FIFO and acknowledge number of bytes copied. */ @@ -287,7 +287,7 @@ static void men_z135_handle_rx(struct men_z135_port *uart) /** * men_z135_handle_tx() - TX tasklet routine - * @arg: Pointer to struct men_z135_port + * @uart: Pointer to struct men_z135_port * */ static void men_z135_handle_tx(struct men_z135_port *uart) @@ -596,7 +596,7 @@ static void men_z135_stop_rx(struct uart_port *port) /** * men_z135_enable_ms() - Enable Modem Status - * port: + * @port: the port * * Enable Modem Status IRQ. */ From 465ddff7e4867fcb65e27fa7ff4d0bb0999e4500 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 4 Aug 2020 16:48:07 +0300 Subject: [PATCH 29/79] serial: sa1100: use platform_get_resource() Use platform_get_resource() to fetch the memory resource instead of open-coded variant. While here, fail the probe if no resource found or no port is added. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20200804134807.11589-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sa1100.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 75c2a22895f9..f5fab1dd96bc 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -879,22 +879,20 @@ static int sa1100_serial_add_one_port(struct sa1100_port *sport, struct platform static int sa1100_serial_probe(struct platform_device *dev) { - struct resource *res = dev->resource; + struct resource *res; int i; - for (i = 0; i < dev->num_resources; i++, res++) - if (res->flags & IORESOURCE_MEM) - break; + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; - if (i < dev->num_resources) { - for (i = 0; i < NR_PORTS; i++) { - if (sa1100_ports[i].port.mapbase != res->start) - continue; - - sa1100_serial_add_one_port(&sa1100_ports[i], dev); + for (i = 0; i < NR_PORTS; i++) + if (sa1100_ports[i].port.mapbase == res->start) break; - } - } + if (i == NR_PORTS) + return -ENODEV; + + sa1100_serial_add_one_port(&sa1100_ports[i], dev); return 0; } From a7de3bcb330bfef8db1d4027da8eb3616ae20fe4 Mon Sep 17 00:00:00 2001 From: Seiya Wang Date: Fri, 14 Aug 2020 14:04:53 +0800 Subject: [PATCH 30/79] dt-bindings: serial: Add compatible for Mediatek MT8192 This commit adds dt-binding documentation of uart for Mediatek MT8192 SoC Platform. Acked-by: Rob Herring Signed-off-by: Seiya Wang Link: https://lore.kernel.org/r/20200814060454.32200-3-seiya.wang@mediatek.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt index 3a3b57079f0d..647b5aee86f3 100644 --- a/Documentation/devicetree/bindings/serial/mtk-uart.txt +++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt @@ -19,6 +19,7 @@ Required properties: * "mediatek,mt8135-uart" for MT8135 compatible UARTS * "mediatek,mt8173-uart" for MT8173 compatible UARTS * "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS + * "mediatek,mt8192-uart", "mediatek,mt6577-uart" for MT8192 compatible UARTS * "mediatek,mt8516-uart" for MT8516 compatible UARTS * "mediatek,mt6577-uart" for MT6577 and all of the above From 377c0d7ea5bb93251e71559c115d2f94650c00d6 Mon Sep 17 00:00:00 2001 From: Seiya Wang Date: Fri, 14 Aug 2020 14:04:54 +0800 Subject: [PATCH 31/79] dt-bindings: timer: Add compatible for Mediatek MT8192 This commit adds dt-binding documentation of timer for Mediatek MT8192 SoC Platform. Acked-by: Rob Herring Signed-off-by: Seiya Wang Link: https://lore.kernel.org/r/20200814060454.32200-4-seiya.wang@mediatek.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt index 0d256486f886..690a9c0966ac 100644 --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt @@ -22,6 +22,7 @@ Required properties: For those SoCs that use SYST * "mediatek,mt8183-timer" for MT8183 compatible timers (SYST) + * "mediatek,mt8192-timer" for MT8192 compatible timers (SYST) * "mediatek,mt7629-timer" for MT7629 compatible timers (SYST) * "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST) From 52c3c3a59234a9725b5dcfe9729ed737d7843980 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 24 Aug 2020 11:54:25 +0200 Subject: [PATCH 32/79] Revert "vc_screen: extract vcs_read_buf_header" This reverts commit b1c32fcfadf5593ab7a63261cc8a5747c36e627e, because Syzkaller reports a use-after-free, a write in vcs_read: BUG: KASAN: use-after-free in vcs_read_buf drivers/tty/vt/vc_screen.c:357 [inline] BUG: KASAN: use-after-free in vcs_read+0xaa7/0xb40 drivers/tty/vt/vc_screen.c:449 Write of size 2 at addr ffff8880a8014000 by task syz-executor.5/16936 CPU: 1 PID: 16936 Comm: syz-executor.5 Not tainted 5.9.0-rc1-next-20200820-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: ... kasan_report.cold+0x1f/0x37 mm/kasan/report.c:530 vcs_read_buf drivers/tty/vt/vc_screen.c:357 [inline] vcs_read+0xaa7/0xb40 drivers/tty/vt/vc_screen.c:449 There are two issues with the patch: 1) vcs_read rounds the 'count' *up* to an even number. So if we read odd bytes from the header (3 bytes in the reproducer), the second byte of a (2-byte/ushort) write to temporary con_buf won't fit. It is because with the patch applied, we only subtract the real number read (3 bytes) and not the whole header (4 bytes). 2) in this scenario, we perform unaligned accesses now: there are 2-byte/ushort writes to odd addresses. Due to the same reason as above. Revert this for now, re-think and retry later. Signed-off-by: Jiri Slaby Reported-by: syzbot+ad1f53726c3bd11180cb@syzkaller.appspotmail.com Fixes: b1c32fcfadf5 ("vc_screen: extract vcs_read_buf_header") Cc: akpm@linux-foundation.org Cc: nico@fluxnic.net Link: https://lore.kernel.org/r/20200824095425.4376-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 3e3a6a9a7f44..1850bacdb5b0 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -293,22 +293,6 @@ static void vcs_read_buf_noattr(const struct vc_data *vc, char *con_buf, } } -static unsigned int vcs_read_buf_header(const struct vc_data *vc, char *con_buf, - unsigned int pos, unsigned int count) -{ - count = min(HEADER_SIZE - pos, count); - - /* clamp header values if they don't fit */ - con_buf[0] = min(vc->vc_rows, 0xFFu); - con_buf[1] = min(vc->vc_cols, 0xFFu); - getconsxy(vc, con_buf + 2); - - if (pos) - memmove(con_buf, con_buf + pos, count); - - return count; -} - static unsigned int vcs_read_buf(const struct vc_data *vc, char *con_buf, unsigned int pos, unsigned int count, bool viewed, unsigned int *skip) @@ -318,11 +302,22 @@ static unsigned int vcs_read_buf(const struct vc_data *vc, char *con_buf, unsigned int filled = count; if (pos < HEADER_SIZE) { - count -= vcs_read_buf_header(vc, con_buf, pos, count); + /* clamp header values if they don't fit */ + con_buf[0] = min(vc->vc_rows, 0xFFu); + con_buf[1] = min(vc->vc_cols, 0xFFu); + getconsxy(vc, con_buf + 2); + *skip += pos; + count += pos; + if (count > CON_BUF_SIZE) { + count = CON_BUF_SIZE; + filled = count - pos; + } + + /* Advance state pointers and move on. */ + count -= min(HEADER_SIZE, count); pos = HEADER_SIZE; con_buf += HEADER_SIZE; - /* If count >= 0, then pos is even... */ } else if (pos & 1) { /* From c9fe14ac8bd6c329d84e1f88c1b89cb1d5fb982a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 18 Aug 2020 19:44:57 -0300 Subject: [PATCH 33/79] serial: fsl_lpuart: Fix typo in "transfer" Fix two occurrences where "transfer" is spelled incorrectly. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20200818224457.16507-1-festevam@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 7ca642249224..5a5a22d77841 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1260,7 +1260,7 @@ static int lpuart_config_rs485(struct uart_port *port, modem |= UARTMODEM_TXRTSE; /* - * RTS needs to be logic HIGH either during transer _or_ after + * RTS needs to be logic HIGH either during transfer _or_ after * transfer, other variants are not supported by the hardware. */ @@ -1311,7 +1311,7 @@ static int lpuart32_config_rs485(struct uart_port *port, modem |= UARTMODEM_TXRTSE; /* - * RTS needs to be logic HIGH either during transer _or_ after + * RTS needs to be logic HIGH either during transfer _or_ after * transfer, other variants are not supported by the hardware. */ From 9cfbf7a6416b5fa2b88ac337d092be82778a0469 Mon Sep 17 00:00:00 2001 From: Alex Dewar Date: Mon, 24 Aug 2020 23:39:33 +0100 Subject: [PATCH 34/79] serial: core: don't use snprintf() for formatting sysfs attrs As per the documentation (Documentation/filesystems/sysfs.rst), snprintf() should not be used for formatting values returned by sysfs. For all of the instances in serial_core.c, we know that the string will be Link: https://lore.kernel.org/r/20200824223932.27709-1-alex.dewar90@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 3403dd790517..b303a9a44a4e 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2637,7 +2637,7 @@ static ssize_t uartclk_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.baud_base * 16); + return sprintf(buf, "%d\n", tmp.baud_base * 16); } static ssize_t type_show(struct device *dev, @@ -2647,7 +2647,7 @@ static ssize_t type_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.type); + return sprintf(buf, "%d\n", tmp.type); } static ssize_t line_show(struct device *dev, @@ -2657,7 +2657,7 @@ static ssize_t line_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.line); + return sprintf(buf, "%d\n", tmp.line); } static ssize_t port_show(struct device *dev, @@ -2671,7 +2671,7 @@ static ssize_t port_show(struct device *dev, ioaddr = tmp.port; if (HIGH_BITS_OFFSET) ioaddr |= (unsigned long)tmp.port_high << HIGH_BITS_OFFSET; - return snprintf(buf, PAGE_SIZE, "0x%lX\n", ioaddr); + return sprintf(buf, "0x%lX\n", ioaddr); } static ssize_t irq_show(struct device *dev, @@ -2681,7 +2681,7 @@ static ssize_t irq_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.irq); + return sprintf(buf, "%d\n", tmp.irq); } static ssize_t flags_show(struct device *dev, @@ -2691,7 +2691,7 @@ static ssize_t flags_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "0x%X\n", tmp.flags); + return sprintf(buf, "0x%X\n", tmp.flags); } static ssize_t xmit_fifo_size_show(struct device *dev, @@ -2701,7 +2701,7 @@ static ssize_t xmit_fifo_size_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.xmit_fifo_size); + return sprintf(buf, "%d\n", tmp.xmit_fifo_size); } static ssize_t close_delay_show(struct device *dev, @@ -2711,7 +2711,7 @@ static ssize_t close_delay_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.close_delay); + return sprintf(buf, "%d\n", tmp.close_delay); } static ssize_t closing_wait_show(struct device *dev, @@ -2721,7 +2721,7 @@ static ssize_t closing_wait_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.closing_wait); + return sprintf(buf, "%d\n", tmp.closing_wait); } static ssize_t custom_divisor_show(struct device *dev, @@ -2731,7 +2731,7 @@ static ssize_t custom_divisor_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.custom_divisor); + return sprintf(buf, "%d\n", tmp.custom_divisor); } static ssize_t io_type_show(struct device *dev, @@ -2741,7 +2741,7 @@ static ssize_t io_type_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.io_type); + return sprintf(buf, "%d\n", tmp.io_type); } static ssize_t iomem_base_show(struct device *dev, @@ -2751,7 +2751,7 @@ static ssize_t iomem_base_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)tmp.iomem_base); + return sprintf(buf, "0x%lX\n", (unsigned long)tmp.iomem_base); } static ssize_t iomem_reg_shift_show(struct device *dev, @@ -2761,7 +2761,7 @@ static ssize_t iomem_reg_shift_show(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift); + return sprintf(buf, "%d\n", tmp.iomem_reg_shift); } static ssize_t console_show(struct device *dev, From c7ac46dac744455047438de7acc63e1236536a83 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 28 Aug 2020 11:37:52 +0530 Subject: [PATCH 35/79] tty: serial: qcom_geni_serial: Unconditionally call dev_pm_opp_of_remove_table() dev_pm_opp_of_remove_table() doesn't report any errors when it fails to find the OPP table with error -ENODEV (i.e. OPP table not present for the device). And we can call dev_pm_opp_of_remove_table() unconditionally here. While at it, create a new label to put clkname on errors. Signed-off-by: Viresh Kumar Link: https://lore.kernel.org/r/583003f385a103b4c089ce8144a215c58cfb117a.1598594714.git.viresh.kumar@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 3aa29d201f54..33f1af6c61d1 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1433,11 +1433,9 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) return PTR_ERR(port->se.opp_table); /* OPP table is optional */ ret = dev_pm_opp_of_add_table(&pdev->dev); - if (!ret) { - port->se.has_opp_table = true; - } else if (ret != -ENODEV) { + if (ret && ret != -ENODEV) { dev_err(&pdev->dev, "invalid OPP table in device tree\n"); - return ret; + goto put_clkname; } port->private_data.drv = drv; @@ -1478,8 +1476,8 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) return 0; err: - if (port->se.has_opp_table) - dev_pm_opp_of_remove_table(&pdev->dev); + dev_pm_opp_of_remove_table(&pdev->dev); +put_clkname: dev_pm_opp_put_clkname(port->se.opp_table); return ret; } @@ -1489,8 +1487,7 @@ static int qcom_geni_serial_remove(struct platform_device *pdev) struct qcom_geni_serial_port *port = platform_get_drvdata(pdev); struct uart_driver *drv = port->private_data.drv; - if (port->se.has_opp_table) - dev_pm_opp_of_remove_table(&pdev->dev); + dev_pm_opp_of_remove_table(&pdev->dev); dev_pm_opp_put_clkname(port->se.opp_table); dev_pm_clear_wake_irq(&pdev->dev); device_init_wakeup(&pdev->dev, false); From 04b6ff5f25dece9b0ee244aa768b251cfe855c85 Mon Sep 17 00:00:00 2001 From: Du Huanpeng Date: Sat, 22 Aug 2020 09:47:28 +0800 Subject: [PATCH 36/79] serial: 8250_pci: Add WCH384_8S 8 port serial device Add PCI id for WCH384_8S 8 port PCI-E serial card. because this card has so many ports, you may have to check these two options before use it: CONFIG_SERIAL_8250_RUNTIME_UARTS CONFIG_SERIAL_8250_NR_UARTS Signed-off-by: Du Huanpeng Link: https://lore.kernel.org/r/1598060848-27807-1-git-send-email-u74147@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 56 ++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 1a74d511b02a..d8f43f23b5b0 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1776,6 +1776,39 @@ pci_wch_ch38x_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } + +#define CH384_XINT_ENABLE_REG 0xEB +#define CH384_XINT_ENABLE_BIT 0x02 + +static int pci_wch_ch38x_init(struct pci_dev *dev) +{ + int max_port; + unsigned long iobase; + + + switch (dev->device) { + case 0x3853: /* 8 ports */ + max_port = 8; + break; + default: + return -EINVAL; + } + + iobase = pci_resource_start(dev, 0); + outb(CH384_XINT_ENABLE_BIT, iobase + CH384_XINT_ENABLE_REG); + + return max_port; +} + +static void pci_wch_ch38x_exit(struct pci_dev *dev) +{ + unsigned long iobase; + + iobase = pci_resource_start(dev, 0); + outb(0x0, iobase + CH384_XINT_ENABLE_REG); +} + + static int pci_sunix_setup(struct serial_private *priv, const struct pciserial_board *board, @@ -1867,6 +1900,7 @@ pci_moxa_setup(struct serial_private *priv, #define PCIE_VENDOR_ID_WCH 0x1c00 #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 #define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 +#define PCIE_DEVICE_ID_WCH_CH384_8S 0x3853 #define PCIE_DEVICE_ID_WCH_CH382_2S 0x3253 #define PCI_VENDOR_ID_ACCESIO 0x494f @@ -2642,6 +2676,16 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_wch_ch38x_setup, }, + /* WCH CH384 8S card (16850 clone) */ + { + .vendor = PCIE_VENDOR_ID_WCH, + .device = PCIE_DEVICE_ID_WCH_CH384_8S, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_wch_ch38x_init, + .exit = pci_wch_ch38x_exit, + .setup = pci_wch_ch38x_setup, + }, /* * ASIX devices with FIFO bug */ @@ -2913,6 +2957,7 @@ enum pci_board_num_t { pbn_fintek_F81512A, pbn_wch382_2, pbn_wch384_4, + pbn_wch384_8, pbn_pericom_PI7C9X7951, pbn_pericom_PI7C9X7952, pbn_pericom_PI7C9X7954, @@ -3650,6 +3695,13 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 8, .first_offset = 0xC0, }, + [pbn_wch384_8] = { + .flags = FL_BASE0, + .num_ports = 8, + .base_baud = 115200, + .uart_offset = 8, + .first_offset = 0x00, + }, /* * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART */ @@ -5566,6 +5618,10 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_wch384_4 }, + { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_8S, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, pbn_wch384_8 }, + /* Fintek PCI serial cards */ { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 }, { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 }, From 5f0e708c8d74049f524e7407b523cce4330b090f Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Thu, 3 Sep 2020 14:24:01 +0800 Subject: [PATCH 37/79] serial: imx: Delete duplicated argument to '|' in imx_uart_probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When calculate "ucr1" UCR1_TRDYEN is duplicate. Signed-off-by: Ye Bin Reviewed-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20200903062401.692442-1-yebin10@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index ce8c472cf385..4e6ead1f650e 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -2389,8 +2389,7 @@ static int imx_uart_probe(struct platform_device *pdev) /* Disable interrupts before requesting them */ ucr1 = imx_uart_readl(sport, UCR1); - ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | - UCR1_TRDYEN | UCR1_RTSDEN); + ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | UCR1_RTSDEN); imx_uart_writel(sport, ucr1, UCR1); if (!imx_uart_is_imx1(sport) && sport->dte_mode) { From ea43a60b15486bca1c406b59034e3561d543d571 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 1 Sep 2020 17:30:59 +0200 Subject: [PATCH 38/79] serial: 8250: Simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and the error value gets printed. Signed-off-by: Krzysztof Kozlowski Acked-by: Florian Fainelli Reviewed-by: Lukas Wunner Link: https://lore.kernel.org/r/20200901153100.18827-1-krzk@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_bcm2835aux.c | 12 +++--------- drivers/tty/serial/8250/8250_ingenic.c | 20 ++++++-------------- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c index 12d03e678295..fd95860cd661 100644 --- a/drivers/tty/serial/8250/8250_bcm2835aux.c +++ b/drivers/tty/serial/8250/8250_bcm2835aux.c @@ -110,12 +110,8 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev) /* get the clock - this also enables the HW */ data->clk = devm_clk_get(&pdev->dev, NULL); - ret = PTR_ERR_OR_ZERO(data->clk); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "could not get clk: %d\n", ret); - return ret; - } + if (IS_ERR(data->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(data->clk), "could not get clk\n"); /* get the interrupt */ ret = platform_get_irq(pdev, 0); @@ -155,9 +151,7 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev) /* register the port */ ret = serial8250_register_8250_port(&up); if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, - "unable to register 8250 port - %d\n", ret); + dev_err_probe(&pdev->dev, ret, "unable to register 8250 port\n"); goto dis_clk; } data->line = ret; diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index dde766fa465f..988bf6bcce42 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -259,22 +259,14 @@ static int ingenic_uart_probe(struct platform_device *pdev) return -ENOMEM; data->clk_module = devm_clk_get(&pdev->dev, "module"); - if (IS_ERR(data->clk_module)) { - err = PTR_ERR(data->clk_module); - if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, - "unable to get module clock: %d\n", err); - return err; - } + if (IS_ERR(data->clk_module)) + return dev_err_probe(&pdev->dev, PTR_ERR(data->clk_module), + "unable to get module clock\n"); data->clk_baud = devm_clk_get(&pdev->dev, "baud"); - if (IS_ERR(data->clk_baud)) { - err = PTR_ERR(data->clk_baud); - if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, - "unable to get baud clock: %d\n", err); - return err; - } + if (IS_ERR(data->clk_baud)) + return dev_err_probe(&pdev->dev, PTR_ERR(data->clk_baud), + "unable to get baud clock\n"); err = clk_prepare_enable(data->clk_module); if (err) { From 89c65d664832ebaf2cbdcfe83b25c0036780feb7 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 1 Sep 2020 17:31:00 +0200 Subject: [PATCH 39/79] serial: core: Simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and the error value gets printed. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Lukas Wunner Link: https://lore.kernel.org/r/20200901153100.18827-2-krzk@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 4d313385cb2a..6ea13d35d5fc 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3264,9 +3264,7 @@ int uart_get_rs485_mode(struct uart_port *port) if (IS_ERR(port->rs485_term_gpio)) { ret = PTR_ERR(port->rs485_term_gpio); port->rs485_term_gpio = NULL; - if (ret != -EPROBE_DEFER) - dev_err(dev, "Cannot get rs485-term-gpios\n"); - return ret; + return dev_err_probe(dev, ret, "Cannot get rs485-term-gpios\n"); } return 0; From 5da6b1c079e6804a81e63ab8337224cbd2148c91 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 1 Sep 2020 14:03:29 +0200 Subject: [PATCH 40/79] sc16is7xx: Set iobase to device index Some derivates of sc16is7xx devices expose more than one tty device to userspace. If multiple such devices exist in a system, userspace currently has no clean way to infer which tty maps to which physical line. Set the .iobase value to the relative index within the device to allow infering the order through sysfs. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20200901120329.4176302-1-daniel@zonque.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 809610b37c71..f86ec2d2635b 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1271,6 +1271,7 @@ static int sc16is7xx_probe(struct device *dev, s->p[i].port.type = PORT_SC16IS7XX; s->p[i].port.fifosize = SC16IS7XX_FIFO_SIZE; s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; + s->p[i].port.iobase = i; s->p[i].port.iotype = UPIO_PORT; s->p[i].port.uartclk = freq; s->p[i].port.rs485_config = sc16is7xx_config_rs485; From 0fb9342d06b0f667b915ba58bfefc030e534a218 Mon Sep 17 00:00:00 2001 From: Tong Zhang Date: Fri, 28 Aug 2020 08:39:50 -0400 Subject: [PATCH 41/79] tty: serial: earlycon dependency parse_options() in drivers/tty/serial/earlycon.c calls uart_parse_earlycon in drivers/tty/serial/serial_core.c therefore selecting SERIAL_EARLYCON should automatically select SERIAL_CORE, otherwise will result in symbol not found error during linking if SERIAL_CORE is not configured as builtin Fixes: 9aac5887595b ("tty/serial: add generic serial earlycon") Signed-off-by: Tong Zhang Link: https://lore.kernel.org/r/20200828123949.2642-1-ztong0001@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 9409be982aa6..54586c1aba60 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -8,6 +8,7 @@ menu "Serial drivers" config SERIAL_EARLYCON bool + depends on SERIAL_CORE help Support for early consoles with the earlycon parameter. This enables the console before standard serial driver is probed. The console is From ad0c2748059fff13e8295ae91f51073d6c0311b7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 31 Aug 2020 19:10:45 +0200 Subject: [PATCH 42/79] serial: stm32: Add RS485 RTS GPIO control again While the STM32 does support RS485 drive-enable control within the UART IP itself, some systems have the drive-enable line connected to a pin which cannot be pinmuxed as RTS. Add support for toggling the RTS GPIO line using the modem control GPIOs to provide at least some sort of emulation. Fixes: 7df5081cbf5e ("serial: stm32: Add RS485 RTS GPIO control") Signed-off-by: Marek Vasut Cc: Alexandre Torgue Cc: Andy Shevchenko Cc: Manivannan Sadhasivam Cc: Fabrice Gasnier Cc: linux-stm32@st-md-mailman.stormreply.com Link: https://lore.kernel.org/r/20200831171045.205691-1-marex@denx.de Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 33 ++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index ba503dd04ce2..ee6c7762d355 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -129,13 +129,9 @@ static int stm32_config_rs485(struct uart_port *port, if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { cr3 &= ~USART_CR3_DEP; rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND; - mctrl_gpio_set(stm32_port->gpios, - stm32_port->port.mctrl & ~TIOCM_RTS); } else { cr3 |= USART_CR3_DEP; rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; - mctrl_gpio_set(stm32_port->gpios, - stm32_port->port.mctrl | TIOCM_RTS); } writel_relaxed(cr3, port->membase + ofs->cr3); @@ -541,17 +537,42 @@ static void stm32_disable_ms(struct uart_port *port) /* Transmit stop */ static void stm32_stop_tx(struct uart_port *port) { + struct stm32_port *stm32_port = to_stm32_port(port); + struct serial_rs485 *rs485conf = &port->rs485; + stm32_tx_interrupt_disable(port); + + if (rs485conf->flags & SER_RS485_ENABLED) { + if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { + mctrl_gpio_set(stm32_port->gpios, + stm32_port->port.mctrl & ~TIOCM_RTS); + } else { + mctrl_gpio_set(stm32_port->gpios, + stm32_port->port.mctrl | TIOCM_RTS); + } + } } /* There are probably characters waiting to be transmitted. */ static void stm32_start_tx(struct uart_port *port) { + struct stm32_port *stm32_port = to_stm32_port(port); + struct serial_rs485 *rs485conf = &port->rs485; struct circ_buf *xmit = &port->state->xmit; if (uart_circ_empty(xmit)) return; + if (rs485conf->flags & SER_RS485_ENABLED) { + if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { + mctrl_gpio_set(stm32_port->gpios, + stm32_port->port.mctrl | TIOCM_RTS); + } else { + mctrl_gpio_set(stm32_port->gpios, + stm32_port->port.mctrl & ~TIOCM_RTS); + } + } + stm32_transmit_chars(port); } @@ -851,13 +872,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { cr3 &= ~USART_CR3_DEP; rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND; - mctrl_gpio_set(stm32_port->gpios, - stm32_port->port.mctrl & ~TIOCM_RTS); } else { cr3 |= USART_CR3_DEP; rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; - mctrl_gpio_set(stm32_port->gpios, - stm32_port->port.mctrl | TIOCM_RTS); } } else { From 11361610b00500c4afe269ff5a4fe06d58f0a3d0 Mon Sep 17 00:00:00 2001 From: kuldip dwivedi Date: Thu, 3 Sep 2020 17:04:02 +0530 Subject: [PATCH 43/79] serial: 8250_fsl: Add ACPI support This adds support for ACPI enumerated FSL 16550 UARTs. For supporting ACPI, I added a wrapper so that this driver can be used if firmware has exposed the HID "NXP0018" in DSDT table. This will be built as object file if config "SERIAL_8250_FSL" is enabled which depends on config "SERIAL_8250_CONSOLE". Signed-off-by: kuldip dwivedi Link: https://lore.kernel.org/r/20200903113402.12371-1-kuldip.dwivedi@puresoftware.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_fsl.c | 108 +++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index 0d0c80905c58..c3582d8938d6 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -1,15 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 -#include -#include - -#include "8250.h" - /* * Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker. + * Copyright 2020 NXP + * Copyright 2020 Puresoftware Ltd. * * This isn't a full driver; it just provides an alternate IRQ - * handler to deal with an errata. Everything else is just - * using the bog standard 8250 support. + * handler to deal with an errata and provide ACPI wrapper. + * Everything else is just using the bog standard 8250 support. * * We follow code flow of serial8250_default_handle_irq() but add * a check for a break and insert a dummy read on the Rx for the @@ -20,6 +17,16 @@ * IRQ event to the next one. */ +#include +#include +#include + +#include "8250.h" + +struct fsl8250_data { + int line; +}; + int fsl8250_handle_irq(struct uart_port *port) { unsigned char lsr, orig_lsr; @@ -79,3 +86,90 @@ int fsl8250_handle_irq(struct uart_port *port) return 1; } EXPORT_SYMBOL_GPL(fsl8250_handle_irq); + +#ifdef CONFIG_ACPI +static int fsl8250_acpi_probe(struct platform_device *pdev) +{ + struct fsl8250_data *data; + struct uart_8250_port port8250; + struct device *dev = &pdev->dev; + struct resource *regs; + + int ret, irq; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(dev, "no registers defined\n"); + return -EINVAL; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + if (irq != -EPROBE_DEFER) + dev_err(dev, "cannot get irq\n"); + return irq; + } + + memset(&port8250, 0, sizeof(port8250)); + + ret = device_property_read_u32(dev, "clock-frequency", + &port8250.port.uartclk); + if (ret) + return ret; + + spin_lock_init(&port8250.port.lock); + + port8250.port.mapbase = regs->start; + port8250.port.irq = irq; + port8250.port.handle_irq = fsl8250_handle_irq; + port8250.port.type = PORT_16550A; + port8250.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF + | UPF_FIXED_PORT | UPF_IOREMAP + | UPF_FIXED_TYPE; + port8250.port.dev = dev; + port8250.port.mapsize = resource_size(regs); + port8250.port.iotype = UPIO_MEM; + port8250.port.irqflags = IRQF_SHARED; + + port8250.port.membase = devm_ioremap(dev, port8250.port.mapbase, + port8250.port.mapsize); + if (!port8250.port.membase) + return -ENOMEM; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->line = serial8250_register_8250_port(&port8250); + if (data->line < 0) + return data->line; + + platform_set_drvdata(pdev, data); + return 0; +} + +static int fsl8250_acpi_remove(struct platform_device *pdev) +{ + struct fsl8250_data *data = platform_get_drvdata(pdev); + + serial8250_unregister_port(data->line); + return 0; +} + +static const struct acpi_device_id fsl_8250_acpi_id[] = { + { "NXP0018", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, fsl_8250_acpi_id); + +static struct platform_driver fsl8250_platform_driver = { + .driver = { + .name = "fsl-16550-uart", + .acpi_match_table = ACPI_PTR(fsl_8250_acpi_id), + }, + .probe = fsl8250_acpi_probe, + .remove = fsl8250_acpi_remove, +}; + +module_platform_driver(fsl8250_platform_driver); +#endif From c3647f2f30c875830fe972141a96b75a0b8df1a6 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 6 Aug 2020 08:05:07 +0200 Subject: [PATCH 44/79] tty: serial: icom: switch from 'pci_' to 'dma_' API The wrappers in include/linux/pci-dma-compat.h should go away. The patch has been generated with the coccinelle script below and has been hand modified to replace GFP_ with a correct flag. It has been compile tested. When memory is allocated in 'get_port_memory()', GFP_KERNEL can be used because it is only called from a probe function and no lock is acquired. The call chain is: icom_probe (the probe function) --> icom_load_ports --> get_port_memory When memory is allocated in 'load_code()', GFP_KERNEL can be used because it is only called from a .startup function. icom_open (the .startup function of struct uart_ops) --> startup --> load_code .startup functions are protected using a semaphore and no spinlock is taken. @@ @@ - PCI_DMA_BIDIRECTIONAL + DMA_BIDIRECTIONAL @@ @@ - PCI_DMA_TODEVICE + DMA_TO_DEVICE @@ @@ - PCI_DMA_FROMDEVICE + DMA_FROM_DEVICE @@ @@ - PCI_DMA_NONE + DMA_NONE @@ expression e1, e2, e3; @@ - pci_alloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3; @@ - pci_zalloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3, e4; @@ - pci_free_consistent(e1, e2, e3, e4) + dma_free_coherent(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_single(e1, e2, e3, e4) + dma_map_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_single(e1, e2, e3, e4) + dma_unmap_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4, e5; @@ - pci_map_page(e1, e2, e3, e4, e5) + dma_map_page(&e1->dev, e2, e3, e4, e5) @@ expression e1, e2, e3, e4; @@ - pci_unmap_page(e1, e2, e3, e4) + dma_unmap_page(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_sg(e1, e2, e3, e4) + dma_map_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_sg(e1, e2, e3, e4) + dma_unmap_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_cpu(e1, e2, e3, e4) + dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_device(e1, e2, e3, e4) + dma_sync_single_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) + dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_device(e1, e2, e3, e4) + dma_sync_sg_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2; @@ - pci_dma_mapping_error(e1, e2) + dma_mapping_error(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_dma_mask(e1, e2) + dma_set_mask(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_consistent_dma_mask(e1, e2) + dma_set_coherent_mask(&e1->dev, e2) Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/20200806060507.730142-1-christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/icom.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 624f3d541c68..94c8281ddb5f 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -138,24 +138,24 @@ static void free_port_memory(struct icom_port *icom_port) trace(icom_port, "RET_PORT_MEM", 0); if (icom_port->recv_buf) { - pci_free_consistent(dev, 4096, icom_port->recv_buf, - icom_port->recv_buf_pci); + dma_free_coherent(&dev->dev, 4096, icom_port->recv_buf, + icom_port->recv_buf_pci); icom_port->recv_buf = NULL; } if (icom_port->xmit_buf) { - pci_free_consistent(dev, 4096, icom_port->xmit_buf, - icom_port->xmit_buf_pci); + dma_free_coherent(&dev->dev, 4096, icom_port->xmit_buf, + icom_port->xmit_buf_pci); icom_port->xmit_buf = NULL; } if (icom_port->statStg) { - pci_free_consistent(dev, 4096, icom_port->statStg, - icom_port->statStg_pci); + dma_free_coherent(&dev->dev, 4096, icom_port->statStg, + icom_port->statStg_pci); icom_port->statStg = NULL; } if (icom_port->xmitRestart) { - pci_free_consistent(dev, 4096, icom_port->xmitRestart, - icom_port->xmitRestart_pci); + dma_free_coherent(&dev->dev, 4096, icom_port->xmitRestart, + icom_port->xmitRestart_pci); icom_port->xmitRestart = NULL; } } @@ -169,7 +169,8 @@ static int get_port_memory(struct icom_port *icom_port) struct pci_dev *dev = icom_port->adapter->pci_dev; icom_port->xmit_buf = - pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci); + dma_alloc_coherent(&dev->dev, 4096, &icom_port->xmit_buf_pci, + GFP_KERNEL); if (!icom_port->xmit_buf) { dev_err(&dev->dev, "Can not allocate Transmit buffer\n"); return -ENOMEM; @@ -179,7 +180,8 @@ static int get_port_memory(struct icom_port *icom_port) (unsigned long) icom_port->xmit_buf); icom_port->recv_buf = - pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci); + dma_alloc_coherent(&dev->dev, 4096, &icom_port->recv_buf_pci, + GFP_KERNEL); if (!icom_port->recv_buf) { dev_err(&dev->dev, "Can not allocate Receive buffer\n"); free_port_memory(icom_port); @@ -189,7 +191,8 @@ static int get_port_memory(struct icom_port *icom_port) (unsigned long) icom_port->recv_buf); icom_port->statStg = - pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci); + dma_alloc_coherent(&dev->dev, 4096, &icom_port->statStg_pci, + GFP_KERNEL); if (!icom_port->statStg) { dev_err(&dev->dev, "Can not allocate Status buffer\n"); free_port_memory(icom_port); @@ -199,7 +202,8 @@ static int get_port_memory(struct icom_port *icom_port) (unsigned long) icom_port->statStg); icom_port->xmitRestart = - pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci); + dma_alloc_coherent(&dev->dev, 4096, &icom_port->xmitRestart_pci, + GFP_KERNEL); if (!icom_port->xmitRestart) { dev_err(&dev->dev, "Can not allocate xmit Restart buffer\n"); @@ -414,7 +418,7 @@ static void load_code(struct icom_port *icom_port) /*Set up data in icom DRAM to indicate where personality *code is located and its length. */ - new_page = pci_alloc_consistent(dev, 4096, &temp_pci); + new_page = dma_alloc_coherent(&dev->dev, 4096, &temp_pci, GFP_KERNEL); if (!new_page) { dev_err(&dev->dev, "Can not allocate DMA buffer\n"); @@ -494,7 +498,7 @@ static void load_code(struct icom_port *icom_port) } if (new_page != NULL) - pci_free_consistent(dev, 4096, new_page, temp_pci); + dma_free_coherent(&dev->dev, 4096, new_page, temp_pci); } static int startup(struct icom_port *icom_port) From 68778cab29bf27a60b67f55d6f4710d9fa906eab Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 6 Aug 2020 07:44:04 +0200 Subject: [PATCH 45/79] tty: synclink_gt: switch from 'pci_' to 'dma_' API The wrappers in include/linux/pci-dma-compat.h should go away. The patch has been generated with the coccinelle script below and has been hand modified to replace GFP_ with a correct flag. It has been compile tested. When memory is allocated in 'alloc_desc()' and 'alloc_bufs()', GFP_KERNEL can be used because it is only called from a probe function and no lock is acquired. The call chain is: init_one (the probe function) --> device_init --> alloc_dma_bufs --> alloc_desc --> alloc_bufs @@ @@ - PCI_DMA_BIDIRECTIONAL + DMA_BIDIRECTIONAL @@ @@ - PCI_DMA_TODEVICE + DMA_TO_DEVICE @@ @@ - PCI_DMA_FROMDEVICE + DMA_FROM_DEVICE @@ @@ - PCI_DMA_NONE + DMA_NONE @@ expression e1, e2, e3; @@ - pci_alloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3; @@ - pci_zalloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3, e4; @@ - pci_free_consistent(e1, e2, e3, e4) + dma_free_coherent(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_single(e1, e2, e3, e4) + dma_map_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_single(e1, e2, e3, e4) + dma_unmap_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4, e5; @@ - pci_map_page(e1, e2, e3, e4, e5) + dma_map_page(&e1->dev, e2, e3, e4, e5) @@ expression e1, e2, e3, e4; @@ - pci_unmap_page(e1, e2, e3, e4) + dma_unmap_page(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_sg(e1, e2, e3, e4) + dma_map_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_sg(e1, e2, e3, e4) + dma_unmap_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_cpu(e1, e2, e3, e4) + dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_device(e1, e2, e3, e4) + dma_sync_single_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) + dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_device(e1, e2, e3, e4) + dma_sync_sg_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2; @@ - pci_dma_mapping_error(e1, e2) + dma_mapping_error(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_dma_mask(e1, e2) + dma_set_mask(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_consistent_dma_mask(e1, e2) + dma_set_coherent_mask(&e1->dev, e2) Signed-off-by: Christophe JAILLET Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/20200806054404.728854-1-christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 917cc611ad25..afa4cc52e48d 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3338,8 +3338,8 @@ static int alloc_desc(struct slgt_info *info) unsigned int pbufs; /* allocate memory to hold descriptor lists */ - info->bufs = pci_zalloc_consistent(info->pdev, DESC_LIST_SIZE, - &info->bufs_dma_addr); + info->bufs = dma_alloc_coherent(&info->pdev->dev, DESC_LIST_SIZE, + &info->bufs_dma_addr, GFP_KERNEL); if (info->bufs == NULL) return -ENOMEM; @@ -3381,7 +3381,8 @@ static int alloc_desc(struct slgt_info *info) static void free_desc(struct slgt_info *info) { if (info->bufs != NULL) { - pci_free_consistent(info->pdev, DESC_LIST_SIZE, info->bufs, info->bufs_dma_addr); + dma_free_coherent(&info->pdev->dev, DESC_LIST_SIZE, + info->bufs, info->bufs_dma_addr); info->bufs = NULL; info->rbufs = NULL; info->tbufs = NULL; @@ -3392,7 +3393,9 @@ static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count) { int i; for (i=0; i < count; i++) { - if ((bufs[i].buf = pci_alloc_consistent(info->pdev, DMABUFSIZE, &bufs[i].buf_dma_addr)) == NULL) + bufs[i].buf = dma_alloc_coherent(&info->pdev->dev, DMABUFSIZE, + &bufs[i].buf_dma_addr, GFP_KERNEL); + if (!bufs[i].buf) return -ENOMEM; bufs[i].pbuf = cpu_to_le32((unsigned int)bufs[i].buf_dma_addr); } @@ -3405,7 +3408,8 @@ static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count) for (i=0; i < count; i++) { if (bufs[i].buf == NULL) continue; - pci_free_consistent(info->pdev, DMABUFSIZE, bufs[i].buf, bufs[i].buf_dma_addr); + dma_free_coherent(&info->pdev->dev, DMABUFSIZE, bufs[i].buf, + bufs[i].buf_dma_addr); bufs[i].buf = NULL; } } From db332356222d9429731ab9395c89cca403828460 Mon Sep 17 00:00:00 2001 From: Tong Zhang Date: Fri, 21 Aug 2020 12:19:40 -0400 Subject: [PATCH 46/79] tty: ipwireless: fix error handling ipwireless_send_packet() can only return 0 on success and -ENOMEM on error, the caller should check non zero for error condition Signed-off-by: Tong Zhang Acked-by: David Sterba Link: https://lore.kernel.org/r/20200821161942.36589-1-ztong0001@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/ipwireless/network.c | 4 ++-- drivers/tty/ipwireless/tty.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c index cf20616340a1..fe569f6294a2 100644 --- a/drivers/tty/ipwireless/network.c +++ b/drivers/tty/ipwireless/network.c @@ -117,7 +117,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, skb->len, notify_packet_sent, network); - if (ret == -1) { + if (ret < 0) { skb_pull(skb, 2); return 0; } @@ -134,7 +134,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, notify_packet_sent, network); kfree(buf); - if (ret == -1) + if (ret < 0) return 0; } kfree_skb(skb); diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index fad3401e604d..23584769fc29 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -218,7 +218,7 @@ static int ipw_write(struct tty_struct *linux_tty, ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS, buf, count, ipw_write_packet_sent_callback, tty); - if (ret == -1) { + if (ret < 0) { mutex_unlock(&tty->ipw_tty_mutex); return 0; } From 63ffcbdad738e3d1c857027789a2273df3337624 Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Thu, 20 Aug 2020 18:46:38 -0500 Subject: [PATCH 47/79] tty: hvcs: Don't NULL tty->driver_data until hvcs_cleanup() The code currently NULLs tty->driver_data in hvcs_close() with the intent of informing the next call to hvcs_open() that device needs to be reconfigured. However, when hvcs_cleanup() is called we copy hvcsd from tty->driver_data which was previoulsy NULLed by hvcs_close() and our call to tty_port_put(&hvcsd->port) doesn't actually do anything since &hvcsd->port ends up translating to NULL by chance. This has the side effect that when hvcs_remove() is called we have one too many port references preventing hvcs_destuct_port() from ever being called. This also prevents us from reusing the /dev/hvcsX node in a future hvcs_probe() and we can eventually run out of /dev/hvcsX devices. Fix this by waiting to NULL tty->driver_data in hvcs_cleanup(). Fixes: 27bf7c43a19c ("TTY: hvcs, add tty install") Signed-off-by: Tyrel Datwyler Link: https://lore.kernel.org/r/20200820234643.70412-1-tyreld@linux.ibm.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvcs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 55105ac38f89..509d1042825a 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1216,13 +1216,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) tty_wait_until_sent(tty, HVCS_CLOSE_WAIT); - /* - * This line is important because it tells hvcs_open that this - * device needs to be re-configured the next time hvcs_open is - * called. - */ - tty->driver_data = NULL; - free_irq(irq, hvcsd); return; } else if (hvcsd->port.count < 0) { @@ -1237,6 +1230,13 @@ static void hvcs_cleanup(struct tty_struct * tty) { struct hvcs_struct *hvcsd = tty->driver_data; + /* + * This line is important because it tells hvcs_open that this + * device needs to be re-configured the next time hvcs_open is + * called. + */ + tty->driver_data = NULL; + tty_port_put(&hvcsd->port); } From 71a174b39f10b4b93223d374722aa894b5d8a82e Mon Sep 17 00:00:00 2001 From: Artem Savkov Date: Wed, 2 Sep 2020 14:00:45 +0200 Subject: [PATCH 48/79] pty: do tty_flip_buffer_push without port->lock in pty_write b6da31b2c07c "tty: Fix data race in tty_insert_flip_string_fixed_flag" puts tty_flip_buffer_push under port->lock introducing the following possible circular locking dependency: [30129.876566] ====================================================== [30129.876566] WARNING: possible circular locking dependency detected [30129.876567] 5.9.0-rc2+ #3 Tainted: G S W [30129.876568] ------------------------------------------------------ [30129.876568] sysrq.sh/1222 is trying to acquire lock: [30129.876569] ffffffff92c39480 (console_owner){....}-{0:0}, at: console_unlock+0x3fe/0xa90 [30129.876572] but task is already holding lock: [30129.876572] ffff888107cb9018 (&pool->lock/1){-.-.}-{2:2}, at: show_workqueue_state.cold.55+0x15b/0x6ca [30129.876576] which lock already depends on the new lock. [30129.876577] the existing dependency chain (in reverse order) is: [30129.876578] -> #3 (&pool->lock/1){-.-.}-{2:2}: [30129.876581] _raw_spin_lock+0x30/0x70 [30129.876581] __queue_work+0x1a3/0x10f0 [30129.876582] queue_work_on+0x78/0x80 [30129.876582] pty_write+0x165/0x1e0 [30129.876583] n_tty_write+0x47f/0xf00 [30129.876583] tty_write+0x3d6/0x8d0 [30129.876584] vfs_write+0x1a8/0x650 [30129.876588] -> #2 (&port->lock#2){-.-.}-{2:2}: [30129.876590] _raw_spin_lock_irqsave+0x3b/0x80 [30129.876591] tty_port_tty_get+0x1d/0xb0 [30129.876592] tty_port_default_wakeup+0xb/0x30 [30129.876592] serial8250_tx_chars+0x3d6/0x970 [30129.876593] serial8250_handle_irq.part.12+0x216/0x380 [30129.876593] serial8250_default_handle_irq+0x82/0xe0 [30129.876594] serial8250_interrupt+0xdd/0x1b0 [30129.876595] __handle_irq_event_percpu+0xfc/0x850 [30129.876602] -> #1 (&port->lock){-.-.}-{2:2}: [30129.876605] _raw_spin_lock_irqsave+0x3b/0x80 [30129.876605] serial8250_console_write+0x12d/0x900 [30129.876606] console_unlock+0x679/0xa90 [30129.876606] register_console+0x371/0x6e0 [30129.876607] univ8250_console_init+0x24/0x27 [30129.876607] console_init+0x2f9/0x45e [30129.876609] -> #0 (console_owner){....}-{0:0}: [30129.876611] __lock_acquire+0x2f70/0x4e90 [30129.876612] lock_acquire+0x1ac/0xad0 [30129.876612] console_unlock+0x460/0xa90 [30129.876613] vprintk_emit+0x130/0x420 [30129.876613] printk+0x9f/0xc5 [30129.876614] show_pwq+0x154/0x618 [30129.876615] show_workqueue_state.cold.55+0x193/0x6ca [30129.876615] __handle_sysrq+0x244/0x460 [30129.876616] write_sysrq_trigger+0x48/0x4a [30129.876616] proc_reg_write+0x1a6/0x240 [30129.876617] vfs_write+0x1a8/0x650 [30129.876619] other info that might help us debug this: [30129.876620] Chain exists of: [30129.876621] console_owner --> &port->lock#2 --> &pool->lock/1 [30129.876625] Possible unsafe locking scenario: [30129.876626] CPU0 CPU1 [30129.876626] ---- ---- [30129.876627] lock(&pool->lock/1); [30129.876628] lock(&port->lock#2); [30129.876630] lock(&pool->lock/1); [30129.876631] lock(console_owner); [30129.876633] *** DEADLOCK *** [30129.876634] 5 locks held by sysrq.sh/1222: [30129.876634] #0: ffff8881d3ce0470 (sb_writers#3){.+.+}-{0:0}, at: vfs_write+0x359/0x650 [30129.876637] #1: ffffffff92c612c0 (rcu_read_lock){....}-{1:2}, at: __handle_sysrq+0x4d/0x460 [30129.876640] #2: ffffffff92c612c0 (rcu_read_lock){....}-{1:2}, at: show_workqueue_state+0x5/0xf0 [30129.876642] #3: ffff888107cb9018 (&pool->lock/1){-.-.}-{2:2}, at: show_workqueue_state.cold.55+0x15b/0x6ca [30129.876645] #4: ffffffff92c39980 (console_lock){+.+.}-{0:0}, at: vprintk_emit+0x123/0x420 [30129.876648] stack backtrace: [30129.876649] CPU: 3 PID: 1222 Comm: sysrq.sh Tainted: G S W 5.9.0-rc2+ #3 [30129.876649] Hardware name: Intel Corporation 2012 Client Platform/Emerald Lake 2, BIOS ACRVMBY1.86C.0078.P00.1201161002 01/16/2012 [30129.876650] Call Trace: [30129.876650] dump_stack+0x9d/0xe0 [30129.876651] check_noncircular+0x34f/0x410 [30129.876653] __lock_acquire+0x2f70/0x4e90 [30129.876656] lock_acquire+0x1ac/0xad0 [30129.876658] console_unlock+0x460/0xa90 [30129.876660] vprintk_emit+0x130/0x420 [30129.876660] printk+0x9f/0xc5 [30129.876661] show_pwq+0x154/0x618 [30129.876662] show_workqueue_state.cold.55+0x193/0x6ca [30129.876664] __handle_sysrq+0x244/0x460 [30129.876665] write_sysrq_trigger+0x48/0x4a [30129.876665] proc_reg_write+0x1a6/0x240 [30129.876666] vfs_write+0x1a8/0x650 It looks like the commit was aimed to protect tty_insert_flip_string and there is no need for tty_flip_buffer_push to be under this lock. Fixes: b6da31b2c07c ("tty: Fix data race in tty_insert_flip_string_fixed_flag") Signed-off-by: Artem Savkov Acked-by: Jiri Slaby Link: https://lore.kernel.org/r/20200902120045.3693075-1-asavkov@redhat.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index b6d8cc7f0f16..23368cec7ee8 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -120,10 +120,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) spin_lock_irqsave(&to->port->lock, flags); /* Stuff the data into the input queue of the other end */ c = tty_insert_flip_string(to->port, buf, c); + spin_unlock_irqrestore(&to->port->lock, flags); /* And shovel */ if (c) tty_flip_buffer_push(to->port); - spin_unlock_irqrestore(&to->port->lock, flags); } return c; } From 57cee071311800c59bb8735f24d83c95701dc04f Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 9 Sep 2020 21:51:03 +0800 Subject: [PATCH 49/79] serial: 8250_pci: Remove unused function get_pci_irq() It is not used since commit 8428413b1d14 ("serial: 8250_pci: Implement MSI(-X) support") Signed-off-by: YueHaibing Link: https://lore.kernel.org/r/20200909135103.17768-1-yuehaibing@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 85810b8b9d20..824c44ec25a8 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -2795,15 +2795,6 @@ static struct pci_serial_quirk *find_quirk(struct pci_dev *dev) return quirk; } -static inline int get_pci_irq(struct pci_dev *dev, - const struct pciserial_board *board) -{ - if (board->flags & FL_NOIRQ) - return 0; - else - return dev->irq; -} - /* * This is the configuration table for all of the PCI serial boards * which we support. It is directly indexed by the pci_board_num_t enum From 4be002f1dec8418d88bbc556a0dfbaa9adc38ab0 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Sat, 12 Sep 2020 11:38:34 +0800 Subject: [PATCH 50/79] serial: ucc_uart: make qe_uart_set_mctrl() static This eliminates the following sparse warning: drivers/tty/serial/ucc_uart.c:286:6: warning: symbol 'qe_uart_set_mctrl' was not declared. Should it be static? Reported-by: Hulk Robot Acked-by: Jiri Slaby Signed-off-by: Jason Yan Link: https://lore.kernel.org/r/20200912033834.143166-1-yanaijie@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ucc_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 3c8c662c69e2..d6a8604157ab 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -283,7 +283,7 @@ static unsigned int qe_uart_tx_empty(struct uart_port *port) * don't need that support. This function must exist, however, otherwise * the kernel will panic. */ -void qe_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +static void qe_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) { } From f28295cc8ce14b7a78bc3900eaba2e6c34111595 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Tue, 15 Sep 2020 13:48:25 +0800 Subject: [PATCH 51/79] tty: serial: print earlycon info after match->setup 8250 devices may modify iotype in their own earlycon setup. For example: 8250_mtk and 8250_uniphier force iotype to be MMIO32. Print earlycon info after match->setup to reflect actual earlycon info. Signed-off-by: Hsin-Yi Wang Link: https://lore.kernel.org/r/20200915054825.3289105-1-hsinyi@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/earlycon.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index 2ae9190b64bb..b70877932d47 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -56,7 +56,6 @@ static void __init earlycon_init(struct earlycon_device *device, const char *name) { struct console *earlycon = device->con; - struct uart_port *port = &device->port; const char *s; size_t len; @@ -70,6 +69,12 @@ static void __init earlycon_init(struct earlycon_device *device, len = s - name; strlcpy(earlycon->name, name, min(len + 1, sizeof(earlycon->name))); earlycon->data = &early_console_dev; +} + +static void __init earlycon_print_info(struct earlycon_device *device) +{ + struct console *earlycon = device->con; + struct uart_port *port = &device->port; if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM16 || port->iotype == UPIO_MEM32 || port->iotype == UPIO_MEM32BE) @@ -140,6 +145,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match) earlycon_init(&early_console_dev, match->name); err = match->setup(&early_console_dev, buf); + earlycon_print_info(&early_console_dev); if (err < 0) return err; if (!early_console_dev.con->write) @@ -302,6 +308,7 @@ int __init of_setup_earlycon(const struct earlycon_id *match, } earlycon_init(&early_console_dev, match->name); err = match->setup(&early_console_dev, options); + earlycon_print_info(&early_console_dev); if (err < 0) return err; if (!early_console_dev.con->write) From ea4de367e57d53b37ecb32cea3b5c753162b070a Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Tue, 15 Sep 2020 13:48:27 +0800 Subject: [PATCH 52/79] tty: serial: 8250_mtk: set regshift for mmio32 To use mmio32, we also need to set regshift. Signed-off-by: Hsin-Yi Wang Acked-by: Eddie Huang Link: https://lore.kernel.org/r/20200915054825.3289105-2-hsinyi@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_mtk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 7b0dec14c8b8..41f4120abdf2 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -669,6 +669,7 @@ static int __init early_mtk8250_setup(struct earlycon_device *device, return -ENODEV; device->port.iotype = UPIO_MEM32; + device->port.regshift = 2; return early_serial8250_setup(device, NULL); } From cb91e7519d5d81ebbe66f559d13949b1da4537c9 Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Wed, 16 Sep 2020 14:21:38 +0800 Subject: [PATCH 53/79] serial: pmac_zilog: use for_each_child_of_node() macro Use for_each_child_of_node() macro instead of open coding it. Signed-off-by: Qinglang Miao Link: https://lore.kernel.org/r/20200916062138.191188-1-miaoqinglang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pmac_zilog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 96e7aa479961..063484b22523 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -1644,7 +1644,7 @@ static int __init pmz_probe(void) * TODO: Add routines with proper locking to do that... */ node_a = node_b = NULL; - for (np = NULL; (np = of_get_next_child(node_p, np)) != NULL;) { + for_each_child_of_node(node_p, np) { if (of_node_name_prefix(np, "ch-a")) node_a = of_node_get(np); else if (of_node_name_prefix(np, "ch-b")) From 2ec812a04ff4ef8d4cba4005b7526691333a2973 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 11 Sep 2020 08:00:57 -0700 Subject: [PATCH 54/79] tty: serial: qcom_geni_serial: 115.2 is a better console default than 9600 Commit c5cbc78acf69 ("tty: serial: qcom_geni_serial: Initialize baud in qcom_geni_console_setup") fixed a bug by initting a variable that was used in some cases without initialization. However, the "default" baud rate picked by that CL was probably not the best choice. The chances that anyone out there is trying to run a system with kernel messages piped out over a 9600 baud serial port is just about nil. Console messages are printed in a blocking manner. At 9600 baud we print about 1 character per millisecond which means that printing a 40-byte message to the console will take ~40 ms. While it would probably work, it's going to make boot _very_ slow and probably cause the occasional timeout here and there in drivers (heck, even at 115200 console delays can wreck havoc). This has already bit at least two people that I'm aware of that tried to enable serial console by just adding "console=ttyMSM0" (instead of "console=ttyMSM0,115200n8") to the command line, so it seems like it'd be nice to fix. Let's switch the default to 115200. Reviewed-by: Nathan Chancellor Reviewed-by: Akash Asthana Reviewed-by: Bjorn Andersson Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20200911080054.1.I4c00b921c2f17b6988688046fa7be0f729f8d591@changeid Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index f0b1b47c3abc..e390ffc8bbbd 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1107,7 +1107,7 @@ static int qcom_geni_console_setup(struct console *co, char *options) { struct uart_port *uport; struct qcom_geni_serial_port *port; - int baud = 9600; + int baud = 115200; int bits = 8; int parity = 'n'; int flow = 'n'; From a4ced376fed0f90e5da56aad1612fc37ed5cfdac Mon Sep 17 00:00:00 2001 From: satya priya Date: Thu, 10 Sep 2020 18:23:58 +0530 Subject: [PATCH 55/79] tty: serial: qcom_geni_serial: Fix the UART wakeup issue As a part of system suspend uart_port_suspend is called from the Serial driver, which calls set_mctrl passing mctrl as 0. This makes RFR high(NOT_READY) during suspend. Due to this BT SoC is not able to send wakeup bytes to UART during suspend. Include if check for non-suspend case to keep RFR low during suspend. Signed-off-by: satya priya Reviewed-by: Akash Asthana Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/1599742438-16811-5-git-send-email-skakit@codeaurora.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index e390ffc8bbbd..8da2eb2d1090 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -242,7 +242,7 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport, if (mctrl & TIOCM_LOOP) port->loopback = RX_TX_CTS_RTS_SORTED; - if (!(mctrl & TIOCM_RTS)) + if (!(mctrl & TIOCM_RTS) && !uport->suspended) uart_manual_rfr = UART_MANUAL_RFR_EN | UART_RFR_NOT_READY; writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR); } From 1b24f46925d061b7fab70c828bac6774faf37f93 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 15 Sep 2020 09:00:17 +0900 Subject: [PATCH 56/79] newport_con: remove no-op newport_set_origin() We don't need to call vc->vc_sw->con_set_origin() from set_origin() if it is no-op. Signed-off-by: Tetsuo Handa Link: https://lore.kernel.org/r/20200915000019.3422-1-penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/newport_con.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 0d0989040c58..d494108fce4c 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -678,11 +678,6 @@ static bool newport_scroll(struct vc_data *vc, unsigned int t, unsigned int b, return true; } -static int newport_set_origin(struct vc_data *vc) -{ - return 0; -} - static void newport_save_screen(struct vc_data *vc) { } const struct consw newport_con = { @@ -699,7 +694,6 @@ const struct consw newport_con = { .con_blank = newport_blank, .con_font_set = newport_font_set, .con_font_default = newport_font_default, - .con_set_origin = newport_set_origin, .con_save_screen = newport_save_screen }; From 23f87274f0ad4a9167de23a330ed88966634fdf6 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 15 Sep 2020 09:00:18 +0900 Subject: [PATCH 57/79] sticon: remove no-op sticon_set_origin() We don't need to call vc->vc_sw->con_set_origin() from set_origin() if it is no-op. Signed-off-by: Tetsuo Handa Link: https://lore.kernel.org/r/20200915000019.3422-2-penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/sticon.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index e21147e8a14e..e7fd995d3aea 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -217,11 +217,6 @@ static int sticon_switch(struct vc_data *conp) return 1; /* needs refreshing */ } -static int sticon_set_origin(struct vc_data *conp) -{ - return 0; -} - static int sticon_blank(struct vc_data *c, int blank, int mode_switch) { if (blank == 0) { @@ -229,7 +224,6 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch) vga_is_gfx = 0; return 1; } - sticon_set_origin(c); sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK); if (mode_switch) vga_is_gfx = 1; @@ -334,7 +328,6 @@ static const struct consw sti_con = { .con_scroll = sticon_scroll, .con_switch = sticon_switch, .con_blank = sticon_blank, - .con_set_origin = sticon_set_origin, .con_save_screen = sticon_save_screen, .con_build_attr = sticon_build_attr, .con_invert_region = sticon_invert_region, From c8d55a22bc54e9b91f8d37feaa154313d3798847 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 8 Jul 2020 18:48:24 +0100 Subject: [PATCH 58/79] dt-bindings: serial: renesas, scif: Document r8a774e1 bindings RZ/G2H (R8A774E1) SoC also has the R-Car gen3 compatible SCIF ports, so document the SoC specific bindings. Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Lad Prabhakar Link: https://lore.kernel.org/r/1594230511-24790-2-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,scif.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/serial/renesas,scif.yaml b/Documentation/devicetree/bindings/serial/renesas,scif.yaml index 570b379f9f19..f589ac7577ae 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scif.yaml @@ -51,6 +51,7 @@ properties: - renesas,scif-r8a774a1 # RZ/G2M - renesas,scif-r8a774b1 # RZ/G2N - renesas,scif-r8a774c0 # RZ/G2E + - renesas,scif-r8a774e1 # RZ/G2H - renesas,scif-r8a7795 # R-Car H3 - renesas,scif-r8a7796 # R-Car M3-W - renesas,scif-r8a77961 # R-Car M3-W+ From 7d2bfdf1fa310728d9ce8baca3b691b4eecdeef0 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Wed, 8 Jul 2020 18:48:25 +0100 Subject: [PATCH 59/79] dt-bindings: serial: renesas, hscif: Document r8a774e1 bindings RZ/G2H (R8A774E1) SoC also has the R-Car gen3 compatible HSCIF ports, so document the SoC specific bindings. Reviewed-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Lad Prabhakar Link: https://lore.kernel.org/r/1594230511-24790-3-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,hscif.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml index 6b04c0451d41..9fb87a648c1b 100644 --- a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml @@ -42,6 +42,7 @@ properties: - renesas,hscif-r8a774a1 # RZ/G2M - renesas,hscif-r8a774b1 # RZ/G2N - renesas,hscif-r8a774c0 # RZ/G2E + - renesas,hscif-r8a774e1 # RZ/G2H - renesas,hscif-r8a7795 # R-Car H3 - renesas,hscif-r8a7796 # R-Car M3-W - renesas,hscif-r8a77961 # R-Car M3-W+ From 290ff182e92a3de286440c33990c98569ac329f4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 20 Sep 2020 13:26:13 +0200 Subject: [PATCH 60/79] pch_uart: drop double zeroing sg_init_table zeroes its first argument, so the allocation of that argument doesn't have to. the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,n,flags; @@ x = - kcalloc + kmalloc_array (n,sizeof(struct scatterlist),flags) ... sg_init_table(x,n) // Signed-off-by: Julia Lawall Link: https://lore.kernel.org/r/1600601186-7420-2-git-send-email-Julia.Lawall@inria.fr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 67aca8cb9cd4..a7363bc66c11 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -981,7 +981,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) priv->tx_dma_use = 1; - priv->sg_tx_p = kcalloc(num, sizeof(struct scatterlist), GFP_ATOMIC); + priv->sg_tx_p = kmalloc_array(num, sizeof(struct scatterlist), GFP_ATOMIC); if (!priv->sg_tx_p) { dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__); return 0; From 75fc65079d8253e1c25a5f8348111a85d71e0f01 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 19 Sep 2020 14:35:35 +0800 Subject: [PATCH 61/79] tty: hvc: fix link error with CONFIG_SERIAL_CORE_CONSOLE=n aarch64-linux-gnu-ld: drivers/tty/hvc/hvc_dcc.o: in function `dcc_early_write': hvc_dcc.c:(.text+0x164): undefined reference to `uart_console_write' The driver uses the uart_console_write(), but SERIAL_CORE_CONSOLE is not selected, so uart_console_write is not defined, then we get the error. Fix this by selecting SERIAL_CORE_CONSOLE. Fixes: d1a1af2cdf19 ("hvc: dcc: Add earlycon support") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20200919063535.2809707-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index d1b27b0522a3..8d60e0ff67b4 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig @@ -81,6 +81,7 @@ config HVC_DCC bool "ARM JTAG DCC console" depends on ARM || ARM64 select HVC_DRIVER + select SERIAL_CORE_CONSOLE help This console uses the JTAG DCC on ARM to create a console under the HVC driver. This console is used through a JTAG only on ARM. If you don't have From 24c796926e2f88b383a76ddc871a7cdd62484f3a Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 19 Sep 2020 14:32:40 +0800 Subject: [PATCH 62/79] tty: serial: imx: fix link error with CONFIG_SERIAL_CORE_CONSOLE=n aarch64-linux-gnu-ld: drivers/tty/serial/imx_earlycon.o: in function `imx_uart_console_early_write': imx_earlycon.c:(.text+0x84): undefined reference to `uart_console_write' The driver uses the uart_console_write(), but SERIAL_CORE_CONSOLE is not selected, so uart_console_write is not defined, then we get the error. Fix this by selecting SERIAL_CORE_CONSOLE. Fixes: 699cc4dfd140 ("tty: serial: imx: add imx earlycon driver") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20200919063240.2754965-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 54586c1aba60..20b98a3ba046 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -521,6 +521,7 @@ config SERIAL_IMX_EARLYCON depends on ARCH_MXC || COMPILE_TEST depends on OF select SERIAL_EARLYCON + select SERIAL_CORE_CONSOLE help If you have enabled the earlycon on the Freescale IMX CPU you can make it the earlycon by answering Y to this option. From b63537020db34ac3f88086095cc49df65283fb61 Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Mon, 21 Sep 2020 21:11:05 +0800 Subject: [PATCH 63/79] serial: mvebu-uart: simplify the return expression of mvebu_uart_probe() Simplify the return expression. Signed-off-by: Qinglang Miao Link: https://lore.kernel.org/r/20200921131105.93177-1-miaoqinglang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 4e9a590712cb..7443c0506eb4 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -912,10 +912,7 @@ static int mvebu_uart_probe(struct platform_device *pdev) udelay(1); writel(0, port->membase + UART_CTRL(port)); - ret = uart_add_one_port(&mvebu_uart_driver, port); - if (ret) - return ret; - return 0; + return uart_add_one_port(&mvebu_uart_driver, port); } static struct mvebu_uart_driver_data uart_std_driver_data = { From 988d0763361bb65690d60e2bc53a6b72777040c3 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sun, 27 Sep 2020 20:46:30 +0900 Subject: [PATCH 64/79] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE syzbot is reporting UAF/OOB read at bit_putcs()/soft_cursor() [1][2], for vt_resizex() from ioctl(VT_RESIZEX) allows setting font height larger than actual font height calculated by con_font_set() from ioctl(PIO_FONT). Since fbcon_set_font() from con_font_set() allocates minimal amount of memory based on actual font height calculated by con_font_set(), use of vt_resizex() can cause UAF/OOB read for font data. VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX. #define VT_RESIZE 0x5609 /* set kernel's idea of screensize */ #define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */ So far we are not aware of syzbot reports caused by setting non-zero value to v_vlin parameter. But given that it is possible that nobody is using VT_RESIZEX, we can try removing support for v_clin and v_vlin parameters. Therefore, this patch effectively makes VT_RESIZEX behave like VT_RESIZE, with emitting a message if somebody is still using v_clin and/or v_vlin parameters. [1] https://syzkaller.appspot.com/bug?id=32577e96d88447ded2d3b76d71254fb855245837 [2] https://syzkaller.appspot.com/bug?id=6b8355d27b2b94fb5cedf4655e3a59162d9e48e3 Reported-by: syzbot Reported-by: syzbot Signed-off-by: Tetsuo Handa Cc: stable Link: https://lore.kernel.org/r/4933b81b-9b1a-355b-df0e-9b31e8280ab9@i-love.sakura.ne.jp Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt_ioctl.c | 57 +++++++-------------------------------- 1 file changed, 10 insertions(+), 47 deletions(-) diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 2ea76a09e07f..0a33b8ababe3 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -772,58 +772,21 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs) if (copy_from_user(&v, cs, sizeof(struct vt_consize))) return -EFAULT; - /* FIXME: Should check the copies properly */ - if (!v.v_vlin) - v.v_vlin = vc->vc_scan_lines; - - if (v.v_clin) { - int rows = v.v_vlin / v.v_clin; - if (v.v_rows != rows) { - if (v.v_rows) /* Parameters don't add up */ - return -EINVAL; - v.v_rows = rows; - } - } - - if (v.v_vcol && v.v_ccol) { - int cols = v.v_vcol / v.v_ccol; - if (v.v_cols != cols) { - if (v.v_cols) - return -EINVAL; - v.v_cols = cols; - } - } - - if (v.v_clin > 32) - return -EINVAL; + if (v.v_vlin) + pr_info_once("\"struct vt_consize\"->v_vlin is ignored. Please report if you need this.\n"); + if (v.v_clin) + pr_info_once("\"struct vt_consize\"->v_clin is ignored. Please report if you need this.\n"); + console_lock(); for (i = 0; i < MAX_NR_CONSOLES; i++) { - struct vc_data *vcp; + vc = vc_cons[i].d; - if (!vc_cons[i].d) - continue; - console_lock(); - vcp = vc_cons[i].d; - if (vcp) { - int ret; - int save_scan_lines = vcp->vc_scan_lines; - int save_font_height = vcp->vc_font.height; - - if (v.v_vlin) - vcp->vc_scan_lines = v.v_vlin; - if (v.v_clin) - vcp->vc_font.height = v.v_clin; - vcp->vc_resize_user = 1; - ret = vc_resize(vcp, v.v_cols, v.v_rows); - if (ret) { - vcp->vc_scan_lines = save_scan_lines; - vcp->vc_font.height = save_font_height; - console_unlock(); - return ret; - } + if (vc) { + vc->vc_resize_user = 1; + vc_resize(vc, v.v_cols, v.v_rows); } - console_unlock(); } + console_unlock(); return 0; } From 58e49346672f738cf6eeb62009a5b0ae194374c4 Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Tue, 29 Sep 2020 16:56:51 +0800 Subject: [PATCH 65/79] serial: mvebu-uart: fix unused variable warning There's a warning shows that 'ret' becomes an unused variable after simplify the return expression of mvebu_uart_probe(). So remove it. Fixes: b63537020db3 ("serial: mvebu-uart: simplify the return expression of mvebu_uart_probe()") Reported-by: Stephen Rothwell Signed-off-by: Qinglang Miao Link: https://lore.kernel.org/r/20200929085651.158283-1-miaoqinglang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 7443c0506eb4..118b29912289 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -803,7 +803,7 @@ static int mvebu_uart_probe(struct platform_device *pdev) &pdev->dev); struct uart_port *port; struct mvebu_uart *mvuart; - int ret, id, irq; + int id, irq; if (!reg) { dev_err(&pdev->dev, "no registers defined\n"); From c9ca43d42ed8d5fd635d327a664ed1d8579eb2af Mon Sep 17 00:00:00 2001 From: Paras Sharma Date: Wed, 30 Sep 2020 11:35:26 +0530 Subject: [PATCH 66/79] serial: qcom_geni_serial: To correct QUP Version detection logic For QUP IP versions 2.5 and above the oversampling rate is halved from 32 to 16. Commit ce734600545f ("tty: serial: qcom_geni_serial: Update the oversampling rate") is pushed to handle this scenario. But the existing logic is failing to classify QUP Version 3.0 into the correct group ( 2.5 and above). As result Serial Engine clocks are not configured properly for baud rate and garbage data is sampled to FIFOs from the line. So, fix the logic to detect QUP with versions 2.5 and above. Fixes: ce734600545f ("tty: serial: qcom_geni_serial: Update the oversampling rate") Cc: stable Signed-off-by: Paras Sharma Reviewed-by: Akash Asthana Link: https://lore.kernel.org/r/1601445926-23673-1-git-send-email-parashar@codeaurora.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 2 +- include/linux/qcom-geni-se.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 8da2eb2d1090..291649f02821 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1000,7 +1000,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, sampling_rate = UART_OVERSAMPLING; /* Sampling rate is halved for IP versions >= 2.5 */ ver = geni_se_get_qup_hw_version(&port->se); - if (GENI_SE_VERSION_MAJOR(ver) >= 2 && GENI_SE_VERSION_MINOR(ver) >= 5) + if (ver >= QUP_SE_VERSION_2_5) sampling_rate /= 2; clk_rate = get_clk_div_rate(baud, sampling_rate, &clk_div); diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h index 8f385fbe5a0e..1c31f26ccc7a 100644 --- a/include/linux/qcom-geni-se.h +++ b/include/linux/qcom-geni-se.h @@ -248,6 +248,9 @@ struct geni_se { #define GENI_SE_VERSION_MINOR(ver) ((ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT) #define GENI_SE_VERSION_STEP(ver) (ver & HW_VER_STEP_MASK) +/* QUP SE VERSION value for major number 2 and minor number 5 */ +#define QUP_SE_VERSION_2_5 0x20050000 + /* * Define bandwidth thresholds that cause the underlying Core 2X interconnect * clock to run at the named frequency. These baseline values are recommended From 9ea40db477c024dcb87321b7f32bd6ea12130ac2 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 29 Sep 2020 17:19:20 +0800 Subject: [PATCH 67/79] tty: serial: lpuart: fix lpuart32_write usage The 2nd and 3rd parameter were wrongly used, and cause kernel abort when doing kgdb debug. Fixes: 1da17d7cf8e2 ("tty: serial: fsl_lpuart: Use appropriate lpuart32_* I/O funcs") Cc: stable Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20200929091920.22612-1-peng.fan@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 5a5a22d77841..645bbb24b433 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -649,26 +649,24 @@ static int lpuart32_poll_init(struct uart_port *port) spin_lock_irqsave(&sport->port.lock, flags); /* Disable Rx & Tx */ - lpuart32_write(&sport->port, UARTCTRL, 0); + lpuart32_write(&sport->port, 0, UARTCTRL); temp = lpuart32_read(&sport->port, UARTFIFO); /* Enable Rx and Tx FIFO */ - lpuart32_write(&sport->port, UARTFIFO, - temp | UARTFIFO_RXFE | UARTFIFO_TXFE); + lpuart32_write(&sport->port, temp | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO); /* flush Tx and Rx FIFO */ - lpuart32_write(&sport->port, UARTFIFO, - UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH); + lpuart32_write(&sport->port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO); /* explicitly clear RDRF */ if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_RDRF) { lpuart32_read(&sport->port, UARTDATA); - lpuart32_write(&sport->port, UARTFIFO, UARTFIFO_RXUF); + lpuart32_write(&sport->port, UARTFIFO_RXUF, UARTFIFO); } /* Enable Rx and Tx */ - lpuart32_write(&sport->port, UARTCTRL, UARTCTRL_RE | UARTCTRL_TE); + lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL); spin_unlock_irqrestore(&sport->port.lock, flags); return 0; @@ -677,7 +675,7 @@ static int lpuart32_poll_init(struct uart_port *port) static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c) { lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TDRE); - lpuart32_write(port, UARTDATA, c); + lpuart32_write(port, c, UARTDATA); } static int lpuart32_poll_get_char(struct uart_port *port) From 29788ab1d2bf26c130de8f44f9553ee78a27e8d5 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 29 Sep 2020 17:55:09 +0800 Subject: [PATCH 68/79] tty: serial: fsl_lpuart: fix lpuart32_poll_get_char The watermark is set to 1, so we need to input two chars to trigger RDRF using the original logic. With the new logic, we could always get the char when there is data in FIFO. Suggested-by: Fugang Duan Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20200929095509.21680-1-peng.fan@nxp.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 645bbb24b433..590c901a1fc5 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -680,7 +680,7 @@ static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c) static int lpuart32_poll_get_char(struct uart_port *port) { - if (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_RDRF)) + if (!(lpuart32_read(port, UARTWATER) >> UARTWATER_RXCNT_OFF)) return NO_POLL_CHAR; return lpuart32_read(port, UARTDATA); From 534cf755d9df99e214ddbe26b91cd4d81d2603e2 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 30 Sep 2020 13:04:32 +0100 Subject: [PATCH 69/79] serial: pl011: Fix lockdep splat when handling magic-sysrq interrupt Issuing a magic-sysrq via the PL011 causes the following lockdep splat, which is easily reproducible under QEMU: | sysrq: Changing Loglevel | sysrq: Loglevel set to 9 | | ====================================================== | WARNING: possible circular locking dependency detected | 5.9.0-rc7 #1 Not tainted | ------------------------------------------------------ | systemd-journal/138 is trying to acquire lock: | ffffab133ad950c0 (console_owner){-.-.}-{0:0}, at: console_lock_spinning_enable+0x34/0x70 | | but task is already holding lock: | ffff0001fd47b098 (&port_lock_key){-.-.}-{2:2}, at: pl011_int+0x40/0x488 | | which lock already depends on the new lock. [...] | Possible unsafe locking scenario: | | CPU0 CPU1 | ---- ---- | lock(&port_lock_key); | lock(console_owner); | lock(&port_lock_key); | lock(console_owner); | | *** DEADLOCK *** The issue being that CPU0 takes 'port_lock' on the irq path in pl011_int() before taking 'console_owner' on the printk() path, whereas CPU1 takes the two locks in the opposite order on the printk() path due to setting the "console_owner" prior to calling into into the actual console driver. Fix this in the same way as the msm-serial driver by dropping 'port_lock' before handling the sysrq. Cc: # 4.19+ Cc: Russell King Cc: Greg Kroah-Hartman Cc: Jiri Slaby Link: https://lore.kernel.org/r/20200811101313.GA6970@willie-the-truck Signed-off-by: Peter Zijlstra Tested-by: Will Deacon Signed-off-by: Will Deacon Link: https://lore.kernel.org/r/20200930120432.16551-1-will@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 67498594d7d7..87dc3fc15694 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -308,8 +308,9 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap, */ static int pl011_fifo_to_tty(struct uart_amba_port *uap) { - u16 status; unsigned int ch, flag, fifotaken; + int sysrq; + u16 status; for (fifotaken = 0; fifotaken != 256; fifotaken++) { status = pl011_read(uap, REG_FR); @@ -344,10 +345,12 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&uap->port, ch & 255)) - continue; + spin_unlock(&uap->port.lock); + sysrq = uart_handle_sysrq_char(&uap->port, ch & 255); + spin_lock(&uap->port.lock); - uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); + if (!sysrq) + uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); } return fifotaken; From 409cc4541ade015acd11f2566dcda599363a87a3 Mon Sep 17 00:00:00 2001 From: Andrij Abyzov Date: Mon, 28 Sep 2020 16:41:27 +0200 Subject: [PATCH 70/79] serial: 8250_fsl: Fix TX interrupt handling condition This is the port of the commit db1b5bc047b3 ("serial: 8250: Fix TX interrupt handling condition") to the 8250_fsl irq handling logic. Interrupt handler checked THRE bit (transmitter holding register empty) in LSR to detect if TX fifo is empty. In case when there is only receive interrupts the TX handling got called because THRE bit in LSR is set when there is no transmission (FIFO empty). TX handling caused TX stop, which in RS-485 half-duplex mode actually resets receiver FIFO. This is not desired during reception because of possible data loss. The fix is to check if THRI is set in IER in addition of the TX fifo status. THRI in IER is set when TX is started and cleared when TX is stopped. This ensures that TX handling is only called when there is really transmission on going and an interrupt for THRE and not when there are only RX interrupts. Signed-off-by: Andrij Abyzov Link: https://lore.kernel.org/r/20200928144127.87156-1-aabyzov@slb.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_fsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index c3582d8938d6..fbcc90c31ca1 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -78,7 +78,7 @@ int fsl8250_handle_irq(struct uart_port *port) serial8250_modem_status(up); - if (lsr & UART_LSR_THRE) + if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI)) serial8250_tx_chars(up); up->lsr_saved_flags = orig_lsr; From edd64f30792dca1aee1fc27381b7c9c1ec0e9e58 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 25 Sep 2020 10:24:12 +0200 Subject: [PATCH 71/79] tty: serial: imx: disable TXDC IRQ in imx_uart_shutdown() to avoid IRQ storm The IPG clock is disabled at the end of imx_uart_shutdown(); we really don't want to run any IRQ handlers after this point. At least on i.MX8MN, the UART will happily continue to generate interrupts even with its clocks disabled, but in this state, all register writes are ignored (which will cause the shadow registers to differ from the actual register values, resulting in all kinds of weirdness). In a transfer without DMA, this could lead to the following sequence of events: - The UART finishes its transmission while imx_uart_shutdown() is run, triggering the TXDC interrupt (we can trigger this fairly reliably by writing a single byte to the TTY and closing it right away) - imx_uart_shutdown() finishes, disabling the UART clocks - imx_uart_int() -> imx_uart_transmit_buffer() -> imx_uart_stop_tx() imx_uart_stop_tx() should now clear UCR4_TCEN to disable the TXDC interrupt, but this register write is ineffective. This results in an interrupt storm. To disable all interrupts in the same place, and to avoid setting UCR4 twice, clearing UCR4_OREN is moved below del_timer_sync() as well; this should be harmless. Signed-off-by: Matthias Schiffer Link: https://lore.kernel.org/r/20200925082412.12960-1-matthias.schiffer@ew.tq-group.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 4e6ead1f650e..1731d9728865 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1552,10 +1552,6 @@ static void imx_uart_shutdown(struct uart_port *port) ucr2 = imx_uart_readl(sport, UCR2); ucr2 &= ~(UCR2_TXEN | UCR2_ATEN); imx_uart_writel(sport, ucr2, UCR2); - - ucr4 = imx_uart_readl(sport, UCR4); - ucr4 &= ~UCR4_OREN; - imx_uart_writel(sport, ucr4, UCR4); spin_unlock_irqrestore(&sport->port.lock, flags); /* @@ -1568,10 +1564,15 @@ static void imx_uart_shutdown(struct uart_port *port) */ spin_lock_irqsave(&sport->port.lock, flags); + ucr1 = imx_uart_readl(sport, UCR1); ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN); - imx_uart_writel(sport, ucr1, UCR1); + + ucr4 = imx_uart_readl(sport, UCR4); + ucr4 &= ~(UCR4_OREN | UCR4_TCEN); + imx_uart_writel(sport, ucr4, UCR4); + spin_unlock_irqrestore(&sport->port.lock, flags); clk_disable_unprepare(sport->clk_per); From 7718453e36960dadb8dc46f2b514b309659e1270 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Wed, 23 Sep 2020 19:19:48 +0300 Subject: [PATCH 72/79] serial: 8250: Discard RTS/DTS setting from clock update method It has been a mistake to add the MCR register RTS/DTS fields setting in the generic method of the UART reference clock update. There is no point in asserting these lines at that procedure. Just discard the serial8250_out_MCR() mathod invocation from there then. Fixes: 868f3ee6e452 ("serial: 8250: Add 8250 port clock update method") Tested-by: Hans de Goede Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20200923161950.6237-2-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index c71d647eb87a..1259fb6b66b3 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2665,7 +2665,6 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) serial8250_set_divisor(port, baud, quot, frac); serial_port_out(port, UART_LCR, up->lcr); - serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); spin_unlock_irqrestore(&port->lock, flags); serial8250_rpm_put(up); From c8dff3aa824177013d90967687f09f713a55d13f Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Wed, 23 Sep 2020 19:19:49 +0300 Subject: [PATCH 73/79] serial: 8250: Skip uninitialized TTY port baud rate update It is erroneous to update the TTY port baud rate if it hasn't been initialized yet, because in that case the TTY struct isn't set. So there is no termios structure to get and re-calculate the baud if the current baud can't be reached. Let's skip the baud rate update then until the port is fully initialized. Note the update UART clock method still sets the uartclk member with a new ref clock value even if the port is turned off. The new UART ref clock rate will be used later on the port starting up procedure. Fixes: 868f3ee6e452 ("serial: 8250: Add 8250 port clock update method") Tested-by: Hans de Goede Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20200923161950.6237-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 1259fb6b66b3..b0af13074cd3 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2653,6 +2653,10 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) goto out_lock; port->uartclk = uartclk; + + if (!tty_port_initialized(&port->state->port)) + goto out_lock; + termios = &port->state->port.tty->termios; baud = serial8250_get_baud_rate(port, termios, NULL); From 85985a3dcd7415dd849cf62ec14f931cd905099a Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Wed, 23 Sep 2020 19:19:50 +0300 Subject: [PATCH 74/79] serial: 8250_dw: Fix clk-notifier/port suspend deadlock It has been discovered that there is a potential deadlock between the clock-change-notifier thread and the UART port suspending one: CPU0 (suspend CPU/UART) CPU1 (update clock) ---- ---- lock(&port->mutex); lock((work_completion)(&data->clk_work)); lock(&port->mutex); lock((work_completion)(&data->clk_work)); *** DEADLOCK *** The best way to fix this is to eliminate the CPU0 port->mutex/work-completion scenario. So we suggest to register and unregister the clock-notifier during the DW APB UART port probe/remove procedures, instead of doing that at the points of the port startup/shutdown. Link: https://lore.kernel.org/linux-serial/f1cd5c75-9cda-6896-a4e2-42c5bfc3f5c3@redhat.com Fixes: cc816969d7b5 ("serial: 8250_dw: Fix common clocks usage race condition") Reported-by: Hans de Goede Tested-by: Hans de Goede Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20200923161950.6237-4-Sergey.Semin@baikalelectronics.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 54 +++++++++++-------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 87f450b7c177..9e204f9b799a 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -373,39 +373,6 @@ static void dw8250_set_ldisc(struct uart_port *p, struct ktermios *termios) serial8250_do_set_ldisc(p, termios); } -static int dw8250_startup(struct uart_port *p) -{ - struct dw8250_data *d = to_dw8250_data(p->private_data); - int ret; - - /* - * Some platforms may provide a reference clock shared between several - * devices. In this case before using the serial port first we have to - * make sure that any clock state change is known to the UART port at - * least post factum. - */ - if (d->clk) { - ret = clk_notifier_register(d->clk, &d->clk_notifier); - if (ret) - dev_warn(p->dev, "Failed to set the clock notifier\n"); - } - - return serial8250_do_startup(p); -} - -static void dw8250_shutdown(struct uart_port *p) -{ - struct dw8250_data *d = to_dw8250_data(p->private_data); - - serial8250_do_shutdown(p); - - if (d->clk) { - clk_notifier_unregister(d->clk, &d->clk_notifier); - - flush_work(&d->clk_work); - } -} - /* * dw8250_fallback_dma_filter will prevent the UART from getting just any free * channel on platforms that have DMA engines, but don't have any channels @@ -501,8 +468,6 @@ static int dw8250_probe(struct platform_device *pdev) p->serial_out = dw8250_serial_out; p->set_ldisc = dw8250_set_ldisc; p->set_termios = dw8250_set_termios; - p->startup = dw8250_startup; - p->shutdown = dw8250_shutdown; p->membase = devm_ioremap(dev, regs->start, resource_size(regs)); if (!p->membase) @@ -622,6 +587,19 @@ static int dw8250_probe(struct platform_device *pdev) goto err_reset; } + /* + * Some platforms may provide a reference clock shared between several + * devices. In this case any clock state change must be known to the + * UART port at least post factum. + */ + if (data->clk) { + err = clk_notifier_register(data->clk, &data->clk_notifier); + if (err) + dev_warn(p->dev, "Failed to set the clock notifier\n"); + else + queue_work(system_unbound_wq, &data->clk_work); + } + platform_set_drvdata(pdev, data); pm_runtime_set_active(dev); @@ -648,6 +626,12 @@ static int dw8250_remove(struct platform_device *pdev) pm_runtime_get_sync(dev); + if (data->clk) { + clk_notifier_unregister(data->clk, &data->clk_notifier); + + flush_work(&data->clk_work); + } + serial8250_unregister_port(data->data.line); reset_control_assert(data->rst); From fce3c5c1a2d9cd888f2987662ce17c0c651916b2 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 1 Oct 2020 09:44:15 +0200 Subject: [PATCH 75/79] serial: max310x: rework RX interrupt handling Currently, the RX interrupt logic uses the RXEMPTY interrupt, with the RXEMPTYINV bit set, which means we get an RX interrupt as soon as the RX FIFO is non-empty. However, with the MAX310X having a FIFO of 128 bytes, this makes very poor use of the FIFO: we trigger an interrupt as soon as the RX FIFO has one byte, which means a lot of interrupts, each only collecting a few bytes from the FIFO, causing a significant CPU load. Instead this commit relies on two other RX interrupt events: - MAX310X_IRQ_RXFIFO_BIT, which triggers when the RX FIFO has reached a certain threshold, which we define to be half of the FIFO size. This ensure we get an interrupt before the RX FIFO fills up. - MAX310X_LSR_RXTO_BIT, which triggers when the RX FIFO has received some bytes, and then no more bytes are received for a certain time. Arbitrarily, this time is defined to the time is takes to receive 4 characters. On a Microchip SAMA5D3 platform that is receiving 20 bytes every 16ms over one MAX310X UART, this patch has allowed to reduce the CPU consumption of the interrupt handler thread from ~25% to 6-7%. Signed-off-by: Thomas Petazzoni Link: https://lore.kernel.org/r/20201001074415.349739-1-thomas.petazzoni@bootlin.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 8434bd5a8ec7..21130af106bb 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1056,9 +1056,9 @@ static int max310x_startup(struct uart_port *port) max310x_port_update(port, MAX310X_MODE1_REG, MAX310X_MODE1_TRNSCVCTRL_BIT, 0); - /* Configure MODE2 register & Reset FIFOs*/ - val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT; - max310x_port_write(port, MAX310X_MODE2_REG, val); + /* Reset FIFOs */ + max310x_port_write(port, MAX310X_MODE2_REG, + MAX310X_MODE2_FIFORST_BIT); max310x_port_update(port, MAX310X_MODE2_REG, MAX310X_MODE2_FIFORST_BIT, 0); @@ -1086,8 +1086,27 @@ static int max310x_startup(struct uart_port *port) /* Clear IRQ status register */ max310x_port_read(port, MAX310X_IRQSTS_REG); - /* Enable RX, TX, CTS change interrupts */ - val = MAX310X_IRQ_RXEMPTY_BIT | MAX310X_IRQ_TXEMPTY_BIT; + /* + * Let's ask for an interrupt after a timeout equivalent to + * the receiving time of 4 characters after the last character + * has been received. + */ + max310x_port_write(port, MAX310X_RXTO_REG, 4); + + /* + * Make sure we also get RX interrupts when the RX FIFO is + * filling up quickly, so get an interrupt when half of the RX + * FIFO has been filled in. + */ + max310x_port_write(port, MAX310X_FIFOTRIGLVL_REG, + MAX310X_FIFOTRIGLVL_RX(MAX310X_FIFO_SIZE / 2)); + + /* Enable RX timeout interrupt in LSR */ + max310x_port_write(port, MAX310X_LSR_IRQEN_REG, + MAX310X_LSR_RXTO_BIT); + + /* Enable LSR, RX FIFO trigger, CTS change interrupts */ + val = MAX310X_IRQ_LSR_BIT | MAX310X_IRQ_RXFIFO_BIT | MAX310X_IRQ_TXEMPTY_BIT; max310x_port_write(port, MAX310X_IRQEN_REG, val | MAX310X_IRQ_CTS_BIT); return 0; From a27eb0cb4b2104461de1a1284059b3ac875e45b5 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 18 Aug 2020 13:28:24 +0200 Subject: [PATCH 76/79] tty/sysrq: Extend the sysrq_key_table to cover capital letters All slots in sysrq_key_table[] are either used, reserved or at least commented with their intended use. This patch adds capital letter versions available, which means adding 26 more entries. For already existing SysRq operations the user presses Alt-SysRq-, and for the newly added ones Alt-Shift-SysRq-. Signed-off-by: Andrzej Pietrasiewicz Acked-by: Daniel Vetter Link: https://lore.kernel.org/r/20200818112825.6445-2-andrzej.p@collabora.com Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/sysrq.rst | 2 ++ drivers/gpu/drm/drm_fb_helper.c | 2 +- drivers/tty/sysrq.c | 49 +++++++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/Documentation/admin-guide/sysrq.rst b/Documentation/admin-guide/sysrq.rst index e6424d8c5846..67dfa4c29093 100644 --- a/Documentation/admin-guide/sysrq.rst +++ b/Documentation/admin-guide/sysrq.rst @@ -79,6 +79,8 @@ On all echo t > /proc/sysrq-trigger +The :kbd:`` is case sensitive. + What are the 'command' keys? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 8697554ccd41..1543d9d10970 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -325,7 +325,7 @@ static void drm_fb_helper_sysrq(int dummy1) static const struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { .handler = drm_fb_helper_sysrq, - .help_msg = "force-fb(V)", + .help_msg = "force-fb(v)", .action_msg = "Restore framebuffer console", }; #else diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index a8e39b2cdd55..959f9e121cc6 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -440,7 +441,7 @@ static const struct sysrq_key_op sysrq_unrt_op = { /* Key Operations table and lock */ static DEFINE_SPINLOCK(sysrq_key_table_lock); -static const struct sysrq_key_op *sysrq_key_table[36] = { +static const struct sysrq_key_op *sysrq_key_table[62] = { &sysrq_loglevel_op, /* 0 */ &sysrq_loglevel_op, /* 1 */ &sysrq_loglevel_op, /* 2 */ @@ -497,6 +498,32 @@ static const struct sysrq_key_op *sysrq_key_table[36] = { /* y: May be registered on sparc64 for global register dump */ NULL, /* y */ &sysrq_ftrace_dump_op, /* z */ + NULL, /* A */ + NULL, /* B */ + NULL, /* C */ + NULL, /* D */ + NULL, /* E */ + NULL, /* F */ + NULL, /* G */ + NULL, /* H */ + NULL, /* I */ + NULL, /* J */ + NULL, /* K */ + NULL, /* L */ + NULL, /* M */ + NULL, /* N */ + NULL, /* O */ + NULL, /* P */ + NULL, /* Q */ + NULL, /* R */ + NULL, /* S */ + NULL, /* T */ + NULL, /* U */ + NULL, /* V */ + NULL, /* W */ + NULL, /* X */ + NULL, /* Y */ + NULL, /* Z */ }; /* key2index calculation, -1 on invalid index */ @@ -508,6 +535,8 @@ static int sysrq_key_table_key2index(int key) retval = key - '0'; else if ((key >= 'a') && (key <= 'z')) retval = key + 10 - 'a'; + else if ((key >= 'A') && (key <= 'Z')) + retval = key + 36 - 'A'; else retval = -1; return retval; @@ -621,6 +650,8 @@ struct sysrq_state { unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; unsigned int alt; unsigned int alt_use; + unsigned int shift; + unsigned int shift_use; bool active; bool need_reinject; bool reinjecting; @@ -805,10 +836,20 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq, } break; + case KEY_LEFTSHIFT: + case KEY_RIGHTSHIFT: + if (!value) + sysrq->shift = KEY_RESERVED; + else if (value != 2) + sysrq->shift = code; + break; + case KEY_SYSRQ: if (value == 1 && sysrq->alt != KEY_RESERVED) { sysrq->active = true; sysrq->alt_use = sysrq->alt; + /* either RESERVED (for released) or actual code */ + sysrq->shift_use = sysrq->shift; /* * If nothing else will be pressed we'll need * to re-inject Alt-SysRq keysroke. @@ -831,8 +872,12 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq, default: if (sysrq->active && value && value != 2) { + unsigned char c = sysrq_xlate[code]; + sysrq->need_reinject = false; - __handle_sysrq(sysrq_xlate[code], true); + if (sysrq->shift_use != KEY_RESERVED) + c = toupper(c); + __handle_sysrq(c, true); } break; } From bfeb28539d1f61829232883ced0986569218c4de Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 15 Sep 2020 09:00:19 +0900 Subject: [PATCH 77/79] fbcon: remove no-op fbcon_set_origin() We don't need to call vc->vc_sw->con_set_origin() from set_origin() if it is no-op. Signed-off-by: Tetsuo Handa Link: https://lore.kernel.org/r/20200915000019.3422-3-penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/core/fbcon.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 6fea22c4642c..ad0862d6c1a9 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -163,8 +163,6 @@ static const struct consw fb_con; #define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row) -static int fbcon_set_origin(struct vc_data *); - static int fbcon_cursor_noblink; #define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1) @@ -2635,11 +2633,6 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt) } } -static int fbcon_set_origin(struct vc_data *vc) -{ - return 0; -} - void fbcon_suspended(struct fb_info *info) { struct vc_data *vc = NULL; @@ -3110,7 +3103,6 @@ static const struct consw fb_con = { .con_font_default = fbcon_set_def_font, .con_font_copy = fbcon_copy_font, .con_set_palette = fbcon_set_palette, - .con_set_origin = fbcon_set_origin, .con_invert_region = fbcon_invert_region, .con_screen_pos = fbcon_screen_pos, .con_getxy = fbcon_getxy, From f4eef224a09f4ea4344211dabfb875dd865df479 Mon Sep 17 00:00:00 2001 From: Angelo Dureghello Date: Sun, 4 Oct 2020 18:11:44 +0200 Subject: [PATCH 78/79] serial: fsl_lpuart: add sysrq support when using dma Add handling of magic sysrq keys when using dma/edma. Tested by sending BREAK followed by a sysrq command inside a 5 secs time window, by: echo 1 > /proc/sys/kernel/sysrq BREAK + h, t, e, b, c Tested also sending a command after 5 secs after BREAK, that's properly ignored. Signed-off-by: Angelo Dureghello Link: https://lore.kernel.org/r/20201004161144.1307174-1-angelo.dureghello@timesys.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 590c901a1fc5..ff4b88c637d0 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -976,6 +976,15 @@ static irqreturn_t lpuart_int(int irq, void *dev_id) sts = readb(sport->port.membase + UARTSR1); + /* SysRq, using dma, check for linebreak by framing err. */ + if (sts & UARTSR1_FE && sport->lpuart_dma_rx_use) { + readb(sport->port.membase + UARTDR); + uart_handle_break(&sport->port); + /* linebreak produces some garbage, removing it */ + writeb(UARTCFIFO_RXFLUSH, sport->port.membase + UARTCFIFO); + return IRQ_HANDLED; + } + if (sts & UARTSR1_RDRF && !sport->lpuart_dma_rx_use) lpuart_rxint(sport); @@ -1004,6 +1013,37 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id) return IRQ_HANDLED; } + +static inline void lpuart_handle_sysrq_chars(struct uart_port *port, + unsigned char *p, int count) +{ + while (count--) { + if (*p && uart_handle_sysrq_char(port, *p)) + return; + p++; + } +} + +static void lpuart_handle_sysrq(struct lpuart_port *sport) +{ + struct circ_buf *ring = &sport->rx_ring; + int count; + + if (ring->head < ring->tail) { + count = sport->rx_sgl.length - ring->tail; + lpuart_handle_sysrq_chars(&sport->port, + ring->buf + ring->tail, count); + ring->tail = 0; + } + + if (ring->head > ring->tail) { + count = ring->head - ring->tail; + lpuart_handle_sysrq_chars(&sport->port, + ring->buf + ring->tail, count); + ring->tail = ring->head; + } +} + static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) { struct tty_port *port = &sport->port.state->port; @@ -1090,6 +1130,15 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) */ ring->head = sport->rx_sgl.length - state.residue; BUG_ON(ring->head > sport->rx_sgl.length); + + /* + * Silent handling of keys pressed in the sysrq timeframe + */ + if (sport->port.sysrq) { + lpuart_handle_sysrq(sport); + goto exit; + } + /* * At this point ring->head may point to the first byte right after the * last byte of the dma buffer: @@ -1121,6 +1170,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) sport->port.icount.rx += count; } +exit: dma_sync_sg_for_device(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); @@ -1557,6 +1607,7 @@ err: static void lpuart_rx_dma_startup(struct lpuart_port *sport) { int ret; + unsigned char cr3; if (!sport->dma_rx_chan) goto err; @@ -1573,6 +1624,12 @@ static void lpuart_rx_dma_startup(struct lpuart_port *sport) sport->lpuart_dma_rx_use = true; rx_dma_timer_init(sport); + if (sport->port.has_sysrq) { + cr3 = readb(sport->port.membase + UARTCR3); + cr3 |= UARTCR3_FEIE; + writeb(cr3, sport->port.membase + UARTCR3); + } + return; err: From 4be87603b6dc9e49c2e07151bb51180dc0b6964a Mon Sep 17 00:00:00 2001 From: Angelo Dureghello Date: Fri, 2 Oct 2020 16:05:45 +0200 Subject: [PATCH 79/79] serial: mcf: add sysrq capability After some unsuccessful attempts to use sysrq over console, figured out that port->has_sysrq should likely be enabled, as per other architectures, this when CONFIG_SERIAL_MCF_CONSOLE is also enabled. Tested some magic sysrq commands (h, p, t, b), they works now properly. Commands works inside 5 secs after BREAK is sent, as expected. Signed-off-by: Angelo Dureghello Link: https://lore.kernel.org/r/20201002140545.477481-1-angelo.dureghello@timesys.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mcf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index 7dbfb4cde124..09c88c48fb7b 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -632,6 +632,7 @@ static int mcf_probe(struct platform_device *pdev) port->ops = &mcf_uart_ops; port->flags = UPF_BOOT_AUTOCONF; port->rs485_config = mcf_config_rs485; + port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MCF_CONSOLE); uart_add_one_port(&mcf_driver, port); }