diff options
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r-- | drivers/serial/8250.c | 123 |
1 files changed, 111 insertions, 12 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 90621c3312bc..c9832d963f1e 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -251,9 +251,16 @@ static const struct serial8250_config uart_config[] = { | |||
251 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 251 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
252 | .flags = UART_CAP_FIFO | UART_CAP_UUE, | 252 | .flags = UART_CAP_FIFO | UART_CAP_UUE, |
253 | }, | 253 | }, |
254 | [PORT_RM9000] = { | ||
255 | .name = "RM9000", | ||
256 | .fifo_size = 16, | ||
257 | .tx_loadsz = 16, | ||
258 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | ||
259 | .flags = UART_CAP_FIFO, | ||
260 | }, | ||
254 | }; | 261 | }; |
255 | 262 | ||
256 | #ifdef CONFIG_SERIAL_8250_AU1X00 | 263 | #if defined (CONFIG_SERIAL_8250_AU1X00) |
257 | 264 | ||
258 | /* Au1x00 UART hardware has a weird register layout */ | 265 | /* Au1x00 UART hardware has a weird register layout */ |
259 | static const u8 au_io_in_map[] = { | 266 | static const u8 au_io_in_map[] = { |
@@ -289,6 +296,44 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) | |||
289 | return au_io_out_map[offset]; | 296 | return au_io_out_map[offset]; |
290 | } | 297 | } |
291 | 298 | ||
299 | #elif defined (CONFIG_SERIAL_8250_RM9K) | ||
300 | |||
301 | static const u8 | ||
302 | regmap_in[8] = { | ||
303 | [UART_RX] = 0x00, | ||
304 | [UART_IER] = 0x0c, | ||
305 | [UART_IIR] = 0x14, | ||
306 | [UART_LCR] = 0x1c, | ||
307 | [UART_MCR] = 0x20, | ||
308 | [UART_LSR] = 0x24, | ||
309 | [UART_MSR] = 0x28, | ||
310 | [UART_SCR] = 0x2c | ||
311 | }, | ||
312 | regmap_out[8] = { | ||
313 | [UART_TX] = 0x04, | ||
314 | [UART_IER] = 0x0c, | ||
315 | [UART_FCR] = 0x18, | ||
316 | [UART_LCR] = 0x1c, | ||
317 | [UART_MCR] = 0x20, | ||
318 | [UART_LSR] = 0x24, | ||
319 | [UART_MSR] = 0x28, | ||
320 | [UART_SCR] = 0x2c | ||
321 | }; | ||
322 | |||
323 | static inline int map_8250_in_reg(struct uart_8250_port *up, int offset) | ||
324 | { | ||
325 | if (up->port.iotype != UPIO_RM9000) | ||
326 | return offset; | ||
327 | return regmap_in[offset]; | ||
328 | } | ||
329 | |||
330 | static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) | ||
331 | { | ||
332 | if (up->port.iotype != UPIO_RM9000) | ||
333 | return offset; | ||
334 | return regmap_out[offset]; | ||
335 | } | ||
336 | |||
292 | #else | 337 | #else |
293 | 338 | ||
294 | /* sane hardware needs no mapping */ | 339 | /* sane hardware needs no mapping */ |
@@ -308,8 +353,10 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) | |||
308 | return inb(up->port.iobase + 1); | 353 | return inb(up->port.iobase + 1); |
309 | 354 | ||
310 | case UPIO_MEM: | 355 | case UPIO_MEM: |
356 | case UPIO_DWAPB: | ||
311 | return readb(up->port.membase + offset); | 357 | return readb(up->port.membase + offset); |
312 | 358 | ||
359 | case UPIO_RM9000: | ||
313 | case UPIO_MEM32: | 360 | case UPIO_MEM32: |
314 | return readl(up->port.membase + offset); | 361 | return readl(up->port.membase + offset); |
315 | 362 | ||
@@ -333,6 +380,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) | |||
333 | static void | 380 | static void |
334 | serial_out(struct uart_8250_port *up, int offset, int value) | 381 | serial_out(struct uart_8250_port *up, int offset, int value) |
335 | { | 382 | { |
383 | /* Save the offset before it's remapped */ | ||
384 | int save_offset = offset; | ||
336 | offset = map_8250_out_reg(up, offset) << up->port.regshift; | 385 | offset = map_8250_out_reg(up, offset) << up->port.regshift; |
337 | 386 | ||
338 | switch (up->port.iotype) { | 387 | switch (up->port.iotype) { |
@@ -345,6 +394,7 @@ serial_out(struct uart_8250_port *up, int offset, int value) | |||
345 | writeb(value, up->port.membase + offset); | 394 | writeb(value, up->port.membase + offset); |
346 | break; | 395 | break; |
347 | 396 | ||
397 | case UPIO_RM9000: | ||
348 | case UPIO_MEM32: | 398 | case UPIO_MEM32: |
349 | writel(value, up->port.membase + offset); | 399 | writel(value, up->port.membase + offset); |
350 | break; | 400 | break; |
@@ -359,6 +409,18 @@ serial_out(struct uart_8250_port *up, int offset, int value) | |||
359 | writeb(value, up->port.membase + offset); | 409 | writeb(value, up->port.membase + offset); |
360 | break; | 410 | break; |
361 | 411 | ||
412 | case UPIO_DWAPB: | ||
413 | /* Save the LCR value so it can be re-written when a | ||
414 | * Busy Detect interrupt occurs. */ | ||
415 | if (save_offset == UART_LCR) | ||
416 | up->lcr = value; | ||
417 | writeb(value, up->port.membase + offset); | ||
418 | /* Read the IER to ensure any interrupt is cleared before | ||
419 | * returning from ISR. */ | ||
420 | if (save_offset == UART_TX || save_offset == UART_IER) | ||
421 | value = serial_in(up, UART_IER); | ||
422 | break; | ||
423 | |||
362 | default: | 424 | default: |
363 | outb(value, up->port.iobase + offset); | 425 | outb(value, up->port.iobase + offset); |
364 | } | 426 | } |
@@ -373,6 +435,7 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) | |||
373 | #ifdef CONFIG_SERIAL_8250_AU1X00 | 435 | #ifdef CONFIG_SERIAL_8250_AU1X00 |
374 | case UPIO_AU: | 436 | case UPIO_AU: |
375 | #endif | 437 | #endif |
438 | case UPIO_DWAPB: | ||
376 | serial_out(up, offset, value); | 439 | serial_out(up, offset, value); |
377 | serial_in(up, UART_LCR); /* safe, no side-effects */ | 440 | serial_in(up, UART_LCR); /* safe, no side-effects */ |
378 | break; | 441 | break; |
@@ -403,7 +466,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value) | |||
403 | serial_outp(up, UART_DLM, value >> 8 & 0xff); | 466 | serial_outp(up, UART_DLM, value >> 8 & 0xff); |
404 | } | 467 | } |
405 | 468 | ||
406 | #ifdef CONFIG_SERIAL_8250_AU1X00 | 469 | #if defined (CONFIG_SERIAL_8250_AU1X00) |
407 | /* Au1x00 haven't got a standard divisor latch */ | 470 | /* Au1x00 haven't got a standard divisor latch */ |
408 | static int serial_dl_read(struct uart_8250_port *up) | 471 | static int serial_dl_read(struct uart_8250_port *up) |
409 | { | 472 | { |
@@ -420,6 +483,24 @@ static void serial_dl_write(struct uart_8250_port *up, int value) | |||
420 | else | 483 | else |
421 | _serial_dl_write(up, value); | 484 | _serial_dl_write(up, value); |
422 | } | 485 | } |
486 | #elif defined (CONFIG_SERIAL_8250_RM9K) | ||
487 | static int serial_dl_read(struct uart_8250_port *up) | ||
488 | { | ||
489 | return (up->port.iotype == UPIO_RM9000) ? | ||
490 | (((__raw_readl(up->port.membase + 0x10) << 8) | | ||
491 | (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) : | ||
492 | _serial_dl_read(up); | ||
493 | } | ||
494 | |||
495 | static void serial_dl_write(struct uart_8250_port *up, int value) | ||
496 | { | ||
497 | if (up->port.iotype == UPIO_RM9000) { | ||
498 | __raw_writel(value, up->port.membase + 0x08); | ||
499 | __raw_writel(value >> 8, up->port.membase + 0x10); | ||
500 | } else { | ||
501 | _serial_dl_write(up, value); | ||
502 | } | ||
503 | } | ||
423 | #else | 504 | #else |
424 | #define serial_dl_read(up) _serial_dl_read(up) | 505 | #define serial_dl_read(up) _serial_dl_read(up) |
425 | #define serial_dl_write(up, value) _serial_dl_write(up, value) | 506 | #define serial_dl_write(up, value) _serial_dl_write(up, value) |
@@ -621,7 +702,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) | |||
621 | * its clones. (We treat the broken original StarTech 16650 V1 as a | 702 | * its clones. (We treat the broken original StarTech 16650 V1 as a |
622 | * 16550, and why not? Startech doesn't seem to even acknowledge its | 703 | * 16550, and why not? Startech doesn't seem to even acknowledge its |
623 | * existence.) | 704 | * existence.) |
624 | * | 705 | * |
625 | * What evil have men's minds wrought... | 706 | * What evil have men's minds wrought... |
626 | */ | 707 | */ |
627 | static void autoconfig_has_efr(struct uart_8250_port *up) | 708 | static void autoconfig_has_efr(struct uart_8250_port *up) |
@@ -674,7 +755,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up) | |||
674 | up->bugs |= UART_BUG_QUOT; | 755 | up->bugs |= UART_BUG_QUOT; |
675 | return; | 756 | return; |
676 | } | 757 | } |
677 | 758 | ||
678 | /* | 759 | /* |
679 | * We check for a XR16C850 by setting DLL and DLM to 0, and then | 760 | * We check for a XR16C850 by setting DLL and DLM to 0, and then |
680 | * reading back DLL and DLM. The chip type depends on the DLM | 761 | * reading back DLL and DLM. The chip type depends on the DLM |
@@ -817,7 +898,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
817 | status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ | 898 | status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ |
818 | status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ | 899 | status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ |
819 | serial_outp(up, 0x04, status1); | 900 | serial_outp(up, 0x04, status1); |
820 | 901 | ||
821 | serial_dl_write(up, quot); | 902 | serial_dl_write(up, quot); |
822 | 903 | ||
823 | serial_outp(up, UART_LCR, 0); | 904 | serial_outp(up, UART_LCR, 0); |
@@ -922,7 +1003,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
922 | /* | 1003 | /* |
923 | * Do a simple existence test first; if we fail this, | 1004 | * Do a simple existence test first; if we fail this, |
924 | * there's no point trying anything else. | 1005 | * there's no point trying anything else. |
925 | * | 1006 | * |
926 | * 0x80 is used as a nonsense port to prevent against | 1007 | * 0x80 is used as a nonsense port to prevent against |
927 | * false positives due to ISA bus float. The | 1008 | * false positives due to ISA bus float. The |
928 | * assumption is that 0x80 is a non-existent port; | 1009 | * assumption is that 0x80 is a non-existent port; |
@@ -961,7 +1042,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
961 | save_mcr = serial_in(up, UART_MCR); | 1042 | save_mcr = serial_in(up, UART_MCR); |
962 | save_lcr = serial_in(up, UART_LCR); | 1043 | save_lcr = serial_in(up, UART_LCR); |
963 | 1044 | ||
964 | /* | 1045 | /* |
965 | * Check to see if a UART is really there. Certain broken | 1046 | * Check to see if a UART is really there. Certain broken |
966 | * internal modems based on the Rockwell chipset fail this | 1047 | * internal modems based on the Rockwell chipset fail this |
967 | * test, because they apparently don't implement the loopback | 1048 | * test, because they apparently don't implement the loopback |
@@ -1068,7 +1149,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
1068 | else | 1149 | else |
1069 | serial_outp(up, UART_IER, 0); | 1150 | serial_outp(up, UART_IER, 0); |
1070 | 1151 | ||
1071 | out: | 1152 | out: |
1072 | spin_unlock_irqrestore(&up->port.lock, flags); | 1153 | spin_unlock_irqrestore(&up->port.lock, flags); |
1073 | // restore_flags(flags); | 1154 | // restore_flags(flags); |
1074 | DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); | 1155 | DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); |
@@ -1094,7 +1175,7 @@ static void autoconfig_irq(struct uart_8250_port *up) | |||
1094 | save_mcr = serial_inp(up, UART_MCR); | 1175 | save_mcr = serial_inp(up, UART_MCR); |
1095 | save_ier = serial_inp(up, UART_IER); | 1176 | save_ier = serial_inp(up, UART_IER); |
1096 | serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); | 1177 | serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); |
1097 | 1178 | ||
1098 | irqs = probe_irq_on(); | 1179 | irqs = probe_irq_on(); |
1099 | serial_outp(up, UART_MCR, 0); | 1180 | serial_outp(up, UART_MCR, 0); |
1100 | udelay (10); | 1181 | udelay (10); |
@@ -1159,8 +1240,11 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1159 | if (up->bugs & UART_BUG_TXEN) { | 1240 | if (up->bugs & UART_BUG_TXEN) { |
1160 | unsigned char lsr, iir; | 1241 | unsigned char lsr, iir; |
1161 | lsr = serial_in(up, UART_LSR); | 1242 | lsr = serial_in(up, UART_LSR); |
1162 | iir = serial_in(up, UART_IIR); | 1243 | iir = serial_in(up, UART_IIR) & 0x0f; |
1163 | if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) | 1244 | if ((up->port.type == PORT_RM9000) ? |
1245 | (lsr & UART_LSR_THRE && | ||
1246 | (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) : | ||
1247 | (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)) | ||
1164 | transmit_chars(up); | 1248 | transmit_chars(up); |
1165 | } | 1249 | } |
1166 | } | 1250 | } |
@@ -1389,6 +1473,19 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) | |||
1389 | handled = 1; | 1473 | handled = 1; |
1390 | 1474 | ||
1391 | end = NULL; | 1475 | end = NULL; |
1476 | } else if (up->port.iotype == UPIO_DWAPB && | ||
1477 | (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | ||
1478 | /* The DesignWare APB UART has an Busy Detect (0x07) | ||
1479 | * interrupt meaning an LCR write attempt occured while the | ||
1480 | * UART was busy. The interrupt must be cleared by reading | ||
1481 | * the UART status register (USR) and the LCR re-written. */ | ||
1482 | unsigned int status; | ||
1483 | status = *(volatile u32 *)up->port.private_data; | ||
1484 | serial_out(up, UART_LCR, up->lcr); | ||
1485 | |||
1486 | handled = 1; | ||
1487 | |||
1488 | end = NULL; | ||
1392 | } else if (end == NULL) | 1489 | } else if (end == NULL) |
1393 | end = l; | 1490 | end = l; |
1394 | 1491 | ||
@@ -1928,7 +2025,7 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1928 | /* | 2025 | /* |
1929 | * Ask the core to calculate the divisor for us. | 2026 | * Ask the core to calculate the divisor for us. |
1930 | */ | 2027 | */ |
1931 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 2028 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
1932 | quot = serial8250_get_divisor(port, baud); | 2029 | quot = serial8250_get_divisor(port, baud); |
1933 | 2030 | ||
1934 | /* | 2031 | /* |
@@ -2090,6 +2187,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) | |||
2090 | case UPIO_TSI: | 2187 | case UPIO_TSI: |
2091 | case UPIO_MEM32: | 2188 | case UPIO_MEM32: |
2092 | case UPIO_MEM: | 2189 | case UPIO_MEM: |
2190 | case UPIO_DWAPB: | ||
2093 | if (!up->port.mapbase) | 2191 | if (!up->port.mapbase) |
2094 | break; | 2192 | break; |
2095 | 2193 | ||
@@ -2127,6 +2225,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) | |||
2127 | case UPIO_TSI: | 2225 | case UPIO_TSI: |
2128 | case UPIO_MEM32: | 2226 | case UPIO_MEM32: |
2129 | case UPIO_MEM: | 2227 | case UPIO_MEM: |
2228 | case UPIO_DWAPB: | ||
2130 | if (!up->port.mapbase) | 2229 | if (!up->port.mapbase) |
2131 | break; | 2230 | break; |
2132 | 2231 | ||