diff -Naur old/arch/ppc/8xx_io/uart.c new/arch/ppc/8xx_io/uart.c --- old/arch/ppc/8xx_io/uart.c Wed Feb 16 10:43:24 2005 +++ new/arch/ppc/8xx_io/uart.c Wed Feb 16 10:42:01 2005 @@ -119,6 +119,11 @@ static int uart_buf_read_proc (char *, char **, off_t, int, int *, void *); #endif +#ifdef CONFIG_SERIAL_CONSOLE +static void full_seq_smc_stop (int port); +static void smc_init_rx_tx (int port); +#endif + /* * Serial driver configuration section. Here are the various options: */ @@ -831,10 +836,17 @@ else { smcp = &cpmp->cp_smc[idx]; +#ifdef CONFIG_SERIAL_CONSOLE + /* stop SMC in the correct way, before re-configuring it + */ + if (((state - rs_table) == CONFIG_SERIAL_CONSOLE_PORT)){ + full_seq_smc_stop(PORT_NUM(info->state->smc_scc_num)); + } +#endif + /* Enable interrupts and I/O. */ smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); /* We can tune the buffer length and idle characters * to take advantage of the entire incoming buffer size. @@ -848,6 +860,17 @@ up->smc_mrblr = RX_BUF_SIZE; up->smc_maxidl = RX_BUF_SIZE; up->smc_brkcr = 1; /* number of break chars */ + +#ifdef CONFIG_SERIAL_CONSOLE + if (((state - rs_table) == CONFIG_SERIAL_CONSOLE_PORT)){ + + smc_init_rx_tx(PORT_NUM(info->state->smc_scc_num)); + info->rx_cur = info->rx_bd_base; + info->tx_cur = info->tx_bd_base; + } +#endif + + smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); } info->flags |= ASYNC_INITIALIZED; @@ -2694,6 +2717,46 @@ } /* end uart_removeProcEntries() */ + +#ifdef CONFIG_SERIAL_CONSOLE +static void full_seq_smc_stop (int port) +{ + volatile cpm8xx_t *cp=cpmp; + volatile smc_t *sp; + ushort chan; + unsigned long flags; + + sp = &cp->cp_smc[port]; + chan = smc_chan_map[port]; + + local_irq_save(flags); + + while (cp->cp_cpcr & CPM_CR_FLG); + cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + + local_irq_restore(flags); + +} /* full_seq_smc_stop */ + +static void smc_init_rx_tx (int port) +{ + unsigned long flags; + volatile cpm8xx_t *cp=cpmp; + ushort chan; + + chan = smc_chan_map[port]; + + local_irq_save(flags); + while (cp->cp_cpcr & CPM_CR_FLG); + cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + local_irq_restore(flags); + +} /* smc_init_rx_tx */ +#endif /* CONFIG_SERIAL_CONSOLE */ + /* * The serial driver boot-time initialization code! */ @@ -2905,6 +2968,15 @@ } else { sp = &cp->cp_smc[idx]; + +#ifdef CONFIG_SERIAL_CONSOLE + /* stop SMC in the correct way, before re-configuring it + */ + if (i == CONFIG_SERIAL_CONSOLE_PORT){ + full_seq_smc_stop(idx); + } +#endif + up = (smc_uart_t *)&cp->cp_dparam[state->port]; up->smc_rbase = dp_addr; }