diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c index 3fab1c377a80..ba060d0ceca2 100644 --- a/drivers/staging/speakup/serialio.c +++ b/drivers/staging/speakup/serialio.c @@ -26,8 +26,13 @@ static const struct old_serial_port *serstate; static int timeouts; static int spk_serial_out(struct spk_synth *in_synth, const char ch); +static void spk_serial_send_xchar(char ch); +static void spk_serial_tiocmset(unsigned int set, unsigned int clear); + struct spk_io_ops spk_serial_io_ops = { .synth_out = spk_serial_out, + .send_xchar = spk_serial_send_xchar, + .tiocmset = spk_serial_tiocmset, }; EXPORT_SYMBOL_GPL(spk_serial_io_ops); @@ -136,6 +141,24 @@ static void start_serial_interrupt(int irq) outb(1, speakup_info.port_tts + UART_FCR); /* Turn FIFO On */ } +static void spk_serial_send_xchar(char ch) +{ + int timeout = SPK_XMITR_TIMEOUT; + + while (spk_serial_tx_busy()) { + if (!--timeout) + break; + udelay(1); + } + outb(ch, speakup_info.port_tts); +} + +static void spk_serial_tiocmset(unsigned int set, unsigned int clear) +{ + int old = inb(speakup_info.port_tts + UART_MCR); + outb((old & ~clear) | set, speakup_info.port_tts + UART_MCR); +} + int spk_serial_synth_probe(struct spk_synth *synth) { const struct old_serial_port *ser; diff --git a/drivers/staging/speakup/speakup_apollo.c b/drivers/staging/speakup/speakup_apollo.c index 6ad83dc642c4..cead8b1b1bfc 100644 --- a/drivers/staging/speakup/speakup_apollo.c +++ b/drivers/staging/speakup/speakup_apollo.c @@ -171,9 +171,8 @@ static void do_catch_up(struct spk_synth *synth) full_time_val = full_time->u.n.value; spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (!synth->io_ops->synth_out(synth, ch)) { - outb(UART_MCR_DTR, speakup_info.port_tts + UART_MCR); - outb(UART_MCR_DTR | UART_MCR_RTS, - speakup_info.port_tts + UART_MCR); + synth->io_ops->tiocmset(0, UART_MCR_RTS); + synth->io_ops->tiocmset(UART_MCR_RTS, 0); schedule_timeout(msecs_to_jiffies(full_time_val)); continue; } diff --git a/drivers/staging/speakup/speakup_audptr.c b/drivers/staging/speakup/speakup_audptr.c index da3fd94a6ad9..6880352a7b74 100644 --- a/drivers/staging/speakup/speakup_audptr.c +++ b/drivers/staging/speakup/speakup_audptr.c @@ -128,14 +128,7 @@ static struct spk_synth synth_audptr = { static void synth_flush(struct spk_synth *synth) { - int timeout = SPK_XMITR_TIMEOUT; - - while (spk_serial_tx_busy()) { - if (!--timeout) - break; - udelay(1); - } - outb(SYNTH_CLEAR, speakup_info.port_tts); + synth->io_ops->send_xchar(SYNTH_CLEAR); synth->io_ops->synth_out(synth, PROCSPEECH); } diff --git a/drivers/staging/speakup/speakup_spkout.c b/drivers/staging/speakup/speakup_spkout.c index d08ddc110f57..d95c375a0736 100644 --- a/drivers/staging/speakup/speakup_spkout.c +++ b/drivers/staging/speakup/speakup_spkout.c @@ -126,14 +126,7 @@ static struct spk_synth synth_spkout = { static void synth_flush(struct spk_synth *synth) { - int timeout = SPK_XMITR_TIMEOUT; - - while (spk_serial_tx_busy()) { - if (!--timeout) - break; - udelay(1); - } - outb(SYNTH_CLEAR, speakup_info.port_tts); + synth->io_ops->send_xchar(SYNTH_CLEAR); } module_param_named(ser, synth_spkout.ser, int, 0444); diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h index a446064b6c91..c156975392c8 100644 --- a/drivers/staging/speakup/spk_types.h +++ b/drivers/staging/speakup/spk_types.h @@ -150,6 +150,8 @@ struct spk_synth; struct spk_io_ops { int (*synth_out)(struct spk_synth *synth, const char ch); + void (*send_xchar)(char ch); + void (*tiocmset)(unsigned int set, unsigned int clear); }; struct spk_synth {