Skip to content

Commit

Permalink
Fix problems with TCR register access
Browse files Browse the repository at this point in the history
Per SC16IS752/762 manual Table 10, MCR and TCR are part of the General register set, which is "accessible only when LCR[7] = logic 0."  Therefore, clear bit 7 of LCR before attempting to write MCR (to enable access to TCR), and TCR (to set flow control thresholds).

Additionally, this function was leaving the register set in TCR/TLR mode.  Turn that off after writing TCR.

Note that it's also leaving the EFR_ENABLE bit set, but that's also done in a couple other places, so I left it be.

I am not sure the `regcache_cache_bypass(s->regmap, false);` is in the right place, someone in the know should check that.
  • Loading branch information
StephenWall committed Jan 23, 2023
1 parent 2475bf0 commit 7a9c8f2
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions drivers/tty/serial/sc16is7xx.c
Expand Up @@ -1173,6 +1173,10 @@ static int sc16is7xx_startup(struct uart_port *port)
SC16IS7XX_EFR_ENABLE_BIT,
SC16IS7XX_EFR_ENABLE_BIT);

/* Set word length to 8 bits. */
/* This also clears Divisor Latch bit, returning registers to normal mode. */
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8);

/* Enable TCR/TLR */
sc16is7xx_port_update(port, SC16IS7XX_MCR_REG,
SC16IS7XX_MCR_TCRTLR_BIT,
Expand All @@ -1184,10 +1188,12 @@ static int sc16is7xx_startup(struct uart_port *port)
SC16IS7XX_TCR_RX_RESUME(24) |
SC16IS7XX_TCR_RX_HALT(48));

regcache_cache_bypass(s->regmap, false);
/* Disable TCR/TLR */
sc16is7xx_port_update(port, SC16IS7XX_MCR_REG,
SC16IS7XX_MCR_TCRTLR_BIT,
~SC16IS7XX_MCR_TCRTLR_BIT);

/* Now, initialize the UART */
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8);
regcache_cache_bypass(s->regmap, false);

/* Enable IrDA mode if requested in DT */
/* This bit must be written with LCR[7] = 0 */
Expand Down

0 comments on commit 7a9c8f2

Please sign in to comment.