aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/21285.c14
-rw-r--r--drivers/serial/8250.c32
-rw-r--r--drivers/serial/amba-pl010.c14
-rw-r--r--drivers/serial/amba-pl011.c14
-rw-r--r--drivers/serial/clps711x.c5
-rw-r--r--drivers/serial/pxa.c16
-rw-r--r--drivers/serial/s3c2410.c15
-rw-r--r--drivers/serial/sa1100.c5
-rw-r--r--drivers/serial/serial_cs.c4
-rw-r--r--drivers/serial/serial_lh7a40x.c13
-rw-r--r--drivers/serial/serial_txx9.c15
-rw-r--r--drivers/serial/sunsab.c109
-rw-r--r--drivers/serial/sunsab.h1
-rw-r--r--drivers/serial/vr41xx_siu.c6
14 files changed, 108 insertions, 155 deletions
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 33fbda79f350..0b10169961eb 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -126,18 +126,8 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *r
126 flag = TTY_FRAME; 126 flag = TTY_FRAME;
127 } 127 }
128 128
129 if ((rxs & port->ignore_status_mask) == 0) { 129 uart_insert_char(port, rxs, RXSTAT_OVERRUN, ch, flag);
130 tty_insert_flip_char(tty, ch, flag); 130
131 }
132 if ((rxs & RXSTAT_OVERRUN) &&
133 tty->flip.count < TTY_FLIPBUF_SIZE) {
134 /*
135 * Overrun is special, since it's reported
136 * immediately, and doesn't affect the current
137 * character.
138 */
139 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
140 }
141 status = *CSR_UARTFLG; 131 status = *CSR_UARTFLG;
142 } 132 }
143 tty_flip_buffer_push(tty); 133 tty_flip_buffer_push(tty);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0d9358608fdf..30e8beb71430 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -682,8 +682,6 @@ static void autoconfig_16550a(struct uart_8250_port *up)
682 * from EXCR1. Switch back to bank 0, change it in MCR. Then 682 * from EXCR1. Switch back to bank 0, change it in MCR. Then
683 * switch back to bank 2, read it from EXCR1 again and check 683 * switch back to bank 2, read it from EXCR1 again and check
684 * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 684 * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
685 * On PowerPC we don't want to change baud_base, as we have
686 * a number of different divisors. -- Tom Rini
687 */ 685 */
688 serial_outp(up, UART_LCR, 0); 686 serial_outp(up, UART_LCR, 0);
689 status1 = serial_in(up, UART_MCR); 687 status1 = serial_in(up, UART_MCR);
@@ -699,16 +697,25 @@ static void autoconfig_16550a(struct uart_8250_port *up)
699 serial_outp(up, UART_MCR, status1); 697 serial_outp(up, UART_MCR, status1);
700 698
701 if ((status2 ^ status1) & UART_MCR_LOOP) { 699 if ((status2 ^ status1) & UART_MCR_LOOP) {
702#ifndef CONFIG_PPC 700 unsigned short quot;
701
703 serial_outp(up, UART_LCR, 0xE0); 702 serial_outp(up, UART_LCR, 0xE0);
703
704 quot = serial_inp(up, UART_DLM) << 8;
705 quot += serial_inp(up, UART_DLL);
706 quot <<= 3;
707
704 status1 = serial_in(up, 0x04); /* EXCR1 */ 708 status1 = serial_in(up, 0x04); /* EXCR1 */
705 status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ 709 status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
706 status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ 710 status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
707 serial_outp(up, 0x04, status1); 711 serial_outp(up, 0x04, status1);
712
713 serial_outp(up, UART_DLL, quot & 0xff);
714 serial_outp(up, UART_DLM, quot >> 8);
715
708 serial_outp(up, UART_LCR, 0); 716 serial_outp(up, UART_LCR, 0);
709 up->port.uartclk = 921600*16;
710#endif
711 717
718 up->port.uartclk = 921600*16;
712 up->port.type = PORT_NS16550A; 719 up->port.type = PORT_NS16550A;
713 up->capabilities |= UART_NATSEMI; 720 up->capabilities |= UART_NATSEMI;
714 return; 721 return;
@@ -1122,18 +1129,9 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
1122 } 1129 }
1123 if (uart_handle_sysrq_char(&up->port, ch, regs)) 1130 if (uart_handle_sysrq_char(&up->port, ch, regs))
1124 goto ignore_char; 1131 goto ignore_char;
1125 if ((lsr & up->port.ignore_status_mask) == 0) { 1132
1126 tty_insert_flip_char(tty, ch, flag); 1133 uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
1127 } 1134
1128 if ((lsr & UART_LSR_OE) &&
1129 tty->flip.count < TTY_FLIPBUF_SIZE) {
1130 /*
1131 * Overrun is special, since it's reported
1132 * immediately, and doesn't affect the current
1133 * character.
1134 */
1135 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
1136 }
1137 ignore_char: 1135 ignore_char:
1138 lsr = serial_inp(up, UART_LSR); 1136 lsr = serial_inp(up, UART_LSR);
1139 } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); 1137 } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index f2a5e2933c47..2884b310e54d 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -198,18 +198,8 @@ pl010_rx_chars(struct uart_port *port)
198 if (uart_handle_sysrq_char(port, ch, regs)) 198 if (uart_handle_sysrq_char(port, ch, regs))
199 goto ignore_char; 199 goto ignore_char;
200 200
201 if ((rsr & port->ignore_status_mask) == 0) { 201 uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
202 tty_insert_flip_char(tty, ch, flag); 202
203 }
204 if ((rsr & UART01x_RSR_OE) &&
205 tty->flip.count < TTY_FLIPBUF_SIZE) {
206 /*
207 * Overrun is special, since it's reported
208 * immediately, and doesn't affect the current
209 * character
210 */
211 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
212 }
213 ignore_char: 203 ignore_char:
214 status = UART_GET_FR(port); 204 status = UART_GET_FR(port);
215 } 205 }
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index d5cbef3fe8b6..7db88ee18f75 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -163,18 +163,8 @@ pl011_rx_chars(struct uart_amba_port *uap)
163 if (uart_handle_sysrq_char(&uap->port, ch, regs)) 163 if (uart_handle_sysrq_char(&uap->port, ch, regs))
164 goto ignore_char; 164 goto ignore_char;
165 165
166 if ((rsr & uap->port.ignore_status_mask) == 0) { 166 uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag);
167 tty_insert_flip_char(tty, ch, flag); 167
168 }
169 if ((rsr & UART01x_RSR_OE) &&
170 tty->flip.count < TTY_FLIPBUF_SIZE) {
171 /*
172 * Overrun is special, since it's reported
173 * immediately, and doesn't affect the current
174 * character
175 */
176 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
177 }
178 ignore_char: 168 ignore_char:
179 status = readw(uap->port.membase + UART01x_FR); 169 status = readw(uap->port.membase + UART01x_FR);
180 } 170 }
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 6242f3090a96..e92522b33c48 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -143,10 +143,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re
143 * CHECK: does overrun affect the current character? 143 * CHECK: does overrun affect the current character?
144 * ASSUMPTION: it does not. 144 * ASSUMPTION: it does not.
145 */ 145 */
146 if ((ch & port->ignore_status_mask & ~RXSTAT_OVERRUN) == 0) 146 uart_insert_char(port, ch, UARTDR_OVERR, ch, flg);
147 tty_insert_flip_char(tty, ch, flg);
148 if ((ch & ~port->ignore_status_mask & RXSTAT_OVERRUN) == 0)
149 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
150 147
151 ignore_char: 148 ignore_char:
152 status = clps_readl(SYSFLG(port)); 149 status = clps_readl(SYSFLG(port));
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 51d8a49f4477..9dc151d8fa61 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -161,20 +161,12 @@ receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs)
161 else if (*status & UART_LSR_FE) 161 else if (*status & UART_LSR_FE)
162 flag = TTY_FRAME; 162 flag = TTY_FRAME;
163 } 163 }
164
164 if (uart_handle_sysrq_char(&up->port, ch, regs)) 165 if (uart_handle_sysrq_char(&up->port, ch, regs))
165 goto ignore_char; 166 goto ignore_char;
166 if ((*status & up->port.ignore_status_mask) == 0) { 167
167 tty_insert_flip_char(tty, ch, flag); 168 uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag);
168 } 169
169 if ((*status & UART_LSR_OE) &&
170 tty->flip.count < TTY_FLIPBUF_SIZE) {
171 /*
172 * Overrun is special, since it's reported
173 * immediately, and doesn't affect the current
174 * character.
175 */
176 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
177 }
178 ignore_char: 170 ignore_char:
179 *status = serial_in(up, UART_LSR); 171 *status = serial_in(up, UART_LSR);
180 } while ((*status & UART_LSR_DR) && (max_count-- > 0)); 172 } while ((*status & UART_LSR_DR) && (max_count-- > 0));
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 435750d40a47..2a9f7ade2c9d 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -394,20 +394,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
394 if (uart_handle_sysrq_char(port, ch, regs)) 394 if (uart_handle_sysrq_char(port, ch, regs))
395 goto ignore_char; 395 goto ignore_char;
396 396
397 if ((uerstat & port->ignore_status_mask) == 0) { 397 uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag);
398 tty_insert_flip_char(tty, ch, flag);
399 }
400
401 if ((uerstat & S3C2410_UERSTAT_OVERRUN) &&
402 tty->flip.count < TTY_FLIPBUF_SIZE) {
403 /*
404 * Overrun is special, since it's reported
405 * immediately, and doesn't affect the current
406 * character.
407 */
408
409 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
410 }
411 398
412 ignore_char: 399 ignore_char:
413 continue; 400 continue;
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 157218bc6c6f..22565a67a57c 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -237,10 +237,7 @@ sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
237 if (uart_handle_sysrq_char(&sport->port, ch, regs)) 237 if (uart_handle_sysrq_char(&sport->port, ch, regs))
238 goto ignore_char; 238 goto ignore_char;
239 239
240 if ((status & port->ignore_status_mask & ~UTSR1_TO_SM(UTSR1_ROR)) == 0) 240 uart_insert_char(&sport->port, status, UTSR1_TO_SM(UTSR1_ROR), ch, flg);
241 tty_insert_flip_char(tty, ch, flg);
242 if (status & ~port->ignore_status_mask & UTSR1_TO_SM(UTSR1_ROR))
243 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
244 241
245 ignore_char: 242 ignore_char:
246 status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | 243 status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 6eeb48f6a482..0d7b65f93e8d 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -661,10 +661,10 @@ void serial_config(dev_link_t * link)
661 /* Is this a multiport card? */ 661 /* Is this a multiport card? */
662 tuple->DesiredTuple = CISTPL_MANFID; 662 tuple->DesiredTuple = CISTPL_MANFID;
663 if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { 663 if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
664 info->manfid = le16_to_cpu(buf[0]); 664 info->manfid = parse->manfid.manf;
665 for (i = 0; i < MULTI_COUNT; i++) 665 for (i = 0; i < MULTI_COUNT; i++)
666 if ((info->manfid == multi_id[i].manfid) && 666 if ((info->manfid == multi_id[i].manfid) &&
667 (le16_to_cpu(buf[1]) == multi_id[i].prodid)) 667 (parse->manfid.card == multi_id[i].prodid))
668 break; 668 break;
669 if (i < MULTI_COUNT) 669 if (i < MULTI_COUNT)
670 info->multi = multi_id[i].multi; 670 info->multi = multi_id[i].multi;
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index 85cfa08d3bad..56f269b6bfb1 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -190,18 +190,7 @@ lh7a40xuart_rx_chars (struct uart_port* port)
190 if (uart_handle_sysrq_char (port, (unsigned char) data, regs)) 190 if (uart_handle_sysrq_char (port, (unsigned char) data, regs))
191 continue; 191 continue;
192 192
193 if ((data & port->ignore_status_mask) == 0) { 193 uart_insert_char(port, data, RxOverrunError, data, flag);
194 tty_insert_flip_char(tty, data, flag);
195 }
196 if ((data & RxOverrunError)
197 && tty->flip.count < TTY_FLIPBUF_SIZE) {
198 /*
199 * Overrun is special, since it's reported
200 * immediately, and doesn't affect the current
201 * character
202 */
203 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
204 }
205 } 194 }
206 tty_flip_buffer_push (tty); 195 tty_flip_buffer_push (tty);
207 return; 196 return;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 37b2ef297cbe..3f1051a4a13f 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -350,18 +350,9 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
350 } 350 }
351 if (uart_handle_sysrq_char(&up->port, ch, regs)) 351 if (uart_handle_sysrq_char(&up->port, ch, regs))
352 goto ignore_char; 352 goto ignore_char;
353 if ((disr & up->port.ignore_status_mask) == 0) { 353
354 tty_insert_flip_char(tty, ch, flag); 354 uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag);
355 } 355
356 if ((disr & TXX9_SIDISR_UOER) &&
357 tty->flip.count < TTY_FLIPBUF_SIZE) {
358 /*
359 * Overrun is special, since it's reported
360 * immediately, and doesn't affect the current
361 * character.
362 */
363 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
364 }
365 ignore_char: 356 ignore_char:
366 disr = sio_in(up, TXX9_SIDISR); 357 disr = sio_in(up, TXX9_SIDISR);
367 } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); 358 } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 39b788d95e39..10e2990a40d4 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -61,6 +61,16 @@ struct uart_sunsab_port {
61 unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */ 61 unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */
62 unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */ 62 unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */
63 int type; /* SAB82532 version */ 63 int type; /* SAB82532 version */
64
65 /* Setting configuration bits while the transmitter is active
66 * can cause garbage characters to get emitted by the chip.
67 * Therefore, we cache such writes here and do the real register
68 * write the next time the transmitter becomes idle.
69 */
70 unsigned int cached_ebrg;
71 unsigned char cached_mode;
72 unsigned char cached_pvr;
73 unsigned char cached_dafo;
64}; 74};
65 75
66/* 76/*
@@ -236,6 +246,7 @@ receive_chars(struct uart_sunsab_port *up,
236} 246}
237 247
238static void sunsab_stop_tx(struct uart_port *, unsigned int); 248static void sunsab_stop_tx(struct uart_port *, unsigned int);
249static void sunsab_tx_idle(struct uart_sunsab_port *);
239 250
240static void transmit_chars(struct uart_sunsab_port *up, 251static void transmit_chars(struct uart_sunsab_port *up,
241 union sab82532_irq_status *stat) 252 union sab82532_irq_status *stat)
@@ -258,6 +269,7 @@ static void transmit_chars(struct uart_sunsab_port *up,
258 return; 269 return;
259 270
260 set_bit(SAB82532_XPR, &up->irqflags); 271 set_bit(SAB82532_XPR, &up->irqflags);
272 sunsab_tx_idle(up);
261 273
262 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 274 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
263 up->interrupt_mask1 |= SAB82532_IMR1_XPR; 275 up->interrupt_mask1 |= SAB82532_IMR1_XPR;
@@ -397,21 +409,21 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl)
397 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; 409 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
398 410
399 if (mctrl & TIOCM_RTS) { 411 if (mctrl & TIOCM_RTS) {
400 writeb(readb(&up->regs->rw.mode) & ~SAB82532_MODE_FRTS, 412 up->cached_mode &= ~SAB82532_MODE_FRTS;
401 &up->regs->rw.mode); 413 up->cached_mode |= SAB82532_MODE_RTS;
402 writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
403 &up->regs->rw.mode);
404 } else { 414 } else {
405 writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS, 415 up->cached_mode |= (SAB82532_MODE_FRTS |
406 &up->regs->rw.mode); 416 SAB82532_MODE_RTS);
407 writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
408 &up->regs->rw.mode);
409 } 417 }
410 if (mctrl & TIOCM_DTR) { 418 if (mctrl & TIOCM_DTR) {
411 writeb(readb(&up->regs->rw.pvr) & ~(up->pvr_dtr_bit), &up->regs->rw.pvr); 419 up->cached_pvr &= ~(up->pvr_dtr_bit);
412 } else { 420 } else {
413 writeb(readb(&up->regs->rw.pvr) | up->pvr_dtr_bit, &up->regs->rw.pvr); 421 up->cached_pvr |= up->pvr_dtr_bit;
414 } 422 }
423
424 set_bit(SAB82532_REGS_PENDING, &up->irqflags);
425 if (test_bit(SAB82532_XPR, &up->irqflags))
426 sunsab_tx_idle(up);
415} 427}
416 428
417/* port->lock is not held. */ 429/* port->lock is not held. */
@@ -450,6 +462,25 @@ static void sunsab_stop_tx(struct uart_port *port, unsigned int tty_stop)
450} 462}
451 463
452/* port->lock held by caller. */ 464/* port->lock held by caller. */
465static void sunsab_tx_idle(struct uart_sunsab_port *up)
466{
467 if (test_bit(SAB82532_REGS_PENDING, &up->irqflags)) {
468 u8 tmp;
469
470 clear_bit(SAB82532_REGS_PENDING, &up->irqflags);
471 writeb(up->cached_mode, &up->regs->rw.mode);
472 writeb(up->cached_pvr, &up->regs->rw.pvr);
473 writeb(up->cached_dafo, &up->regs->w.dafo);
474
475 writeb(up->cached_ebrg & 0xff, &up->regs->w.bgr);
476 tmp = readb(&up->regs->rw.ccr2);
477 tmp &= ~0xc0;
478 tmp |= (up->cached_ebrg >> 2) & 0xc0;
479 writeb(tmp, &up->regs->rw.ccr2);
480 }
481}
482
483/* port->lock held by caller. */
453static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start) 484static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start)
454{ 485{
455 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; 486 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
@@ -517,12 +548,16 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state)
517 548
518 spin_lock_irqsave(&up->port.lock, flags); 549 spin_lock_irqsave(&up->port.lock, flags);
519 550
520 val = readb(&up->regs->rw.dafo); 551 val = up->cached_dafo;
521 if (break_state) 552 if (break_state)
522 val |= SAB82532_DAFO_XBRK; 553 val |= SAB82532_DAFO_XBRK;
523 else 554 else
524 val &= ~SAB82532_DAFO_XBRK; 555 val &= ~SAB82532_DAFO_XBRK;
525 writeb(val, &up->regs->rw.dafo); 556 up->cached_dafo = val;
557
558 set_bit(SAB82532_REGS_PENDING, &up->irqflags);
559 if (test_bit(SAB82532_XPR, &up->irqflags))
560 sunsab_tx_idle(up);
526 561
527 spin_unlock_irqrestore(&up->port.lock, flags); 562 spin_unlock_irqrestore(&up->port.lock, flags);
528} 563}
@@ -566,8 +601,9 @@ static int sunsab_startup(struct uart_port *port)
566 SAB82532_CCR2_TOE, &up->regs->w.ccr2); 601 SAB82532_CCR2_TOE, &up->regs->w.ccr2);
567 writeb(0, &up->regs->w.ccr3); 602 writeb(0, &up->regs->w.ccr3);
568 writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4); 603 writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4);
569 writeb(SAB82532_MODE_RTS | SAB82532_MODE_FCTS | 604 up->cached_mode = (SAB82532_MODE_RTS | SAB82532_MODE_FCTS |
570 SAB82532_MODE_RAC, &up->regs->w.mode); 605 SAB82532_MODE_RAC);
606 writeb(up->cached_mode, &up->regs->w.mode);
571 writeb(SAB82532_RFC_DPS|SAB82532_RFC_RFTH_32, &up->regs->w.rfc); 607 writeb(SAB82532_RFC_DPS|SAB82532_RFC_RFTH_32, &up->regs->w.rfc);
572 608
573 tmp = readb(&up->regs->rw.ccr0); 609 tmp = readb(&up->regs->rw.ccr0);
@@ -598,7 +634,6 @@ static void sunsab_shutdown(struct uart_port *port)
598{ 634{
599 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; 635 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
600 unsigned long flags; 636 unsigned long flags;
601 unsigned char tmp;
602 637
603 spin_lock_irqsave(&up->port.lock, flags); 638 spin_lock_irqsave(&up->port.lock, flags);
604 639
@@ -609,14 +644,13 @@ static void sunsab_shutdown(struct uart_port *port)
609 writeb(up->interrupt_mask1, &up->regs->w.imr1); 644 writeb(up->interrupt_mask1, &up->regs->w.imr1);
610 645
611 /* Disable break condition */ 646 /* Disable break condition */
612 tmp = readb(&up->regs->rw.dafo); 647 up->cached_dafo = readb(&up->regs->rw.dafo);
613 tmp &= ~SAB82532_DAFO_XBRK; 648 up->cached_dafo &= ~SAB82532_DAFO_XBRK;
614 writeb(tmp, &up->regs->rw.dafo); 649 writeb(up->cached_dafo, &up->regs->rw.dafo);
615 650
616 /* Disable Receiver */ 651 /* Disable Receiver */
617 tmp = readb(&up->regs->rw.mode); 652 up->cached_mode &= ~SAB82532_MODE_RAC;
618 tmp &= ~SAB82532_MODE_RAC; 653 writeb(up->cached_mode, &up->regs->rw.mode);
619 writeb(tmp, &up->regs->rw.mode);
620 654
621 /* 655 /*
622 * XXX FIXME 656 * XXX FIXME
@@ -685,7 +719,6 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
685 unsigned int iflag, unsigned int baud, 719 unsigned int iflag, unsigned int baud,
686 unsigned int quot) 720 unsigned int quot)
687{ 721{
688 unsigned int ebrg;
689 unsigned char dafo; 722 unsigned char dafo;
690 int bits, n, m; 723 int bits, n, m;
691 724
@@ -714,10 +747,11 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
714 } else { 747 } else {
715 dafo |= SAB82532_DAFO_PAR_EVEN; 748 dafo |= SAB82532_DAFO_PAR_EVEN;
716 } 749 }
750 up->cached_dafo = dafo;
717 751
718 calc_ebrg(baud, &n, &m); 752 calc_ebrg(baud, &n, &m);
719 753
720 ebrg = n | (m << 6); 754 up->cached_ebrg = n | (m << 6);
721 755
722 up->tec_timeout = (10 * 1000000) / baud; 756 up->tec_timeout = (10 * 1000000) / baud;
723 up->cec_timeout = up->tec_timeout >> 2; 757 up->cec_timeout = up->tec_timeout >> 2;
@@ -770,16 +804,13 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
770 uart_update_timeout(&up->port, cflag, 804 uart_update_timeout(&up->port, cflag,
771 (up->port.uartclk / (16 * quot))); 805 (up->port.uartclk / (16 * quot)));
772 806
773 /* Now bang the new settings into the chip. */ 807 /* Now schedule a register update when the chip's
774 sunsab_cec_wait(up); 808 * transmitter is idle.
775 sunsab_tec_wait(up); 809 */
776 writeb(dafo, &up->regs->w.dafo); 810 up->cached_mode |= SAB82532_MODE_RAC;
777 writeb(ebrg & 0xff, &up->regs->w.bgr); 811 set_bit(SAB82532_REGS_PENDING, &up->irqflags);
778 writeb((readb(&up->regs->rw.ccr2) & ~0xc0) | ((ebrg >> 2) & 0xc0), 812 if (test_bit(SAB82532_XPR, &up->irqflags))
779 &up->regs->rw.ccr2); 813 sunsab_tx_idle(up);
780
781 writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RAC, &up->regs->rw.mode);
782
783} 814}
784 815
785/* port->lock is not held. */ 816/* port->lock is not held. */
@@ -1084,11 +1115,13 @@ static void __init sunsab_init_hw(void)
1084 up->pvr_dsr_bit = (1 << 3); 1115 up->pvr_dsr_bit = (1 << 3);
1085 up->pvr_dtr_bit = (1 << 2); 1116 up->pvr_dtr_bit = (1 << 2);
1086 } 1117 }
1087 writeb((1 << 1) | (1 << 2) | (1 << 4), &up->regs->w.pvr); 1118 up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4);
1088 writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS, 1119 writeb(up->cached_pvr, &up->regs->w.pvr);
1089 &up->regs->rw.mode); 1120 up->cached_mode = readb(&up->regs->rw.mode);
1090 writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS, 1121 up->cached_mode |= SAB82532_MODE_FRTS;
1091 &up->regs->rw.mode); 1122 writeb(up->cached_mode, &up->regs->rw.mode);
1123 up->cached_mode |= SAB82532_MODE_RTS;
1124 writeb(up->cached_mode, &up->regs->rw.mode);
1092 1125
1093 up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; 1126 up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
1094 up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; 1127 up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
diff --git a/drivers/serial/sunsab.h b/drivers/serial/sunsab.h
index 686086fcbbf5..b78e1f7b8050 100644
--- a/drivers/serial/sunsab.h
+++ b/drivers/serial/sunsab.h
@@ -126,6 +126,7 @@ union sab82532_irq_status {
126/* irqflags bits */ 126/* irqflags bits */
127#define SAB82532_ALLS 0x00000001 127#define SAB82532_ALLS 0x00000001
128#define SAB82532_XPR 0x00000002 128#define SAB82532_XPR 0x00000002
129#define SAB82532_REGS_PENDING 0x00000004
129 130
130/* RFIFO Status Byte */ 131/* RFIFO Status Byte */
131#define SAB82532_RSTAT_PE 0x80 132#define SAB82532_RSTAT_PE 0x80
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 307886199f2f..5d2ceb623e6f 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -412,10 +412,8 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status,
412 412
413 if (uart_handle_sysrq_char(port, ch, regs)) 413 if (uart_handle_sysrq_char(port, ch, regs))
414 goto ignore_char; 414 goto ignore_char;
415 if ((lsr & port->ignore_status_mask) == 0) 415
416 tty_insert_flip_char(tty, ch, flag); 416 uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
417 if ((lsr & UART_LSR_OE) && (tty->flip.count < TTY_FLIPBUF_SIZE))
418 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
419 417
420 ignore_char: 418 ignore_char:
421 lsr = siu_read(port, UART_LSR); 419 lsr = siu_read(port, UART_LSR);