diff options
author | Nye Liu <nyet@mrv.com> | 2008-07-24 00:29:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:30 -0400 |
commit | ae2d4c396e19f45918ed6e0900b031538d009823 (patch) | |
tree | 809061b816c0ef3a724df8c7369632fb2dda58cd | |
parent | e9a8f4d1de12633bfb71b5fee47745b32877b7b5 (diff) |
cpm1: don't send break on TX_STOP, don't interrupt RX/TX when adjusting termios parameters
Before setting STOP_TX, set _brkcr to 0 so the SMC does not send a break
character. The driver appears to properly re-initialize _brkcr when the
SMC is restarted.
Do not interrupt RX/TX when the termios is being adjusted; it results in
corrupted characters appearing on the line.
Cc: Vitaly Bordug <vbordug@ru.mvista.com>
Cc: Scott Wood <scottwood@freescale.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_core.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 1ff80de177db..a4f86927a74b 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -435,10 +435,13 @@ static void cpm_uart_shutdown(struct uart_port *port) | |||
435 | } | 435 | } |
436 | 436 | ||
437 | /* Shut them really down and reinit buffer descriptors */ | 437 | /* Shut them really down and reinit buffer descriptors */ |
438 | if (IS_SMC(pinfo)) | 438 | if (IS_SMC(pinfo)) { |
439 | out_be16(&pinfo->smcup->smc_brkcr, 0); | ||
439 | cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); | 440 | cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); |
440 | else | 441 | } else { |
442 | out_be16(&pinfo->sccup->scc_brkcr, 0); | ||
441 | cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); | 443 | cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); |
444 | } | ||
442 | 445 | ||
443 | cpm_uart_initbd(pinfo); | 446 | cpm_uart_initbd(pinfo); |
444 | } | 447 | } |
@@ -554,9 +557,11 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
554 | * enables, because we want to put them back if they were | 557 | * enables, because we want to put them back if they were |
555 | * present. | 558 | * present. |
556 | */ | 559 | */ |
557 | prev_mode = in_be16(&smcp->smc_smcmr); | 560 | prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN); |
558 | out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART); | 561 | /* Output in *one* operation, so we don't interrupt RX/TX if they |
559 | setbits16(&smcp->smc_smcmr, (prev_mode & (SMCMR_REN | SMCMR_TEN))); | 562 | * were already enabled. */ |
563 | out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | | ||
564 | SMCMR_SM_UART | prev_mode); | ||
560 | } else { | 565 | } else { |
561 | out_be16(&sccp->scc_psmr, (sbits << 12) | scval); | 566 | out_be16(&sccp->scc_psmr, (sbits << 12) | scval); |
562 | } | 567 | } |
@@ -1198,12 +1203,14 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
1198 | udbg_putc = NULL; | 1203 | udbg_putc = NULL; |
1199 | #endif | 1204 | #endif |
1200 | 1205 | ||
1201 | cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); | ||
1202 | |||
1203 | if (IS_SMC(pinfo)) { | 1206 | if (IS_SMC(pinfo)) { |
1207 | out_be16(&pinfo->smcup->smc_brkcr, 0); | ||
1208 | cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); | ||
1204 | clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); | 1209 | clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); |
1205 | clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); | 1210 | clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); |
1206 | } else { | 1211 | } else { |
1212 | out_be16(&pinfo->sccup->scc_brkcr, 0); | ||
1213 | cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); | ||
1207 | clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); | 1214 | clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); |
1208 | clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 1215 | clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
1209 | } | 1216 | } |