You need to sign in or sign up before continuing.
提交 c03c3719 编写于 作者: P Phil Elwell 提交者: Zheng Zengkai

sc16is7xx: Fix for hardware flow control

raspberrypi inclusion
category: feature
bugzilla: 50432

--------------------------------

The SC16IS7XX hardware flow control is mishandled by the driver in
a number of ways:

  1. The set_baud method accidentally clears it when setting EFR bit.
  2. Even though hardware flow control is enabled, it isn't indicated
     back to the serial framework.
  3. Applying the flow control clears the EFR bit.
  4. The CTS support is not indicated in the return from
     sc16is7xx_get_mctrl.

Address all of those issues using a mixture of patches found on the
linked pages.

See: https://github.com/raspberrypi/linux/issues/2542
See: https://www.spinics.net/lists/linux-serial/msg21794.htmlSigned-off-by: NPhil Elwell <phil@raspberrypi.com>
Signed-off-by: NFang Yafen <yafen@iscas.ac.cn>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 98a2f008
...@@ -523,8 +523,9 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) ...@@ -523,8 +523,9 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
/* Enable enhanced features */ /* Enable enhanced features */
regcache_cache_bypass(s->regmap, true); regcache_cache_bypass(s->regmap, true);
sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, sc16is7xx_port_update(port, SC16IS7XX_EFR_REG,
SC16IS7XX_EFR_ENABLE_BIT); SC16IS7XX_EFR_ENABLE_BIT,
SC16IS7XX_EFR_ENABLE_BIT);
regcache_cache_bypass(s->regmap, false); regcache_cache_bypass(s->regmap, false);
/* Put LCR back to the normal mode */ /* Put LCR back to the normal mode */
...@@ -839,7 +840,7 @@ static unsigned int sc16is7xx_get_mctrl(struct uart_port *port) ...@@ -839,7 +840,7 @@ static unsigned int sc16is7xx_get_mctrl(struct uart_port *port)
/* DCD and DSR are not wired and CTS/RTS is handled automatically /* DCD and DSR are not wired and CTS/RTS is handled automatically
* so just indicate DSR and CAR asserted * so just indicate DSR and CAR asserted
*/ */
return TIOCM_DSR | TIOCM_CAR; return TIOCM_DSR | TIOCM_CAR | TIOCM_RI | TIOCM_CTS;
} }
static void sc16is7xx_set_mctrl(struct uart_port *port, unsigned int mctrl) static void sc16is7xx_set_mctrl(struct uart_port *port, unsigned int mctrl)
...@@ -926,14 +927,19 @@ static void sc16is7xx_set_termios(struct uart_port *port, ...@@ -926,14 +927,19 @@ static void sc16is7xx_set_termios(struct uart_port *port,
regcache_cache_bypass(s->regmap, true); regcache_cache_bypass(s->regmap, true);
sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]); sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]);
sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]); sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]);
if (termios->c_cflag & CRTSCTS) if (termios->c_cflag & CRTSCTS) {
flow |= SC16IS7XX_EFR_AUTOCTS_BIT | flow |= SC16IS7XX_EFR_AUTOCTS_BIT |
SC16IS7XX_EFR_AUTORTS_BIT; SC16IS7XX_EFR_AUTORTS_BIT;
port->status |= UPSTAT_AUTOCTS;
};
if (termios->c_iflag & IXON) if (termios->c_iflag & IXON)
flow |= SC16IS7XX_EFR_SWFLOW3_BIT; flow |= SC16IS7XX_EFR_SWFLOW3_BIT;
if (termios->c_iflag & IXOFF) if (termios->c_iflag & IXOFF)
flow |= SC16IS7XX_EFR_SWFLOW1_BIT; flow |= SC16IS7XX_EFR_SWFLOW1_BIT;
/* Always set enable enhanced */
flow |= SC16IS7XX_EFR_ENABLE_BIT;
sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, flow); sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, flow);
regcache_cache_bypass(s->regmap, false); regcache_cache_bypass(s->regmap, false);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册