diff options
Diffstat (limited to 'drivers/tty/serial/sccnxp.c')
| -rw-r--r-- | drivers/tty/serial/sccnxp.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index c0a68eee4479..68a24a14f6b7 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c | |||
| @@ -48,7 +48,6 @@ | |||
| 48 | # define MR2_STOP1 (7 << 0) | 48 | # define MR2_STOP1 (7 << 0) |
| 49 | # define MR2_STOP2 (0xf << 0) | 49 | # define MR2_STOP2 (0xf << 0) |
| 50 | #define SCCNXP_SR_REG (0x01) | 50 | #define SCCNXP_SR_REG (0x01) |
| 51 | #define SCCNXP_CSR_REG SCCNXP_SR_REG | ||
| 52 | # define SR_RXRDY (1 << 0) | 51 | # define SR_RXRDY (1 << 0) |
| 53 | # define SR_FULL (1 << 1) | 52 | # define SR_FULL (1 << 1) |
| 54 | # define SR_TXRDY (1 << 2) | 53 | # define SR_TXRDY (1 << 2) |
| @@ -57,6 +56,8 @@ | |||
| 57 | # define SR_PE (1 << 5) | 56 | # define SR_PE (1 << 5) |
| 58 | # define SR_FE (1 << 6) | 57 | # define SR_FE (1 << 6) |
| 59 | # define SR_BRK (1 << 7) | 58 | # define SR_BRK (1 << 7) |
| 59 | #define SCCNXP_CSR_REG (SCCNXP_SR_REG) | ||
| 60 | # define CSR_TIMER_MODE (0x0d) | ||
| 60 | #define SCCNXP_CR_REG (0x02) | 61 | #define SCCNXP_CR_REG (0x02) |
| 61 | # define CR_RX_ENABLE (1 << 0) | 62 | # define CR_RX_ENABLE (1 << 0) |
| 62 | # define CR_RX_DISABLE (1 << 1) | 63 | # define CR_RX_DISABLE (1 << 1) |
| @@ -83,9 +84,12 @@ | |||
| 83 | # define IMR_RXRDY (1 << 1) | 84 | # define IMR_RXRDY (1 << 1) |
| 84 | # define ISR_TXRDY(x) (1 << ((x * 4) + 0)) | 85 | # define ISR_TXRDY(x) (1 << ((x * 4) + 0)) |
| 85 | # define ISR_RXRDY(x) (1 << ((x * 4) + 1)) | 86 | # define ISR_RXRDY(x) (1 << ((x * 4) + 1)) |
| 87 | #define SCCNXP_CTPU_REG (0x06) | ||
| 88 | #define SCCNXP_CTPL_REG (0x07) | ||
| 86 | #define SCCNXP_IPR_REG (0x0d) | 89 | #define SCCNXP_IPR_REG (0x0d) |
| 87 | #define SCCNXP_OPCR_REG SCCNXP_IPR_REG | 90 | #define SCCNXP_OPCR_REG SCCNXP_IPR_REG |
| 88 | #define SCCNXP_SOP_REG (0x0e) | 91 | #define SCCNXP_SOP_REG (0x0e) |
| 92 | #define SCCNXP_START_COUNTER_REG SCCNXP_SOP_REG | ||
| 89 | #define SCCNXP_ROP_REG (0x0f) | 93 | #define SCCNXP_ROP_REG (0x0f) |
| 90 | 94 | ||
| 91 | /* Route helpers */ | 95 | /* Route helpers */ |
| @@ -255,7 +259,7 @@ static int sccnxp_update_best_err(int a, int b, int *besterr) | |||
| 255 | { | 259 | { |
| 256 | int err = abs(a - b); | 260 | int err = abs(a - b); |
| 257 | 261 | ||
| 258 | if ((*besterr < 0) || (*besterr > err)) { | 262 | if (*besterr > err) { |
| 259 | *besterr = err; | 263 | *besterr = err; |
| 260 | return 0; | 264 | return 0; |
| 261 | } | 265 | } |
| @@ -303,10 +307,22 @@ static const struct { | |||
| 303 | static int sccnxp_set_baud(struct uart_port *port, int baud) | 307 | static int sccnxp_set_baud(struct uart_port *port, int baud) |
| 304 | { | 308 | { |
| 305 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 309 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
| 306 | int div_std, tmp_baud, bestbaud = baud, besterr = -1; | 310 | int div_std, tmp_baud, bestbaud = INT_MAX, besterr = INT_MAX; |
| 307 | struct sccnxp_chip *chip = s->chip; | 311 | struct sccnxp_chip *chip = s->chip; |
| 308 | u8 i, acr = 0, csr = 0, mr0 = 0; | 312 | u8 i, acr = 0, csr = 0, mr0 = 0; |
| 309 | 313 | ||
| 314 | /* Find divisor to load to the timer preset registers */ | ||
| 315 | div_std = DIV_ROUND_CLOSEST(port->uartclk, 2 * 16 * baud); | ||
| 316 | if ((div_std >= 2) && (div_std <= 0xffff)) { | ||
| 317 | bestbaud = DIV_ROUND_CLOSEST(port->uartclk, 2 * 16 * div_std); | ||
| 318 | sccnxp_update_best_err(baud, bestbaud, &besterr); | ||
| 319 | csr = CSR_TIMER_MODE; | ||
| 320 | sccnxp_port_write(port, SCCNXP_CTPU_REG, div_std >> 8); | ||
| 321 | sccnxp_port_write(port, SCCNXP_CTPL_REG, div_std); | ||
| 322 | /* Issue start timer/counter command */ | ||
| 323 | sccnxp_port_read(port, SCCNXP_START_COUNTER_REG); | ||
| 324 | } | ||
| 325 | |||
| 310 | /* Find best baud from table */ | 326 | /* Find best baud from table */ |
| 311 | for (i = 0; baud_std[i].baud && besterr; i++) { | 327 | for (i = 0; baud_std[i].baud && besterr; i++) { |
| 312 | if (baud_std[i].mr0 && !(chip->flags & SCCNXP_HAVE_MR0)) | 328 | if (baud_std[i].mr0 && !(chip->flags & SCCNXP_HAVE_MR0)) |
