Skip to content

Commit

Permalink
Merge tag 'tty-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/gregkh/tty

Pull tty/serial updates from Greg KH:
 "Here is the large set of TTY and Serial driver patches for 5.9-rc1.

  Lots of bugfixes in here, thanks to syzbot fuzzing for serial and vt
  and console code.

  Other highlights include:

   - much needed vt/vc code cleanup from Jiri Slaby

   - 8250 driver fixes and additions

   - various serial driver updates and feature enhancements

   - locking cleanup for serial/console initializations

   - other minor cleanups

  All of these have been in linux-next with no reported issues"

* tag 'tty-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (90 commits)
  MAINTAINERS: enlist Greg formally for console stuff
  vgacon: Fix for missing check in scrollback handling
  Revert "serial: 8250: Let serial core initialise spin lock"
  serial: 8250: Let serial core initialise spin lock
  tty: keyboard, do not speculate on func_table index
  serial: stm32: Add RS485 RTS GPIO control
  serial: 8250_dw: Fix common clocks usage race condition
  serial: 8250_dw: Pass the same rate to the clk round and set rate methods
  serial: 8250_dw: Simplify the ref clock rate setting procedure
  serial: 8250: Add 8250 port clock update method
  tty: serial: imx: add imx earlycon driver
  tty: serial: imx: enable imx serial console port as module
  tty/synclink: remove leftover bits of non-PCI card support
  tty: Use the preferred form for passing the size of a structure type
  tty: Fix identation issues in struct serial_struct32
  tty: Avoid the use of one-element arrays
  serial: msm_serial: add sparse context annotation
  serial: pmac_zilog: add sparse context annotation
  newport_con: vc_color is now in state
  serial: imx: use hrtimers for rs485 delays
  ...
  • Loading branch information
torvalds committed Aug 6, 2020
2 parents c0c419c + f6c6eb2 commit d6efb3a
Show file tree
Hide file tree
Showing 63 changed files with 1,847 additions and 1,613 deletions.
4 changes: 3 additions & 1 deletion Documentation/devicetree/bindings/serial/st,stm32-uart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ properties:
description: label associated with this uart

st,hw-flow-ctrl:
description: enable hardware flow control
description: enable hardware flow control (deprecated)
$ref: /schemas/types.yaml#/definitions/flag

uart-has-rtscts: true

dmas:
minItems: 1
maxItems: 2
Expand Down
2 changes: 1 addition & 1 deletion Documentation/driver-api/serial/n_gsm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ GSM 0710 tty multiplexor HOWTO
This line discipline implements the GSM 07.10 multiplexing protocol
detailed in the following 3GPP document:

http://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
https://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip

This document give some hints on how to use this driver with GPRS and 3G
modems connected to a physical serial port.
Expand Down
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4386,6 +4386,12 @@ L: [email protected]
S: Maintained
F: drivers/connector/

CONSOLE SUBSYSTEM
M: Greg Kroah-Hartman <[email protected]>
S: Supported
F: drivers/video/console/
F: include/linux/console*

CONTROL GROUP (CGROUP)
M: Tejun Heo <[email protected]>
M: Li Zefan <[email protected]>
Expand Down
5 changes: 0 additions & 5 deletions arch/um/drivers/line.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,6 @@ void line_flush_chars(struct tty_struct *tty)
line_flush_buffer(tty);
}

int line_put_char(struct tty_struct *tty, unsigned char ch)
{
return line_write(tty, &ch, sizeof(ch));
}

int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
{
struct line *line = tty->driver_data;
Expand Down
1 change: 0 additions & 1 deletion arch/um/drivers/line.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ extern int line_setup(char **conf, unsigned nlines, char **def,
char *init, char *name);
extern int line_write(struct tty_struct *tty, const unsigned char *buf,
int len);
extern int line_put_char(struct tty_struct *tty, unsigned char ch);
extern void line_set_termios(struct tty_struct *tty, struct ktermios * old);
extern int line_chars_in_buffer(struct tty_struct *tty);
extern void line_flush_buffer(struct tty_struct *tty);
Expand Down
1 change: 0 additions & 1 deletion arch/um/drivers/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ static const struct tty_operations ssl_ops = {
.open = line_open,
.close = line_close,
.write = line_write,
.put_char = line_put_char,
.write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer,
.flush_buffer = line_flush_buffer,
Expand Down
1 change: 0 additions & 1 deletion arch/um/drivers/stdio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ static const struct tty_operations console_ops = {
.install = con_install,
.close = line_close,
.write = line_write,
.put_char = line_put_char,
.write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer,
.flush_buffer = line_flush_buffer,
Expand Down
10 changes: 5 additions & 5 deletions drivers/accessibility/braille/braille_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,16 @@ static void braille_write(u16 *buf)
/* Follow the VC cursor*/
static void vc_follow_cursor(struct vc_data *vc)
{
vc_x = vc->vc_x - (vc->vc_x % WIDTH);
vc_y = vc->vc_y;
lastvc_x = vc->vc_x;
lastvc_y = vc->vc_y;
vc_x = vc->state.x - (vc->state.x % WIDTH);
vc_y = vc->state.y;
lastvc_x = vc->state.x;
lastvc_y = vc->state.y;
}

/* Maybe the VC cursor moved, if so follow it */
static void vc_maybe_cursor_moved(struct vc_data *vc)
{
if (vc->vc_x != lastvc_x || vc->vc_y != lastvc_y)
if (vc->state.x != lastvc_x || vc->state.y != lastvc_y)
vc_follow_cursor(vc);
}

Expand Down
28 changes: 14 additions & 14 deletions drivers/accessibility/speakup/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ static unsigned char get_attributes(struct vc_data *vc, u16 *pos)

static void speakup_date(struct vc_data *vc)
{
spk_x = spk_cx = vc->vc_x;
spk_y = spk_cy = vc->vc_y;
spk_x = spk_cx = vc->state.x;
spk_y = spk_cy = vc->state.y;
spk_pos = spk_cp = vc->vc_pos;
spk_old_attr = spk_attr;
spk_attr = get_attributes(vc, (u_short *)spk_pos);
Expand Down Expand Up @@ -1551,9 +1551,9 @@ static void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag)
*/
is_cursor = value + 1;
old_cursor_pos = vc->vc_pos;
old_cursor_x = vc->vc_x;
old_cursor_y = vc->vc_y;
speakup_console[vc->vc_num]->ht.cy = vc->vc_y;
old_cursor_x = vc->state.x;
old_cursor_y = vc->state.y;
speakup_console[vc->vc_num]->ht.cy = vc->state.y;
cursor_con = vc->vc_num;
if (cursor_track == CT_Highlight)
reset_highlight_buffers(vc);
Expand All @@ -1574,8 +1574,8 @@ static void update_color_buffer(struct vc_data *vc, const u16 *ic, int len)
i = 0;
if (speakup_console[vc_num]->ht.highsize[bi] == 0) {
speakup_console[vc_num]->ht.rpos[bi] = vc->vc_pos;
speakup_console[vc_num]->ht.rx[bi] = vc->vc_x;
speakup_console[vc_num]->ht.ry[bi] = vc->vc_y;
speakup_console[vc_num]->ht.rx[bi] = vc->state.x;
speakup_console[vc_num]->ht.ry[bi] = vc->state.y;
}
while ((hi < COLOR_BUFFER_SIZE) && (i < len)) {
if (ic[i] > 32) {
Expand Down Expand Up @@ -1664,9 +1664,9 @@ static int speak_highlight(struct vc_data *vc)
return 0;
hc = get_highlight_color(vc);
if (hc != -1) {
d = vc->vc_y - speakup_console[vc_num]->ht.cy;
d = vc->state.y - speakup_console[vc_num]->ht.cy;
if ((d == 1) || (d == -1))
if (speakup_console[vc_num]->ht.ry[hc] != vc->vc_y)
if (speakup_console[vc_num]->ht.ry[hc] != vc->state.y)
return 0;
spk_parked |= 0x01;
spk_do_flush();
Expand All @@ -1693,8 +1693,8 @@ static void cursor_done(struct timer_list *unused)
}
speakup_date(vc);
if (win_enabled) {
if (vc->vc_x >= win_left && vc->vc_x <= win_right &&
vc->vc_y >= win_top && vc->vc_y <= win_bottom) {
if (vc->state.x >= win_left && vc->state.x <= win_right &&
vc->state.y >= win_top && vc->state.y <= win_bottom) {
spk_keydown = 0;
is_cursor = 0;
goto out;
Expand Down Expand Up @@ -1757,7 +1757,7 @@ static void speakup_con_write(struct vc_data *vc, u16 *str, int len)
if (!spin_trylock_irqsave(&speakup_info.spinlock, flags))
/* Speakup output, discard */
return;
if (spk_bell_pos && spk_keydown && (vc->vc_x == spk_bell_pos - 1))
if (spk_bell_pos && spk_keydown && (vc->state.x == spk_bell_pos - 1))
bleep(3);
if ((is_cursor) || (cursor_track == read_all_mode)) {
if (cursor_track == CT_Highlight)
Expand All @@ -1766,8 +1766,8 @@ static void speakup_con_write(struct vc_data *vc, u16 *str, int len)
return;
}
if (win_enabled) {
if (vc->vc_x >= win_left && vc->vc_x <= win_right &&
vc->vc_y >= win_top && vc->vc_y <= win_bottom) {
if (vc->state.x >= win_left && vc->state.x <= win_right &&
vc->state.y >= win_top && vc->state.y <= win_bottom) {
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/moxa.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
#define IntrQuit 0x40 /* received QUIT code */
#define IntrEOF 0x80 /* received EOF code */

#define IntrRxTrigger 0x100 /* rx data count reach tigger value */
#define IntrRxTrigger 0x100 /* rx data count reach trigger value */
#define IntrTxTrigger 0x200 /* tx data count below trigger value */

#define Magic_no (Config_base + 0)
Expand Down
120 changes: 106 additions & 14 deletions drivers/tty/serial/8250/8250_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/clk.h>
Expand All @@ -43,6 +45,8 @@ struct dw8250_data {
int msr_mask_off;
struct clk *clk;
struct clk *pclk;
struct notifier_block clk_notifier;
struct work_struct clk_work;
struct reset_control *rst;

unsigned int skip_autocfg:1;
Expand All @@ -54,6 +58,16 @@ static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
return container_of(data, struct dw8250_data, data);
}

static inline struct dw8250_data *clk_to_dw8250_data(struct notifier_block *nb)
{
return container_of(nb, struct dw8250_data, clk_notifier);
}

static inline struct dw8250_data *work_to_dw8250_data(struct work_struct *work)
{
return container_of(work, struct dw8250_data, clk_work);
}

static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
{
struct dw8250_data *d = to_dw8250_data(p->private_data);
Expand Down Expand Up @@ -260,6 +274,46 @@ static int dw8250_handle_irq(struct uart_port *p)
return 0;
}

static void dw8250_clk_work_cb(struct work_struct *work)
{
struct dw8250_data *d = work_to_dw8250_data(work);
struct uart_8250_port *up;
unsigned long rate;

rate = clk_get_rate(d->clk);
if (rate <= 0)
return;

up = serial8250_get_port(d->data.line);

serial8250_update_uartclk(&up->port, rate);
}

static int dw8250_clk_notifier_cb(struct notifier_block *nb,
unsigned long event, void *data)
{
struct dw8250_data *d = clk_to_dw8250_data(nb);

/*
* We have no choice but to defer the uartclk update due to two
* deadlocks. First one is caused by a recursive mutex lock which
* happens when clk_set_rate() is called from dw8250_set_termios().
* Second deadlock is more tricky and is caused by an inverted order of
* the clk and tty-port mutexes lock. It happens if clock rate change
* is requested asynchronously while set_termios() is executed between
* tty-port mutex lock and clk_set_rate() function invocation and
* vise-versa. Anyway if we didn't have the reference clock alteration
* in the dw8250_set_termios() method we wouldn't have needed this
* deferred event handling complication.
*/
if (event == POST_RATE_CHANGE) {
queue_work(system_unbound_wq, &d->clk_work);
return NOTIFY_OK;
}

return NOTIFY_DONE;
}

static void
dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
{
Expand All @@ -275,27 +329,27 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
struct ktermios *old)
{
unsigned int baud = tty_termios_baud_rate(termios);
unsigned long newrate = tty_termios_baud_rate(termios) * 16;
struct dw8250_data *d = to_dw8250_data(p->private_data);
long rate;
int ret;

clk_disable_unprepare(d->clk);
rate = clk_round_rate(d->clk, baud * 16);
if (rate < 0)
ret = rate;
else if (rate == 0)
ret = -ENOENT;
else
ret = clk_set_rate(d->clk, rate);
rate = clk_round_rate(d->clk, newrate);
if (rate > 0) {
/*
* Premilinary set the uartclk to the new clock rate so the
* clock update event handler caused by the clk_set_rate()
* calling wouldn't actually update the UART divisor since
* we about to do this anyway.
*/
swap(p->uartclk, rate);
ret = clk_set_rate(d->clk, newrate);
if (ret)
swap(p->uartclk, rate);
}
clk_prepare_enable(d->clk);

if (ret)
goto out;

p->uartclk = rate;

out:
p->status &= ~UPSTAT_AUTOCTS;
if (termios->c_cflag & CRTSCTS)
p->status |= UPSTAT_AUTOCTS;
Expand All @@ -319,6 +373,39 @@ 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
Expand Down Expand Up @@ -414,6 +501,8 @@ 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)
Expand Down Expand Up @@ -475,6 +564,9 @@ static int dw8250_probe(struct platform_device *pdev)
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);

INIT_WORK(&data->clk_work, dw8250_clk_work_cb);
data->clk_notifier.notifier_call = dw8250_clk_notifier_cb;

err = clk_prepare_enable(data->clk);
if (err)
dev_warn(dev, "could not enable optional baudclk: %d\n", err);
Expand Down
16 changes: 10 additions & 6 deletions drivers/tty/serial/8250/8250_em.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,18 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value)

static int serial8250_em_probe(struct platform_device *pdev)
{
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
struct serial8250_em_priv *priv;
struct uart_8250_port up;
int ret;
struct resource *regs;
int irq, ret;

if (!regs || !irq) {
dev_err(&pdev->dev, "missing registers or irq\n");
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;

regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&pdev->dev, "missing registers\n");
return -EINVAL;
}

Expand All @@ -101,7 +105,7 @@ static int serial8250_em_probe(struct platform_device *pdev)

memset(&up, 0, sizeof(up));
up.port.mapbase = regs->start;
up.port.irq = irq->start;
up.port.irq = irq;
up.port.type = PORT_UNKNOWN;
up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP;
up.port.dev = &pdev->dev;
Expand Down
Loading

0 comments on commit d6efb3a

Please sign in to comment.