diff options
| author | <jgarzik@pretzel.yyz.us> | 2005-06-04 00:40:40 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-06-04 00:40:40 -0400 |
| commit | ae20ea8525a80a863f70d332cf47b71bd9f54c1f (patch) | |
| tree | 9d3cedeb65db521a8436b545bd91641549a18d24 /drivers/serial | |
| parent | f497ba735fc9ff4e35a19641143708b3be1c7061 (diff) | |
| parent | 8be3de3fd8469154a2b3e18a4712032dac5b4a53 (diff) | |
Automatic merge of /spare/repo/linux-2.6/.git branch HEAD
Diffstat (limited to 'drivers/serial')
| -rw-r--r-- | drivers/serial/21285.c | 14 | ||||
| -rw-r--r-- | drivers/serial/8250.c | 32 | ||||
| -rw-r--r-- | drivers/serial/amba-pl010.c | 14 | ||||
| -rw-r--r-- | drivers/serial/amba-pl011.c | 14 | ||||
| -rw-r--r-- | drivers/serial/clps711x.c | 5 | ||||
| -rw-r--r-- | drivers/serial/pxa.c | 16 | ||||
| -rw-r--r-- | drivers/serial/s3c2410.c | 15 | ||||
| -rw-r--r-- | drivers/serial/sa1100.c | 5 | ||||
| -rw-r--r-- | drivers/serial/serial_cs.c | 4 | ||||
| -rw-r--r-- | drivers/serial/serial_lh7a40x.c | 13 | ||||
| -rw-r--r-- | drivers/serial/serial_txx9.c | 15 | ||||
| -rw-r--r-- | drivers/serial/sunsab.c | 109 | ||||
| -rw-r--r-- | drivers/serial/sunsab.h | 1 | ||||
| -rw-r--r-- | drivers/serial/vr41xx_siu.c | 6 |
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 | ||
| 238 | static void sunsab_stop_tx(struct uart_port *, unsigned int); | 248 | static void sunsab_stop_tx(struct uart_port *, unsigned int); |
| 249 | static void sunsab_tx_idle(struct uart_sunsab_port *); | ||
| 239 | 250 | ||
| 240 | static void transmit_chars(struct uart_sunsab_port *up, | 251 | static 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. */ |
| 465 | static 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. */ | ||
| 453 | static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start) | 484 | static 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); |
