diff options
author | Paul Mackerras <paulus@samba.org> | 2007-05-07 23:37:51 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-05-07 23:37:51 -0400 |
commit | 02bbc0f09c90cefdb2837605c96a66c5ce4ba2e1 (patch) | |
tree | 04ef573cd4de095c500c9fc3477f4278c0b36300 /drivers/serial | |
parent | 7487a2245b8841c77ba9db406cf99a483b9334e9 (diff) | |
parent | 5b94f675f57e4ff16c8fda09088d7480a84dcd91 (diff) |
Merge branch 'linux-2.6'
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/8250.c | 123 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 103 | ||||
-rw-r--r-- | drivers/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/serial/amba-pl010.c | 295 | ||||
-rw-r--r-- | drivers/serial/atmel_serial.c | 9 | ||||
-rw-r--r-- | drivers/serial/atmel_serial.h | 3 | ||||
-rw-r--r-- | drivers/serial/bfin_5xx.c | 1012 | ||||
-rw-r--r-- | drivers/serial/crisv10.h | 136 | ||||
-rw-r--r-- | drivers/serial/imx.c | 268 | ||||
-rw-r--r-- | drivers/serial/mpsc.c | 25 | ||||
-rw-r--r-- | drivers/serial/of_serial.c | 3 | ||||
-rw-r--r-- | drivers/serial/pxa.c | 8 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 41 | ||||
-rw-r--r-- | drivers/serial/sh-sci.c | 113 | ||||
-rw-r--r-- | drivers/serial/sh-sci.h | 83 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 8 |
16 files changed, 1815 insertions, 416 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 90621c3312b..c9832d963f1 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 | ||
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ad9f321968e..924e9bd757f 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -254,6 +254,15 @@ config SERIAL_8250_AU1X00 | |||
254 | to this option. The driver can handle 1 or 2 serial ports. | 254 | to this option. The driver can handle 1 or 2 serial ports. |
255 | If unsure, say N. | 255 | If unsure, say N. |
256 | 256 | ||
257 | config SERIAL_8250_RM9K | ||
258 | bool "Support for MIPS RM9xxx integrated serial port" | ||
259 | depends on SERIAL_8250 != n && SERIAL_RM9000 | ||
260 | select SERIAL_8250_SHARE_IRQ | ||
261 | help | ||
262 | Selecting this option will add support for the integrated serial | ||
263 | port hardware found on MIPS RM9122 and similar processors. | ||
264 | If unsure, say N. | ||
265 | |||
257 | comment "Non-8250 serial port support" | 266 | comment "Non-8250 serial port support" |
258 | 267 | ||
259 | config SERIAL_AMBA_PL010 | 268 | config SERIAL_AMBA_PL010 |
@@ -499,6 +508,100 @@ config SERIAL_SA1100_CONSOLE | |||
499 | your boot loader (lilo or loadlin) about how to pass options to the | 508 | your boot loader (lilo or loadlin) about how to pass options to the |
500 | kernel at boot time.) | 509 | kernel at boot time.) |
501 | 510 | ||
511 | config SERIAL_BFIN | ||
512 | tristate "Blackfin serial port support" | ||
513 | depends on BFIN | ||
514 | select SERIAL_CORE | ||
515 | select SERIAL_BFIN_UART0 if (BF531 || BF532 || BF533 || BF561) | ||
516 | help | ||
517 | Add support for the built-in UARTs on the Blackfin. | ||
518 | |||
519 | To compile this driver as a module, choose M here: the | ||
520 | module will be called bfin_5xx. | ||
521 | |||
522 | config SERIAL_BFIN_CONSOLE | ||
523 | bool "Console on Blackfin serial port" | ||
524 | depends on SERIAL_BFIN | ||
525 | select SERIAL_CORE_CONSOLE | ||
526 | |||
527 | choice | ||
528 | prompt "UART Mode" | ||
529 | depends on SERIAL_BFIN | ||
530 | default SERIAL_BFIN_DMA | ||
531 | help | ||
532 | This driver supports the built-in serial ports of the Blackfin family | ||
533 | of CPUs | ||
534 | |||
535 | config SERIAL_BFIN_DMA | ||
536 | bool "DMA mode" | ||
537 | depends on DMA_UNCACHED_1M | ||
538 | help | ||
539 | This driver works under DMA mode. If this option is selected, the | ||
540 | blackfin simple dma driver is also enabled. | ||
541 | |||
542 | config SERIAL_BFIN_PIO | ||
543 | bool "PIO mode" | ||
544 | help | ||
545 | This driver works under PIO mode. | ||
546 | |||
547 | endchoice | ||
548 | |||
549 | config SERIAL_BFIN_UART0 | ||
550 | bool "Enable UART0" | ||
551 | depends on SERIAL_BFIN | ||
552 | help | ||
553 | Enable UART0 | ||
554 | |||
555 | config BFIN_UART0_CTSRTS | ||
556 | bool "Enable UART0 hardware flow control" | ||
557 | depends on SERIAL_BFIN_UART0 | ||
558 | help | ||
559 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | ||
560 | signal. | ||
561 | |||
562 | config UART0_CTS_PIN | ||
563 | int "UART0 CTS pin" | ||
564 | depends on BFIN_UART0_CTSRTS | ||
565 | default 23 | ||
566 | help | ||
567 | The default pin is GPIO_GP7. | ||
568 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | ||
569 | |||
570 | config UART0_RTS_PIN | ||
571 | int "UART0 RTS pin" | ||
572 | depends on BFIN_UART0_CTSRTS | ||
573 | default 22 | ||
574 | help | ||
575 | The default pin is GPIO_GP6. | ||
576 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | ||
577 | |||
578 | config SERIAL_BFIN_UART1 | ||
579 | bool "Enable UART1" | ||
580 | depends on SERIAL_BFIN && (BF534 || BF536 || BF537) | ||
581 | help | ||
582 | Enable UART1 | ||
583 | |||
584 | config BFIN_UART1_CTSRTS | ||
585 | bool "Enable UART1 hardware flow control" | ||
586 | depends on SERIAL_BFIN_UART1 | ||
587 | help | ||
588 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | ||
589 | signal. | ||
590 | |||
591 | config UART1_CTS_PIN | ||
592 | int "UART1 CTS pin" | ||
593 | depends on BFIN_UART1_CTSRTS | ||
594 | default -1 | ||
595 | help | ||
596 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | ||
597 | |||
598 | config UART1_RTS_PIN | ||
599 | int "UART1 RTS pin" | ||
600 | depends on BFIN_UART1_CTSRTS | ||
601 | default -1 | ||
602 | help | ||
603 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | ||
604 | |||
502 | config SERIAL_IMX | 605 | config SERIAL_IMX |
503 | bool "IMX serial port support" | 606 | bool "IMX serial port support" |
504 | depends on ARM && ARCH_IMX | 607 | depends on ARM && ARCH_IMX |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 6b3560c5749..4959bcb8d1e 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -27,6 +27,7 @@ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o | |||
27 | obj-$(CONFIG_SERIAL_PXA) += pxa.o | 27 | obj-$(CONFIG_SERIAL_PXA) += pxa.o |
28 | obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o | 28 | obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o |
29 | obj-$(CONFIG_SERIAL_SA1100) += sa1100.o | 29 | obj-$(CONFIG_SERIAL_SA1100) += sa1100.o |
30 | obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o | ||
30 | obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o | 31 | obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o |
31 | obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o | 32 | obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o |
32 | obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o | 33 | obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index f69bd097166..1a9a24b8263 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/serial.h> | 48 | #include <linux/serial.h> |
49 | #include <linux/amba/bus.h> | 49 | #include <linux/amba/bus.h> |
50 | #include <linux/amba/serial.h> | 50 | #include <linux/amba/serial.h> |
51 | #include <linux/clk.h> | ||
51 | 52 | ||
52 | #include <asm/io.h> | 53 | #include <asm/io.h> |
53 | 54 | ||
@@ -70,6 +71,7 @@ | |||
70 | */ | 71 | */ |
71 | struct uart_amba_port { | 72 | struct uart_amba_port { |
72 | struct uart_port port; | 73 | struct uart_port port; |
74 | struct clk *clk; | ||
73 | struct amba_device *dev; | 75 | struct amba_device *dev; |
74 | struct amba_pl010_data *data; | 76 | struct amba_pl010_data *data; |
75 | unsigned int old_status; | 77 | unsigned int old_status; |
@@ -77,73 +79,77 @@ struct uart_amba_port { | |||
77 | 79 | ||
78 | static void pl010_stop_tx(struct uart_port *port) | 80 | static void pl010_stop_tx(struct uart_port *port) |
79 | { | 81 | { |
82 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
80 | unsigned int cr; | 83 | unsigned int cr; |
81 | 84 | ||
82 | cr = readb(port->membase + UART010_CR); | 85 | cr = readb(uap->port.membase + UART010_CR); |
83 | cr &= ~UART010_CR_TIE; | 86 | cr &= ~UART010_CR_TIE; |
84 | writel(cr, port->membase + UART010_CR); | 87 | writel(cr, uap->port.membase + UART010_CR); |
85 | } | 88 | } |
86 | 89 | ||
87 | static void pl010_start_tx(struct uart_port *port) | 90 | static void pl010_start_tx(struct uart_port *port) |
88 | { | 91 | { |
92 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
89 | unsigned int cr; | 93 | unsigned int cr; |
90 | 94 | ||
91 | cr = readb(port->membase + UART010_CR); | 95 | cr = readb(uap->port.membase + UART010_CR); |
92 | cr |= UART010_CR_TIE; | 96 | cr |= UART010_CR_TIE; |
93 | writel(cr, port->membase + UART010_CR); | 97 | writel(cr, uap->port.membase + UART010_CR); |
94 | } | 98 | } |
95 | 99 | ||
96 | static void pl010_stop_rx(struct uart_port *port) | 100 | static void pl010_stop_rx(struct uart_port *port) |
97 | { | 101 | { |
102 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
98 | unsigned int cr; | 103 | unsigned int cr; |
99 | 104 | ||
100 | cr = readb(port->membase + UART010_CR); | 105 | cr = readb(uap->port.membase + UART010_CR); |
101 | cr &= ~(UART010_CR_RIE | UART010_CR_RTIE); | 106 | cr &= ~(UART010_CR_RIE | UART010_CR_RTIE); |
102 | writel(cr, port->membase + UART010_CR); | 107 | writel(cr, uap->port.membase + UART010_CR); |
103 | } | 108 | } |
104 | 109 | ||
105 | static void pl010_enable_ms(struct uart_port *port) | 110 | static void pl010_enable_ms(struct uart_port *port) |
106 | { | 111 | { |
112 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
107 | unsigned int cr; | 113 | unsigned int cr; |
108 | 114 | ||
109 | cr = readb(port->membase + UART010_CR); | 115 | cr = readb(uap->port.membase + UART010_CR); |
110 | cr |= UART010_CR_MSIE; | 116 | cr |= UART010_CR_MSIE; |
111 | writel(cr, port->membase + UART010_CR); | 117 | writel(cr, uap->port.membase + UART010_CR); |
112 | } | 118 | } |
113 | 119 | ||
114 | static void pl010_rx_chars(struct uart_port *port) | 120 | static void pl010_rx_chars(struct uart_amba_port *uap) |
115 | { | 121 | { |
116 | struct tty_struct *tty = port->info->tty; | 122 | struct tty_struct *tty = uap->port.info->tty; |
117 | unsigned int status, ch, flag, rsr, max_count = 256; | 123 | unsigned int status, ch, flag, rsr, max_count = 256; |
118 | 124 | ||
119 | status = readb(port->membase + UART01x_FR); | 125 | status = readb(uap->port.membase + UART01x_FR); |
120 | while (UART_RX_DATA(status) && max_count--) { | 126 | while (UART_RX_DATA(status) && max_count--) { |
121 | ch = readb(port->membase + UART01x_DR); | 127 | ch = readb(uap->port.membase + UART01x_DR); |
122 | flag = TTY_NORMAL; | 128 | flag = TTY_NORMAL; |
123 | 129 | ||
124 | port->icount.rx++; | 130 | uap->port.icount.rx++; |
125 | 131 | ||
126 | /* | 132 | /* |
127 | * Note that the error handling code is | 133 | * Note that the error handling code is |
128 | * out of the main execution path | 134 | * out of the main execution path |
129 | */ | 135 | */ |
130 | rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX; | 136 | rsr = readb(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX; |
131 | if (unlikely(rsr & UART01x_RSR_ANY)) { | 137 | if (unlikely(rsr & UART01x_RSR_ANY)) { |
132 | writel(0, port->membase + UART01x_ECR); | 138 | writel(0, uap->port.membase + UART01x_ECR); |
133 | 139 | ||
134 | if (rsr & UART01x_RSR_BE) { | 140 | if (rsr & UART01x_RSR_BE) { |
135 | rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); | 141 | rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); |
136 | port->icount.brk++; | 142 | uap->port.icount.brk++; |
137 | if (uart_handle_break(port)) | 143 | if (uart_handle_break(&uap->port)) |
138 | goto ignore_char; | 144 | goto ignore_char; |
139 | } else if (rsr & UART01x_RSR_PE) | 145 | } else if (rsr & UART01x_RSR_PE) |
140 | port->icount.parity++; | 146 | uap->port.icount.parity++; |
141 | else if (rsr & UART01x_RSR_FE) | 147 | else if (rsr & UART01x_RSR_FE) |
142 | port->icount.frame++; | 148 | uap->port.icount.frame++; |
143 | if (rsr & UART01x_RSR_OE) | 149 | if (rsr & UART01x_RSR_OE) |
144 | port->icount.overrun++; | 150 | uap->port.icount.overrun++; |
145 | 151 | ||
146 | rsr &= port->read_status_mask; | 152 | rsr &= uap->port.read_status_mask; |
147 | 153 | ||
148 | if (rsr & UART01x_RSR_BE) | 154 | if (rsr & UART01x_RSR_BE) |
149 | flag = TTY_BREAK; | 155 | flag = TTY_BREAK; |
@@ -153,53 +159,52 @@ static void pl010_rx_chars(struct uart_port *port) | |||
153 | flag = TTY_FRAME; | 159 | flag = TTY_FRAME; |
154 | } | 160 | } |
155 | 161 | ||
156 | if (uart_handle_sysrq_char(port, ch)) | 162 | if (uart_handle_sysrq_char(&uap->port, ch)) |
157 | goto ignore_char; | 163 | goto ignore_char; |
158 | 164 | ||
159 | uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag); | 165 | uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag); |
160 | 166 | ||
161 | ignore_char: | 167 | ignore_char: |
162 | status = readb(port->membase + UART01x_FR); | 168 | status = readb(uap->port.membase + UART01x_FR); |
163 | } | 169 | } |
164 | tty_flip_buffer_push(tty); | 170 | tty_flip_buffer_push(tty); |
165 | return; | 171 | return; |
166 | } | 172 | } |
167 | 173 | ||
168 | static void pl010_tx_chars(struct uart_port *port) | 174 | static void pl010_tx_chars(struct uart_amba_port *uap) |
169 | { | 175 | { |
170 | struct circ_buf *xmit = &port->info->xmit; | 176 | struct circ_buf *xmit = &uap->port.info->xmit; |
171 | int count; | 177 | int count; |
172 | 178 | ||
173 | if (port->x_char) { | 179 | if (uap->port.x_char) { |
174 | writel(port->x_char, port->membase + UART01x_DR); | 180 | writel(uap->port.x_char, uap->port.membase + UART01x_DR); |
175 | port->icount.tx++; | 181 | uap->port.icount.tx++; |
176 | port->x_char = 0; | 182 | uap->port.x_char = 0; |
177 | return; | 183 | return; |
178 | } | 184 | } |
179 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | 185 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { |
180 | pl010_stop_tx(port); | 186 | pl010_stop_tx(&uap->port); |
181 | return; | 187 | return; |
182 | } | 188 | } |
183 | 189 | ||
184 | count = port->fifosize >> 1; | 190 | count = uap->port.fifosize >> 1; |
185 | do { | 191 | do { |
186 | writel(xmit->buf[xmit->tail], port->membase + UART01x_DR); | 192 | writel(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); |
187 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 193 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
188 | port->icount.tx++; | 194 | uap->port.icount.tx++; |
189 | if (uart_circ_empty(xmit)) | 195 | if (uart_circ_empty(xmit)) |
190 | break; | 196 | break; |
191 | } while (--count > 0); | 197 | } while (--count > 0); |
192 | 198 | ||
193 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 199 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
194 | uart_write_wakeup(port); | 200 | uart_write_wakeup(&uap->port); |
195 | 201 | ||
196 | if (uart_circ_empty(xmit)) | 202 | if (uart_circ_empty(xmit)) |
197 | pl010_stop_tx(port); | 203 | pl010_stop_tx(&uap->port); |
198 | } | 204 | } |
199 | 205 | ||
200 | static void pl010_modem_status(struct uart_port *port) | 206 | static void pl010_modem_status(struct uart_amba_port *uap) |
201 | { | 207 | { |
202 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
203 | unsigned int status, delta; | 208 | unsigned int status, delta; |
204 | 209 | ||
205 | writel(0, uap->port.membase + UART010_ICR); | 210 | writel(0, uap->port.membase + UART010_ICR); |
@@ -226,47 +231,50 @@ static void pl010_modem_status(struct uart_port *port) | |||
226 | 231 | ||
227 | static irqreturn_t pl010_int(int irq, void *dev_id) | 232 | static irqreturn_t pl010_int(int irq, void *dev_id) |
228 | { | 233 | { |
229 | struct uart_port *port = dev_id; | 234 | struct uart_amba_port *uap = dev_id; |
230 | unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; | 235 | unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; |
231 | int handled = 0; | 236 | int handled = 0; |
232 | 237 | ||
233 | spin_lock(&port->lock); | 238 | spin_lock(&uap->port.lock); |
234 | 239 | ||
235 | status = readb(port->membase + UART010_IIR); | 240 | status = readb(uap->port.membase + UART010_IIR); |
236 | if (status) { | 241 | if (status) { |
237 | do { | 242 | do { |
238 | if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) | 243 | if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) |
239 | pl010_rx_chars(port); | 244 | pl010_rx_chars(uap); |
240 | if (status & UART010_IIR_MIS) | 245 | if (status & UART010_IIR_MIS) |
241 | pl010_modem_status(port); | 246 | pl010_modem_status(uap); |
242 | if (status & UART010_IIR_TIS) | 247 | if (status & UART010_IIR_TIS) |
243 | pl010_tx_chars(port); | 248 | pl010_tx_chars(uap); |
244 | 249 | ||
245 | if (pass_counter-- == 0) | 250 | if (pass_counter-- == 0) |
246 | break; | 251 | break; |
247 | 252 | ||
248 | status = readb(port->membase + UART010_IIR); | 253 | status = readb(uap->port.membase + UART010_IIR); |
249 | } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS | | 254 | } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS | |
250 | UART010_IIR_TIS)); | 255 | UART010_IIR_TIS)); |
251 | handled = 1; | 256 | handled = 1; |
252 | } | 257 | } |
253 | 258 | ||
254 | spin_unlock(&port->lock); | 259 | spin_unlock(&uap->port.lock); |
255 | 260 | ||
256 | return IRQ_RETVAL(handled); | 261 | return IRQ_RETVAL(handled); |
257 | } | 262 | } |
258 | 263 | ||
259 | static unsigned int pl010_tx_empty(struct uart_port *port) | 264 | static unsigned int pl010_tx_empty(struct uart_port *port) |
260 | { | 265 | { |
261 | return readb(port->membase + UART01x_FR) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; | 266 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
267 | unsigned int status = readb(uap->port.membase + UART01x_FR); | ||
268 | return status & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; | ||
262 | } | 269 | } |
263 | 270 | ||
264 | static unsigned int pl010_get_mctrl(struct uart_port *port) | 271 | static unsigned int pl010_get_mctrl(struct uart_port *port) |
265 | { | 272 | { |
273 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
266 | unsigned int result = 0; | 274 | unsigned int result = 0; |
267 | unsigned int status; | 275 | unsigned int status; |
268 | 276 | ||
269 | status = readb(port->membase + UART01x_FR); | 277 | status = readb(uap->port.membase + UART01x_FR); |
270 | if (status & UART01x_FR_DCD) | 278 | if (status & UART01x_FR_DCD) |
271 | result |= TIOCM_CAR; | 279 | result |= TIOCM_CAR; |
272 | if (status & UART01x_FR_DSR) | 280 | if (status & UART01x_FR_DSR) |
@@ -287,17 +295,18 @@ static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
287 | 295 | ||
288 | static void pl010_break_ctl(struct uart_port *port, int break_state) | 296 | static void pl010_break_ctl(struct uart_port *port, int break_state) |
289 | { | 297 | { |
298 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
290 | unsigned long flags; | 299 | unsigned long flags; |
291 | unsigned int lcr_h; | 300 | unsigned int lcr_h; |
292 | 301 | ||
293 | spin_lock_irqsave(&port->lock, flags); | 302 | spin_lock_irqsave(&uap->port.lock, flags); |
294 | lcr_h = readb(port->membase + UART010_LCRH); | 303 | lcr_h = readb(uap->port.membase + UART010_LCRH); |
295 | if (break_state == -1) | 304 | if (break_state == -1) |
296 | lcr_h |= UART01x_LCRH_BRK; | 305 | lcr_h |= UART01x_LCRH_BRK; |
297 | else | 306 | else |
298 | lcr_h &= ~UART01x_LCRH_BRK; | 307 | lcr_h &= ~UART01x_LCRH_BRK; |
299 | writel(lcr_h, port->membase + UART010_LCRH); | 308 | writel(lcr_h, uap->port.membase + UART010_LCRH); |
300 | spin_unlock_irqrestore(&port->lock, flags); | 309 | spin_unlock_irqrestore(&uap->port.lock, flags); |
301 | } | 310 | } |
302 | 311 | ||
303 | static int pl010_startup(struct uart_port *port) | 312 | static int pl010_startup(struct uart_port *port) |
@@ -306,48 +315,70 @@ static int pl010_startup(struct uart_port *port) | |||
306 | int retval; | 315 | int retval; |
307 | 316 | ||
308 | /* | 317 | /* |
318 | * Try to enable the clock producer. | ||
319 | */ | ||
320 | retval = clk_enable(uap->clk); | ||
321 | if (retval) | ||
322 | goto out; | ||
323 | |||
324 | uap->port.uartclk = clk_get_rate(uap->clk); | ||
325 | |||
326 | /* | ||
309 | * Allocate the IRQ | 327 | * Allocate the IRQ |
310 | */ | 328 | */ |
311 | retval = request_irq(port->irq, pl010_int, 0, "uart-pl010", port); | 329 | retval = request_irq(uap->port.irq, pl010_int, 0, "uart-pl010", uap); |
312 | if (retval) | 330 | if (retval) |
313 | return retval; | 331 | goto clk_dis; |
314 | 332 | ||
315 | /* | 333 | /* |
316 | * initialise the old status of the modem signals | 334 | * initialise the old status of the modem signals |
317 | */ | 335 | */ |
318 | uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY; | 336 | uap->old_status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; |
319 | 337 | ||
320 | /* | 338 | /* |
321 | * Finally, enable interrupts | 339 | * Finally, enable interrupts |
322 | */ | 340 | */ |
323 | writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE, | 341 | writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE, |
324 | port->membase + UART010_CR); | 342 | uap->port.membase + UART010_CR); |
325 | 343 | ||
326 | return 0; | 344 | return 0; |
345 | |||
346 | clk_dis: | ||
347 | clk_disable(uap->clk); | ||
348 | out: | ||
349 | return retval; | ||
327 | } | 350 | } |
328 | 351 | ||
329 | static void pl010_shutdown(struct uart_port *port) | 352 | static void pl010_shutdown(struct uart_port *port) |
330 | { | 353 | { |
354 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
355 | |||
331 | /* | 356 | /* |
332 | * Free the interrupt | 357 | * Free the interrupt |
333 | */ | 358 | */ |
334 | free_irq(port->irq, port); | 359 | free_irq(uap->port.irq, uap); |
335 | 360 | ||
336 | /* | 361 | /* |
337 | * disable all interrupts, disable the port | 362 | * disable all interrupts, disable the port |
338 | */ | 363 | */ |
339 | writel(0, port->membase + UART010_CR); | 364 | writel(0, uap->port.membase + UART010_CR); |
340 | 365 | ||
341 | /* disable break condition and fifos */ | 366 | /* disable break condition and fifos */ |
342 | writel(readb(port->membase + UART010_LCRH) & | 367 | writel(readb(uap->port.membase + UART010_LCRH) & |
343 | ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN), | 368 | ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN), |
344 | port->membase + UART010_LCRH); | 369 | uap->port.membase + UART010_LCRH); |
370 | |||
371 | /* | ||
372 | * Shut down the clock producer | ||
373 | */ | ||
374 | clk_disable(uap->clk); | ||
345 | } | 375 | } |
346 | 376 | ||
347 | static void | 377 | static void |
348 | pl010_set_termios(struct uart_port *port, struct ktermios *termios, | 378 | pl010_set_termios(struct uart_port *port, struct ktermios *termios, |
349 | struct ktermios *old) | 379 | struct ktermios *old) |
350 | { | 380 | { |
381 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
351 | unsigned int lcr_h, old_cr; | 382 | unsigned int lcr_h, old_cr; |
352 | unsigned long flags; | 383 | unsigned long flags; |
353 | unsigned int baud, quot; | 384 | unsigned int baud, quot; |
@@ -355,7 +386,7 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, | |||
355 | /* | 386 | /* |
356 | * Ask the core to calculate the divisor for us. | 387 | * Ask the core to calculate the divisor for us. |
357 | */ | 388 | */ |
358 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 389 | baud = uart_get_baud_rate(port, termios, old, 0, uap->port.uartclk/16); |
359 | quot = uart_get_divisor(port, baud); | 390 | quot = uart_get_divisor(port, baud); |
360 | 391 | ||
361 | switch (termios->c_cflag & CSIZE) { | 392 | switch (termios->c_cflag & CSIZE) { |
@@ -379,66 +410,66 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, | |||
379 | if (!(termios->c_cflag & PARODD)) | 410 | if (!(termios->c_cflag & PARODD)) |
380 | lcr_h |= UART01x_LCRH_EPS; | 411 | lcr_h |= UART01x_LCRH_EPS; |
381 | } | 412 | } |
382 | if (port->fifosize > 1) | 413 | if (uap->port.fifosize > 1) |
383 | lcr_h |= UART01x_LCRH_FEN; | 414 | lcr_h |= UART01x_LCRH_FEN; |
384 | 415 | ||
385 | spin_lock_irqsave(&port->lock, flags); | 416 | spin_lock_irqsave(&uap->port.lock, flags); |
386 | 417 | ||
387 | /* | 418 | /* |
388 | * Update the per-port timeout. | 419 | * Update the per-port timeout. |
389 | */ | 420 | */ |
390 | uart_update_timeout(port, termios->c_cflag, baud); | 421 | uart_update_timeout(port, termios->c_cflag, baud); |
391 | 422 | ||
392 | port->read_status_mask = UART01x_RSR_OE; | 423 | uap->port.read_status_mask = UART01x_RSR_OE; |
393 | if (termios->c_iflag & INPCK) | 424 | if (termios->c_iflag & INPCK) |
394 | port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; | 425 | uap->port.read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; |
395 | if (termios->c_iflag & (BRKINT | PARMRK)) | 426 | if (termios->c_iflag & (BRKINT | PARMRK)) |
396 | port->read_status_mask |= UART01x_RSR_BE; | 427 | uap->port.read_status_mask |= UART01x_RSR_BE; |
397 | 428 | ||
398 | /* | 429 | /* |
399 | * Characters to ignore | 430 | * Characters to ignore |
400 | */ | 431 | */ |
401 | port->ignore_status_mask = 0; | 432 | uap->port.ignore_status_mask = 0; |
402 | if (termios->c_iflag & IGNPAR) | 433 | if (termios->c_iflag & IGNPAR) |
403 | port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; | 434 | uap->port.ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; |
404 | if (termios->c_iflag & IGNBRK) { | 435 | if (termios->c_iflag & IGNBRK) { |
405 | port->ignore_status_mask |= UART01x_RSR_BE; | 436 | uap->port.ignore_status_mask |= UART01x_RSR_BE; |
406 | /* | 437 | /* |
407 | * If we're ignoring parity and break indicators, | 438 | * If we're ignoring parity and break indicators, |
408 | * ignore overruns too (for real raw support). | 439 | * ignore overruns too (for real raw support). |
409 | */ | 440 | */ |
410 | if (termios->c_iflag & IGNPAR) | 441 | if (termios->c_iflag & IGNPAR) |
411 | port->ignore_status_mask |= UART01x_RSR_OE; | 442 | uap->port.ignore_status_mask |= UART01x_RSR_OE; |
412 | } | 443 | } |
413 | 444 | ||
414 | /* | 445 | /* |
415 | * Ignore all characters if CREAD is not set. | 446 | * Ignore all characters if CREAD is not set. |
416 | */ | 447 | */ |
417 | if ((termios->c_cflag & CREAD) == 0) | 448 | if ((termios->c_cflag & CREAD) == 0) |
418 | port->ignore_status_mask |= UART_DUMMY_RSR_RX; | 449 | uap->port.ignore_status_mask |= UART_DUMMY_RSR_RX; |
419 | 450 | ||
420 | /* first, disable everything */ | 451 | /* first, disable everything */ |
421 | old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE; | 452 | old_cr = readb(uap->port.membase + UART010_CR) & ~UART010_CR_MSIE; |
422 | 453 | ||
423 | if (UART_ENABLE_MS(port, termios->c_cflag)) | 454 | if (UART_ENABLE_MS(port, termios->c_cflag)) |
424 | old_cr |= UART010_CR_MSIE; | 455 | old_cr |= UART010_CR_MSIE; |
425 | 456 | ||
426 | writel(0, port->membase + UART010_CR); | 457 | writel(0, uap->port.membase + UART010_CR); |
427 | 458 | ||
428 | /* Set baud rate */ | 459 | /* Set baud rate */ |
429 | quot -= 1; | 460 | quot -= 1; |
430 | writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM); | 461 | writel((quot & 0xf00) >> 8, uap->port.membase + UART010_LCRM); |
431 | writel(quot & 0xff, port->membase + UART010_LCRL); | 462 | writel(quot & 0xff, uap->port.membase + UART010_LCRL); |
432 | 463 | ||
433 | /* | 464 | /* |
434 | * ----------v----------v----------v----------v----- | 465 | * ----------v----------v----------v----------v----- |
435 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L | 466 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L |
436 | * ----------^----------^----------^----------^----- | 467 | * ----------^----------^----------^----------^----- |
437 | */ | 468 | */ |
438 | writel(lcr_h, port->membase + UART010_LCRH); | 469 | writel(lcr_h, uap->port.membase + UART010_LCRH); |
439 | writel(old_cr, port->membase + UART010_CR); | 470 | writel(old_cr, uap->port.membase + UART010_CR); |
440 | 471 | ||
441 | spin_unlock_irqrestore(&port->lock, flags); | 472 | spin_unlock_irqrestore(&uap->port.lock, flags); |
442 | } | 473 | } |
443 | 474 | ||
444 | static const char *pl010_type(struct uart_port *port) | 475 | static const char *pl010_type(struct uart_port *port) |
@@ -514,47 +545,52 @@ static struct uart_amba_port *amba_ports[UART_NR]; | |||
514 | 545 | ||
515 | static void pl010_console_putchar(struct uart_port *port, int ch) | 546 | static void pl010_console_putchar(struct uart_port *port, int ch) |
516 | { | 547 | { |
548 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
517 | unsigned int status; | 549 | unsigned int status; |
518 | 550 | ||
519 | do { | 551 | do { |
520 | status = readb(port->membase + UART01x_FR); | 552 | status = readb(uap->port.membase + UART01x_FR); |
521 | barrier(); | 553 | barrier(); |
522 | } while (!UART_TX_READY(status)); | 554 | } while (!UART_TX_READY(status)); |
523 | writel(ch, port->membase + UART01x_DR); | 555 | writel(ch, uap->port.membase + UART01x_DR); |
524 | } | 556 | } |
525 | 557 | ||
526 | static void | 558 | static void |
527 | pl010_console_write(struct console *co, const char *s, unsigned int count) | 559 | pl010_console_write(struct console *co, const char *s, unsigned int count) |
528 | { | 560 | { |
529 | struct uart_port *port = &amba_ports[co->index]->port; | 561 | struct uart_amba_port *uap = amba_ports[co->index]; |
530 | unsigned int status, old_cr; | 562 | unsigned int status, old_cr; |
531 | 563 | ||
564 | clk_enable(uap->clk); | ||
565 | |||
532 | /* | 566 | /* |
533 | * First save the CR then disable the interrupts | 567 | * First save the CR then disable the interrupts |
534 | */ | 568 | */ |
535 | old_cr = readb(port->membase + UART010_CR); | 569 | old_cr = readb(uap->port.membase + UART010_CR); |
536 | writel(UART01x_CR_UARTEN, port->membase + UART010_CR); | 570 | writel(UART01x_CR_UARTEN, uap->port.membase + UART010_CR); |
537 | 571 | ||
538 | uart_console_write(port, s, count, pl010_console_putchar); | 572 | uart_console_write(&uap->port, s, count, pl010_console_putchar); |
539 | 573 | ||
540 | /* | 574 | /* |
541 | * Finally, wait for transmitter to become empty | 575 | * Finally, wait for transmitter to become empty |
542 | * and restore the TCR | 576 | * and restore the TCR |
543 | */ | 577 | */ |
544 | do { | 578 | do { |
545 | status = readb(port->membase + UART01x_FR); | 579 | status = readb(uap->port.membase + UART01x_FR); |
546 | barrier(); | 580 | barrier(); |
547 | } while (status & UART01x_FR_BUSY); | 581 | } while (status & UART01x_FR_BUSY); |
548 | writel(old_cr, port->membase + UART010_CR); | 582 | writel(old_cr, uap->port.membase + UART010_CR); |
583 | |||
584 | clk_disable(uap->clk); | ||
549 | } | 585 | } |
550 | 586 | ||
551 | static void __init | 587 | static void __init |
552 | pl010_console_get_options(struct uart_port *port, int *baud, | 588 | pl010_console_get_options(struct uart_amba_port *uap, int *baud, |
553 | int *parity, int *bits) | 589 | int *parity, int *bits) |
554 | { | 590 | { |
555 | if (readb(port->membase + UART010_CR) & UART01x_CR_UARTEN) { | 591 | if (readb(uap->port.membase + UART010_CR) & UART01x_CR_UARTEN) { |
556 | unsigned int lcr_h, quot; | 592 | unsigned int lcr_h, quot; |
557 | lcr_h = readb(port->membase + UART010_LCRH); | 593 | lcr_h = readb(uap->port.membase + UART010_LCRH); |
558 | 594 | ||
559 | *parity = 'n'; | 595 | *parity = 'n'; |
560 | if (lcr_h & UART01x_LCRH_PEN) { | 596 | if (lcr_h & UART01x_LCRH_PEN) { |
@@ -569,14 +605,15 @@ pl010_console_get_options(struct uart_port *port, int *baud, | |||
569 | else | 605 | else |
570 | *bits = 8; | 606 | *bits = 8; |
571 | 607 | ||
572 | quot = readb(port->membase + UART010_LCRL) | readb(port->membase + UART010_LCRM) << 8; | 608 | quot = readb(uap->port.membase + UART010_LCRL) | |
573 | *baud = port->uartclk / (16 * (quot + 1)); | 609 | readb(uap->port.membase + UART010_LCRM) << 8; |
610 | *baud = uap->port.uartclk / (16 * (quot + 1)); | ||
574 | } | 611 | } |
575 | } | 612 | } |
576 | 613 | ||
577 | static int __init pl010_console_setup(struct console *co, char *options) | 614 | static int __init pl010_console_setup(struct console *co, char *options) |
578 | { | 615 | { |
579 | struct uart_port *port; | 616 | struct uart_amba_port *uap; |
580 | int baud = 38400; | 617 | int baud = 38400; |
581 | int bits = 8; | 618 | int bits = 8; |
582 | int parity = 'n'; | 619 | int parity = 'n'; |
@@ -589,16 +626,18 @@ static int __init pl010_console_setup(struct console *co, char *options) | |||
589 | */ | 626 | */ |
590 | if (co->index >= UART_NR) | 627 | if (co->index >= UART_NR) |
591 | co->index = 0; | 628 | co->index = 0; |
592 | if (!amba_ports[co->index]) | 629 | uap = amba_ports[co->index]; |
630 | if (!uap) | ||
593 | return -ENODEV; | 631 | return -ENODEV; |
594 | port = &amba_ports[co->index]->port; | 632 | |
633 | uap->port.uartclk = clk_get_rate(uap->clk); | ||
595 | 634 | ||
596 | if (options) | 635 | if (options) |
597 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 636 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
598 | else | 637 | else |
599 | pl010_console_get_options(port, &baud, &parity, &bits); | 638 | pl010_console_get_options(uap, &baud, &parity, &bits); |
600 | 639 | ||
601 | return uart_set_options(port, co, baud, parity, bits, flow); | 640 | return uart_set_options(&uap->port, co, baud, parity, bits, flow); |
602 | } | 641 | } |
603 | 642 | ||
604 | static struct uart_driver amba_reg; | 643 | static struct uart_driver amba_reg; |
@@ -629,7 +668,7 @@ static struct uart_driver amba_reg = { | |||
629 | 668 | ||
630 | static int pl010_probe(struct amba_device *dev, void *id) | 669 | static int pl010_probe(struct amba_device *dev, void *id) |
631 | { | 670 | { |
632 | struct uart_amba_port *port; | 671 | struct uart_amba_port *uap; |
633 | void __iomem *base; | 672 | void __iomem *base; |
634 | int i, ret; | 673 | int i, ret; |
635 | 674 | ||
@@ -642,8 +681,8 @@ static int pl010_probe(struct amba_device *dev, void *id) | |||
642 | goto out; | 681 | goto out; |
643 | } | 682 | } |
644 | 683 | ||
645 | port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); | 684 | uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); |
646 | if (!port) { | 685 | if (!uap) { |
647 | ret = -ENOMEM; | 686 | ret = -ENOMEM; |
648 | goto out; | 687 | goto out; |
649 | } | 688 | } |
@@ -654,51 +693,57 @@ static int pl010_probe(struct amba_device *dev, void *id) | |||
654 | goto free; | 693 | goto free; |
655 | } | 694 | } |
656 | 695 | ||
657 | port->port.dev = &dev->dev; | 696 | uap->clk = clk_get(&dev->dev, "UARTCLK"); |
658 | port->port.mapbase = dev->res.start; | 697 | if (IS_ERR(uap->clk)) { |
659 | port->port.membase = base; | 698 | ret = PTR_ERR(uap->clk); |
660 | port->port.iotype = UPIO_MEM; | 699 | goto unmap; |
661 | port->port.irq = dev->irq[0]; | 700 | } |
662 | port->port.uartclk = 14745600; | 701 | |
663 | port->port.fifosize = 16; | 702 | uap->port.dev = &dev->dev; |
664 | port->port.ops = &amba_pl010_pops; | 703 | uap->port.mapbase = dev->res.start; |
665 | port->port.flags = UPF_BOOT_AUTOCONF; | 704 | uap->port.membase = base; |
666 | port->port.line = i; | 705 | uap->port.iotype = UPIO_MEM; |
667 | port->dev = dev; | 706 | uap->port.irq = dev->irq[0]; |
668 | port->data = dev->dev.platform_data; | 707 | uap->port.fifosize = 16; |
669 | 708 | uap->port.ops = &amba_pl010_pops; | |
670 | amba_ports[i] = port; | 709 | uap->port.flags = UPF_BOOT_AUTOCONF; |
671 | 710 | uap->port.line = i; | |
672 | amba_set_drvdata(dev, port); | 711 | uap->dev = dev; |
673 | ret = uart_add_one_port(&amba_reg, &port->port); | 712 | uap->data = dev->dev.platform_data; |
713 | |||
714 | amba_ports[i] = uap; | ||
715 | |||
716 | amba_set_drvdata(dev, uap); | ||
717 | ret = uart_add_one_port(&amba_reg, &uap->port); | ||
674 | if (ret) { | 718 | if (ret) { |
675 | amba_set_drvdata(dev, NULL); | 719 | amba_set_drvdata(dev, NULL); |
676 | amba_ports[i] = NULL; | 720 | amba_ports[i] = NULL; |
721 | clk_put(uap->clk); | ||
722 | unmap: | ||
677 | iounmap(base); | 723 | iounmap(base); |
678 | free: | 724 | free: |
679 | kfree(port); | 725 | kfree(uap); |
680 | } | 726 | } |
681 | |||
682 | out: | 727 | out: |
683 | return ret; | 728 | return ret; |
684 | } | 729 | } |
685 | 730 | ||
686 | static int pl010_remove(struct amba_device *dev) | 731 | static int pl010_remove(struct amba_device *dev) |
687 | { | 732 | { |
688 | struct uart_amba_port *port = amba_get_drvdata(dev); | 733 | struct uart_amba_port *uap = amba_get_drvdata(dev); |
689 | int i; | 734 | int i; |
690 | 735 | ||
691 | amba_set_drvdata(dev, NULL); | 736 | amba_set_drvdata(dev, NULL); |
692 | 737 | ||
693 | uart_remove_one_port(&amba_reg, &port->port); | 738 | uart_remove_one_port(&amba_reg, &uap->port); |
694 | 739 | ||
695 | for (i = 0; i < ARRAY_SIZE(amba_ports); i++) | 740 | for (i = 0; i < ARRAY_SIZE(amba_ports); i++) |
696 | if (amba_ports[i] == port) | 741 | if (amba_ports[i] == uap) |
697 | amba_ports[i] = NULL; | 742 | amba_ports[i] = NULL; |
698 | 743 | ||
699 | iounmap(port->port.membase); | 744 | iounmap(uap->port.membase); |
700 | kfree(port); | 745 | clk_put(uap->clk); |
701 | 746 | kfree(uap); | |
702 | return 0; | 747 | return 0; |
703 | } | 748 | } |
704 | 749 | ||
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 935f48fa501..3320bcd92c0 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -484,11 +484,16 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios * termios, | |||
484 | unsigned long flags; | 484 | unsigned long flags; |
485 | unsigned int mode, imr, quot, baud; | 485 | unsigned int mode, imr, quot, baud; |
486 | 486 | ||
487 | /* Get current mode register */ | ||
488 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR); | ||
489 | |||
487 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 490 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
488 | quot = uart_get_divisor(port, baud); | 491 | quot = uart_get_divisor(port, baud); |
489 | 492 | ||
490 | /* Get current mode register */ | 493 | if (quot > 65535) { /* BRGR is 16-bit, so switch to slower clock */ |
491 | mode = UART_GET_MR(port) & ~(ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR); | 494 | quot /= 8; |
495 | mode |= ATMEL_US_USCLKS_MCK_DIV8; | ||
496 | } | ||
492 | 497 | ||
493 | /* byte size */ | 498 | /* byte size */ |
494 | switch (termios->c_cflag & CSIZE) { | 499 | switch (termios->c_cflag & CSIZE) { |
diff --git a/drivers/serial/atmel_serial.h b/drivers/serial/atmel_serial.h index 11b44360e10..e0141776517 100644 --- a/drivers/serial/atmel_serial.h +++ b/drivers/serial/atmel_serial.h | |||
@@ -46,6 +46,9 @@ | |||
46 | #define ATMEL_US_USMODE_ISO7816_T1 6 | 46 | #define ATMEL_US_USMODE_ISO7816_T1 6 |
47 | #define ATMEL_US_USMODE_IRDA 8 | 47 | #define ATMEL_US_USMODE_IRDA 8 |
48 | #define ATMEL_US_USCLKS (3 << 4) /* Clock Selection */ | 48 | #define ATMEL_US_USCLKS (3 << 4) /* Clock Selection */ |
49 | #define ATMEL_US_USCLKS_MCK (0 << 4) | ||
50 | #define ATMEL_US_USCLKS_MCK_DIV8 (1 << 4) | ||
51 | #define ATMEL_US_USCLKS_SCK (3 << 4) | ||
49 | #define ATMEL_US_CHRL (3 << 6) /* Character Length */ | 52 | #define ATMEL_US_CHRL (3 << 6) /* Character Length */ |
50 | #define ATMEL_US_CHRL_5 (0 << 6) | 53 | #define ATMEL_US_CHRL_5 (0 << 6) |
51 | #define ATMEL_US_CHRL_6 (1 << 6) | 54 | #define ATMEL_US_CHRL_6 (1 << 6) |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c new file mode 100644 index 00000000000..408390f93db --- /dev/null +++ b/drivers/serial/bfin_5xx.c | |||
@@ -0,0 +1,1012 @@ | |||
1 | /* | ||
2 | * File: drivers/serial/bfin_5xx.c | ||
3 | * Based on: Based on drivers/serial/sa1100.c | ||
4 | * Author: Aubrey Li <aubrey.li@analog.com> | ||
5 | * | ||
6 | * Created: | ||
7 | * Description: Driver for blackfin 5xx serial ports | ||
8 | * | ||
9 | * Rev: $Id: bfin_5xx.c,v 1.19 2006/09/24 02:33:53 aubrey Exp $ | ||
10 | * | ||
11 | * Modified: | ||
12 | * Copyright 2006 Analog Devices Inc. | ||
13 | * | ||
14 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, see the file COPYING, or write | ||
28 | * to the Free Software Foundation, Inc., | ||
29 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
30 | */ | ||
31 | |||
32 | #if defined(CONFIG_SERIAL_BFIN_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
33 | #define SUPPORT_SYSRQ | ||
34 | #endif | ||
35 | |||
36 | #include <linux/module.h> | ||
37 | #include <linux/ioport.h> | ||
38 | #include <linux/init.h> | ||
39 | #include <linux/console.h> | ||
40 | #include <linux/sysrq.h> | ||
41 | #include <linux/platform_device.h> | ||
42 | #include <linux/tty.h> | ||
43 | #include <linux/tty_flip.h> | ||
44 | #include <linux/serial_core.h> | ||
45 | |||
46 | #include <asm/gpio.h> | ||
47 | #include <asm/mach/bfin_serial_5xx.h> | ||
48 | |||
49 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
50 | #include <linux/dma-mapping.h> | ||
51 | #include <asm/io.h> | ||
52 | #include <asm/irq.h> | ||
53 | #include <asm/cacheflush.h> | ||
54 | #endif | ||
55 | |||
56 | /* UART name and device definitions */ | ||
57 | #define BFIN_SERIAL_NAME "ttyBF" | ||
58 | #define BFIN_SERIAL_MAJOR 204 | ||
59 | #define BFIN_SERIAL_MINOR 64 | ||
60 | |||
61 | /* | ||
62 | * Setup for console. Argument comes from the menuconfig | ||
63 | */ | ||
64 | #define DMA_RX_XCOUNT 512 | ||
65 | #define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT) | ||
66 | |||
67 | #define DMA_RX_FLUSH_JIFFIES 5 | ||
68 | |||
69 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
70 | static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); | ||
71 | #else | ||
72 | static void bfin_serial_do_work(struct work_struct *work); | ||
73 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart); | ||
74 | static void local_put_char(struct bfin_serial_port *uart, char ch); | ||
75 | #endif | ||
76 | |||
77 | static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); | ||
78 | |||
79 | /* | ||
80 | * interrupts are disabled on entry | ||
81 | */ | ||
82 | static void bfin_serial_stop_tx(struct uart_port *port) | ||
83 | { | ||
84 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
85 | |||
86 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
87 | disable_dma(uart->tx_dma_channel); | ||
88 | #else | ||
89 | unsigned short ier; | ||
90 | |||
91 | ier = UART_GET_IER(uart); | ||
92 | ier &= ~ETBEI; | ||
93 | UART_PUT_IER(uart, ier); | ||
94 | #endif | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * port is locked and interrupts are disabled | ||
99 | */ | ||
100 | static void bfin_serial_start_tx(struct uart_port *port) | ||
101 | { | ||
102 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
103 | |||
104 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
105 | bfin_serial_dma_tx_chars(uart); | ||
106 | #else | ||
107 | unsigned short ier; | ||
108 | ier = UART_GET_IER(uart); | ||
109 | ier |= ETBEI; | ||
110 | UART_PUT_IER(uart, ier); | ||
111 | bfin_serial_tx_chars(uart); | ||
112 | #endif | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Interrupts are enabled | ||
117 | */ | ||
118 | static void bfin_serial_stop_rx(struct uart_port *port) | ||
119 | { | ||
120 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
121 | unsigned short ier; | ||
122 | |||
123 | ier = UART_GET_IER(uart); | ||
124 | ier &= ~ERBFI; | ||
125 | UART_PUT_IER(uart, ier); | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Set the modem control timer to fire immediately. | ||
130 | */ | ||
131 | static void bfin_serial_enable_ms(struct uart_port *port) | ||
132 | { | ||
133 | } | ||
134 | |||
135 | #ifdef CONFIG_SERIAL_BFIN_PIO | ||
136 | static void local_put_char(struct bfin_serial_port *uart, char ch) | ||
137 | { | ||
138 | unsigned short status; | ||
139 | int flags = 0; | ||
140 | |||
141 | spin_lock_irqsave(&uart->port.lock, flags); | ||
142 | |||
143 | do { | ||
144 | status = UART_GET_LSR(uart); | ||
145 | } while (!(status & THRE)); | ||
146 | |||
147 | UART_PUT_CHAR(uart, ch); | ||
148 | SSYNC(); | ||
149 | |||
150 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
151 | } | ||
152 | |||
153 | static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | ||
154 | { | ||
155 | struct tty_struct *tty = uart->port.info?uart->port.info->tty:0; | ||
156 | unsigned int status, ch, flg; | ||
157 | #ifdef BF533_FAMILY | ||
158 | static int in_break = 0; | ||
159 | #endif | ||
160 | |||
161 | status = UART_GET_LSR(uart); | ||
162 | ch = UART_GET_CHAR(uart); | ||
163 | uart->port.icount.rx++; | ||
164 | |||
165 | #ifdef BF533_FAMILY | ||
166 | /* The BF533 family of processors have a nice misbehavior where | ||
167 | * they continuously generate characters for a "single" break. | ||
168 | * We have to basically ignore this flood until the "next" valid | ||
169 | * character comes across. All other Blackfin families operate | ||
170 | * properly though. | ||
171 | */ | ||
172 | if (in_break) { | ||
173 | if (ch != 0) { | ||
174 | in_break = 0; | ||
175 | ch = UART_GET_CHAR(uart); | ||
176 | } | ||
177 | return; | ||
178 | } | ||
179 | #endif | ||
180 | |||
181 | if (status & BI) { | ||
182 | #ifdef BF533_FAMILY | ||
183 | in_break = 1; | ||
184 | #endif | ||
185 | uart->port.icount.brk++; | ||
186 | if (uart_handle_break(&uart->port)) | ||
187 | goto ignore_char; | ||
188 | flg = TTY_BREAK; | ||
189 | } else if (status & PE) { | ||
190 | flg = TTY_PARITY; | ||
191 | uart->port.icount.parity++; | ||
192 | } else if (status & OE) { | ||
193 | flg = TTY_OVERRUN; | ||
194 | uart->port.icount.overrun++; | ||
195 | } else if (status & FE) { | ||
196 | flg = TTY_FRAME; | ||
197 | uart->port.icount.frame++; | ||
198 | } else | ||
199 | flg = TTY_NORMAL; | ||
200 | |||
201 | if (uart_handle_sysrq_char(&uart->port, ch)) | ||
202 | goto ignore_char; | ||
203 | if (tty) | ||
204 | uart_insert_char(&uart->port, status, 2, ch, flg); | ||
205 | |||
206 | ignore_char: | ||
207 | if (tty) | ||
208 | tty_flip_buffer_push(tty); | ||
209 | } | ||
210 | |||
211 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | ||
212 | { | ||
213 | struct circ_buf *xmit = &uart->port.info->xmit; | ||
214 | |||
215 | if (uart->port.x_char) { | ||
216 | UART_PUT_CHAR(uart, uart->port.x_char); | ||
217 | uart->port.icount.tx++; | ||
218 | uart->port.x_char = 0; | ||
219 | return; | ||
220 | } | ||
221 | /* | ||
222 | * Check the modem control lines before | ||
223 | * transmitting anything. | ||
224 | */ | ||
225 | bfin_serial_mctrl_check(uart); | ||
226 | |||
227 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { | ||
228 | bfin_serial_stop_tx(&uart->port); | ||
229 | return; | ||
230 | } | ||
231 | |||
232 | local_put_char(uart, xmit->buf[xmit->tail]); | ||
233 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
234 | uart->port.icount.tx++; | ||
235 | |||
236 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
237 | uart_write_wakeup(&uart->port); | ||
238 | |||
239 | if (uart_circ_empty(xmit)) | ||
240 | bfin_serial_stop_tx(&uart->port); | ||
241 | } | ||
242 | |||
243 | static irqreturn_t bfin_serial_int(int irq, void *dev_id) | ||
244 | { | ||
245 | struct bfin_serial_port *uart = dev_id; | ||
246 | unsigned short status; | ||
247 | |||
248 | spin_lock(&uart->port.lock); | ||
249 | status = UART_GET_IIR(uart); | ||
250 | do { | ||
251 | if ((status & IIR_STATUS) == IIR_TX_READY) | ||
252 | bfin_serial_tx_chars(uart); | ||
253 | if ((status & IIR_STATUS) == IIR_RX_READY) | ||
254 | bfin_serial_rx_chars(uart); | ||
255 | status = UART_GET_IIR(uart); | ||
256 | } while (status & (IIR_TX_READY | IIR_RX_READY)); | ||
257 | spin_unlock(&uart->port.lock); | ||
258 | return IRQ_HANDLED; | ||
259 | } | ||
260 | |||
261 | static void bfin_serial_do_work(struct work_struct *work) | ||
262 | { | ||
263 | struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue); | ||
264 | |||
265 | bfin_serial_mctrl_check(uart); | ||
266 | } | ||
267 | |||
268 | #endif | ||
269 | |||
270 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
271 | static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | ||
272 | { | ||
273 | struct circ_buf *xmit = &uart->port.info->xmit; | ||
274 | unsigned short ier; | ||
275 | int flags = 0; | ||
276 | |||
277 | if (!uart->tx_done) | ||
278 | return; | ||
279 | |||
280 | uart->tx_done = 0; | ||
281 | |||
282 | if (uart->port.x_char) { | ||
283 | UART_PUT_CHAR(uart, uart->port.x_char); | ||
284 | uart->port.icount.tx++; | ||
285 | uart->port.x_char = 0; | ||
286 | uart->tx_done = 1; | ||
287 | return; | ||
288 | } | ||
289 | /* | ||
290 | * Check the modem control lines before | ||
291 | * transmitting anything. | ||
292 | */ | ||
293 | bfin_serial_mctrl_check(uart); | ||
294 | |||
295 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { | ||
296 | bfin_serial_stop_tx(&uart->port); | ||
297 | uart->tx_done = 1; | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | spin_lock_irqsave(&uart->port.lock, flags); | ||
302 | uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
303 | if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail)) | ||
304 | uart->tx_count = UART_XMIT_SIZE - xmit->tail; | ||
305 | blackfin_dcache_flush_range((unsigned long)(xmit->buf+xmit->tail), | ||
306 | (unsigned long)(xmit->buf+xmit->tail+uart->tx_count)); | ||
307 | set_dma_config(uart->tx_dma_channel, | ||
308 | set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP, | ||
309 | INTR_ON_BUF, | ||
310 | DIMENSION_LINEAR, | ||
311 | DATA_SIZE_8)); | ||
312 | set_dma_start_addr(uart->tx_dma_channel, (unsigned long)(xmit->buf+xmit->tail)); | ||
313 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); | ||
314 | set_dma_x_modify(uart->tx_dma_channel, 1); | ||
315 | enable_dma(uart->tx_dma_channel); | ||
316 | ier = UART_GET_IER(uart); | ||
317 | ier |= ETBEI; | ||
318 | UART_PUT_IER(uart, ier); | ||
319 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
320 | } | ||
321 | |||
322 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port * uart) | ||
323 | { | ||
324 | struct tty_struct *tty = uart->port.info->tty; | ||
325 | int i, flg, status; | ||
326 | |||
327 | status = UART_GET_LSR(uart); | ||
328 | uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);; | ||
329 | |||
330 | if (status & BI) { | ||
331 | uart->port.icount.brk++; | ||
332 | if (uart_handle_break(&uart->port)) | ||
333 | goto dma_ignore_char; | ||
334 | flg = TTY_BREAK; | ||
335 | } else if (status & PE) { | ||
336 | flg = TTY_PARITY; | ||
337 | uart->port.icount.parity++; | ||
338 | } else if (status & OE) { | ||
339 | flg = TTY_OVERRUN; | ||
340 | uart->port.icount.overrun++; | ||
341 | } else if (status & FE) { | ||
342 | flg = TTY_FRAME; | ||
343 | uart->port.icount.frame++; | ||
344 | } else | ||
345 | flg = TTY_NORMAL; | ||
346 | |||
347 | for (i = uart->rx_dma_buf.head; i < uart->rx_dma_buf.tail; i++) { | ||
348 | if (uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) | ||
349 | goto dma_ignore_char; | ||
350 | uart_insert_char(&uart->port, status, 2, uart->rx_dma_buf.buf[i], flg); | ||
351 | } | ||
352 | dma_ignore_char: | ||
353 | tty_flip_buffer_push(tty); | ||
354 | } | ||
355 | |||
356 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | ||
357 | { | ||
358 | int x_pos, pos; | ||
359 | int flags = 0; | ||
360 | |||
361 | bfin_serial_dma_tx_chars(uart); | ||
362 | |||
363 | spin_lock_irqsave(&uart->port.lock, flags); | ||
364 | x_pos = DMA_RX_XCOUNT - get_dma_curr_xcount(uart->rx_dma_channel); | ||
365 | if (x_pos == DMA_RX_XCOUNT) | ||
366 | x_pos = 0; | ||
367 | |||
368 | pos = uart->rx_dma_nrows * DMA_RX_XCOUNT + x_pos; | ||
369 | |||
370 | if (pos>uart->rx_dma_buf.tail) { | ||
371 | uart->rx_dma_buf.tail = pos; | ||
372 | bfin_serial_dma_rx_chars(uart); | ||
373 | uart->rx_dma_buf.head = uart->rx_dma_buf.tail; | ||
374 | } | ||
375 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
376 | uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; | ||
377 | add_timer(&(uart->rx_dma_timer)); | ||
378 | } | ||
379 | |||
380 | static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) | ||
381 | { | ||
382 | struct bfin_serial_port *uart = dev_id; | ||
383 | struct circ_buf *xmit = &uart->port.info->xmit; | ||
384 | unsigned short ier; | ||
385 | |||
386 | spin_lock(&uart->port.lock); | ||
387 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { | ||
388 | clear_dma_irqstat(uart->tx_dma_channel); | ||
389 | disable_dma(uart->tx_dma_channel); | ||
390 | ier = UART_GET_IER(uart); | ||
391 | ier &= ~ETBEI; | ||
392 | UART_PUT_IER(uart, ier); | ||
393 | xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); | ||
394 | uart->port.icount.tx+=uart->tx_count; | ||
395 | |||
396 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
397 | uart_write_wakeup(&uart->port); | ||
398 | |||
399 | if (uart_circ_empty(xmit)) | ||
400 | bfin_serial_stop_tx(&uart->port); | ||
401 | uart->tx_done = 1; | ||
402 | } | ||
403 | |||
404 | spin_unlock(&uart->port.lock); | ||
405 | return IRQ_HANDLED; | ||
406 | } | ||
407 | |||
408 | static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) | ||
409 | { | ||
410 | struct bfin_serial_port *uart = dev_id; | ||
411 | unsigned short irqstat; | ||
412 | |||
413 | uart->rx_dma_nrows++; | ||
414 | if (uart->rx_dma_nrows == DMA_RX_YCOUNT) { | ||
415 | uart->rx_dma_nrows = 0; | ||
416 | uart->rx_dma_buf.tail = DMA_RX_XCOUNT*DMA_RX_YCOUNT; | ||
417 | bfin_serial_dma_rx_chars(uart); | ||
418 | uart->rx_dma_buf.head = uart->rx_dma_buf.tail = 0; | ||
419 | } | ||
420 | spin_lock(&uart->port.lock); | ||
421 | irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); | ||
422 | clear_dma_irqstat(uart->rx_dma_channel); | ||
423 | |||
424 | spin_unlock(&uart->port.lock); | ||
425 | return IRQ_HANDLED; | ||
426 | } | ||
427 | #endif | ||
428 | |||
429 | /* | ||
430 | * Return TIOCSER_TEMT when transmitter is not busy. | ||
431 | */ | ||
432 | static unsigned int bfin_serial_tx_empty(struct uart_port *port) | ||
433 | { | ||
434 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
435 | unsigned short lsr; | ||
436 | |||
437 | lsr = UART_GET_LSR(uart); | ||
438 | if (lsr & TEMT) | ||
439 | return TIOCSER_TEMT; | ||
440 | else | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static unsigned int bfin_serial_get_mctrl(struct uart_port *port) | ||
445 | { | ||
446 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
447 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
448 | if (uart->cts_pin < 0) | ||
449 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
450 | |||
451 | if (gpio_get_value(uart->cts_pin)) | ||
452 | return TIOCM_DSR | TIOCM_CAR; | ||
453 | else | ||
454 | #endif | ||
455 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
456 | } | ||
457 | |||
458 | static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
459 | { | ||
460 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
461 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
462 | if (uart->rts_pin < 0) | ||
463 | return; | ||
464 | |||
465 | if (mctrl & TIOCM_RTS) | ||
466 | gpio_set_value(uart->rts_pin, 0); | ||
467 | else | ||
468 | gpio_set_value(uart->rts_pin, 1); | ||
469 | #endif | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * Handle any change of modem status signal since we were last called. | ||
474 | */ | ||
475 | static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) | ||
476 | { | ||
477 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
478 | unsigned int status; | ||
479 | # ifdef CONFIG_SERIAL_BFIN_DMA | ||
480 | struct uart_info *info = uart->port.info; | ||
481 | struct tty_struct *tty = info->tty; | ||
482 | |||
483 | status = bfin_serial_get_mctrl(&uart->port); | ||
484 | if (!(status & TIOCM_CTS)) { | ||
485 | tty->hw_stopped = 1; | ||
486 | } else { | ||
487 | tty->hw_stopped = 0; | ||
488 | } | ||
489 | # else | ||
490 | status = bfin_serial_get_mctrl(&uart->port); | ||
491 | uart_handle_cts_change(&uart->port, status & TIOCM_CTS); | ||
492 | if (!(status & TIOCM_CTS)) | ||
493 | schedule_work(&uart->cts_workqueue); | ||
494 | # endif | ||
495 | #endif | ||
496 | } | ||
497 | |||
498 | /* | ||
499 | * Interrupts are always disabled. | ||
500 | */ | ||
501 | static void bfin_serial_break_ctl(struct uart_port *port, int break_state) | ||
502 | { | ||
503 | } | ||
504 | |||
505 | static int bfin_serial_startup(struct uart_port *port) | ||
506 | { | ||
507 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
508 | |||
509 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
510 | dma_addr_t dma_handle; | ||
511 | |||
512 | if (request_dma(uart->rx_dma_channel, "BFIN_UART_RX") < 0) { | ||
513 | printk(KERN_NOTICE "Unable to attach Blackfin UART RX DMA channel\n"); | ||
514 | return -EBUSY; | ||
515 | } | ||
516 | |||
517 | if (request_dma(uart->tx_dma_channel, "BFIN_UART_TX") < 0) { | ||
518 | printk(KERN_NOTICE "Unable to attach Blackfin UART TX DMA channel\n"); | ||
519 | free_dma(uart->rx_dma_channel); | ||
520 | return -EBUSY; | ||
521 | } | ||
522 | |||
523 | set_dma_callback(uart->rx_dma_channel, bfin_serial_dma_rx_int, uart); | ||
524 | set_dma_callback(uart->tx_dma_channel, bfin_serial_dma_tx_int, uart); | ||
525 | |||
526 | uart->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA); | ||
527 | uart->rx_dma_buf.head = 0; | ||
528 | uart->rx_dma_buf.tail = 0; | ||
529 | uart->rx_dma_nrows = 0; | ||
530 | |||
531 | set_dma_config(uart->rx_dma_channel, | ||
532 | set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO, | ||
533 | INTR_ON_ROW, DIMENSION_2D, | ||
534 | DATA_SIZE_8)); | ||
535 | set_dma_x_count(uart->rx_dma_channel, DMA_RX_XCOUNT); | ||
536 | set_dma_x_modify(uart->rx_dma_channel, 1); | ||
537 | set_dma_y_count(uart->rx_dma_channel, DMA_RX_YCOUNT); | ||
538 | set_dma_y_modify(uart->rx_dma_channel, 1); | ||
539 | set_dma_start_addr(uart->rx_dma_channel, (unsigned long)uart->rx_dma_buf.buf); | ||
540 | enable_dma(uart->rx_dma_channel); | ||
541 | |||
542 | uart->rx_dma_timer.data = (unsigned long)(uart); | ||
543 | uart->rx_dma_timer.function = (void *)bfin_serial_rx_dma_timeout; | ||
544 | uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; | ||
545 | add_timer(&(uart->rx_dma_timer)); | ||
546 | #else | ||
547 | if (request_irq | ||
548 | (uart->port.irq, bfin_serial_int, IRQF_DISABLED, | ||
549 | "BFIN_UART_RX", uart)) { | ||
550 | printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); | ||
551 | return -EBUSY; | ||
552 | } | ||
553 | |||
554 | if (request_irq | ||
555 | (uart->port.irq+1, bfin_serial_int, IRQF_DISABLED, | ||
556 | "BFIN_UART_TX", uart)) { | ||
557 | printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n"); | ||
558 | free_irq(uart->port.irq, uart); | ||
559 | return -EBUSY; | ||
560 | } | ||
561 | #endif | ||
562 | UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); | ||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static void bfin_serial_shutdown(struct uart_port *port) | ||
567 | { | ||
568 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
569 | |||
570 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
571 | disable_dma(uart->tx_dma_channel); | ||
572 | free_dma(uart->tx_dma_channel); | ||
573 | disable_dma(uart->rx_dma_channel); | ||
574 | free_dma(uart->rx_dma_channel); | ||
575 | del_timer(&(uart->rx_dma_timer)); | ||
576 | #else | ||
577 | free_irq(uart->port.irq, uart); | ||
578 | free_irq(uart->port.irq+1, uart); | ||
579 | #endif | ||
580 | } | ||
581 | |||
582 | static void | ||
583 | bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | ||
584 | struct ktermios *old) | ||
585 | { | ||
586 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
587 | unsigned long flags; | ||
588 | unsigned int baud, quot; | ||
589 | unsigned short val, ier, lsr, lcr = 0; | ||
590 | |||
591 | switch (termios->c_cflag & CSIZE) { | ||
592 | case CS8: | ||
593 | lcr = WLS(8); | ||
594 | break; | ||
595 | case CS7: | ||
596 | lcr = WLS(7); | ||
597 | break; | ||
598 | case CS6: | ||
599 | lcr = WLS(6); | ||
600 | break; | ||
601 | case CS5: | ||
602 | lcr = WLS(5); | ||
603 | break; | ||
604 | default: | ||
605 | printk(KERN_ERR "%s: word lengh not supported\n", | ||
606 | __FUNCTION__); | ||
607 | } | ||
608 | |||
609 | if (termios->c_cflag & CSTOPB) | ||
610 | lcr |= STB; | ||
611 | if (termios->c_cflag & PARENB) { | ||
612 | lcr |= PEN; | ||
613 | if (!(termios->c_cflag & PARODD)) | ||
614 | lcr |= EPS; | ||
615 | } | ||
616 | |||
617 | /* These controls are not implemented for this port */ | ||
618 | termios->c_iflag |= INPCK | BRKINT | PARMRK; | ||
619 | termios->c_iflag &= ~(IGNPAR | IGNBRK); | ||
620 | |||
621 | /* These controls are not implemented for this port */ | ||
622 | termios->c_iflag |= INPCK | BRKINT | PARMRK; | ||
623 | termios->c_iflag &= ~(IGNPAR | IGNBRK); | ||
624 | |||
625 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | ||
626 | quot = uart_get_divisor(port, baud); | ||
627 | spin_lock_irqsave(&uart->port.lock, flags); | ||
628 | |||
629 | do { | ||
630 | lsr = UART_GET_LSR(uart); | ||
631 | } while (!(lsr & TEMT)); | ||
632 | |||
633 | /* Disable UART */ | ||
634 | ier = UART_GET_IER(uart); | ||
635 | UART_PUT_IER(uart, 0); | ||
636 | |||
637 | /* Set DLAB in LCR to Access DLL and DLH */ | ||
638 | val = UART_GET_LCR(uart); | ||
639 | val |= DLAB; | ||
640 | UART_PUT_LCR(uart, val); | ||
641 | SSYNC(); | ||
642 | |||
643 | UART_PUT_DLL(uart, quot & 0xFF); | ||
644 | SSYNC(); | ||
645 | UART_PUT_DLH(uart, (quot >> 8) & 0xFF); | ||
646 | SSYNC(); | ||
647 | |||
648 | /* Clear DLAB in LCR to Access THR RBR IER */ | ||
649 | val = UART_GET_LCR(uart); | ||
650 | val &= ~DLAB; | ||
651 | UART_PUT_LCR(uart, val); | ||
652 | SSYNC(); | ||
653 | |||
654 | UART_PUT_LCR(uart, lcr); | ||
655 | |||
656 | /* Enable UART */ | ||
657 | UART_PUT_IER(uart, ier); | ||
658 | |||
659 | val = UART_GET_GCTL(uart); | ||
660 | val |= UCEN; | ||
661 | UART_PUT_GCTL(uart, val); | ||
662 | |||
663 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
664 | } | ||
665 | |||
666 | static const char *bfin_serial_type(struct uart_port *port) | ||
667 | { | ||
668 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
669 | |||
670 | return uart->port.type == PORT_BFIN ? "BFIN-UART" : NULL; | ||
671 | } | ||
672 | |||
673 | /* | ||
674 | * Release the memory region(s) being used by 'port'. | ||
675 | */ | ||
676 | static void bfin_serial_release_port(struct uart_port *port) | ||
677 | { | ||
678 | } | ||
679 | |||
680 | /* | ||
681 | * Request the memory region(s) being used by 'port'. | ||
682 | */ | ||
683 | static int bfin_serial_request_port(struct uart_port *port) | ||
684 | { | ||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | /* | ||
689 | * Configure/autoconfigure the port. | ||
690 | */ | ||
691 | static void bfin_serial_config_port(struct uart_port *port, int flags) | ||
692 | { | ||
693 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
694 | |||
695 | if (flags & UART_CONFIG_TYPE && | ||
696 | bfin_serial_request_port(&uart->port) == 0) | ||
697 | uart->port.type = PORT_BFIN; | ||
698 | } | ||
699 | |||
700 | /* | ||
701 | * Verify the new serial_struct (for TIOCSSERIAL). | ||
702 | * The only change we allow are to the flags and type, and | ||
703 | * even then only between PORT_BFIN and PORT_UNKNOWN | ||
704 | */ | ||
705 | static int | ||
706 | bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
707 | { | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | static struct uart_ops bfin_serial_pops = { | ||
712 | .tx_empty = bfin_serial_tx_empty, | ||
713 | .set_mctrl = bfin_serial_set_mctrl, | ||
714 | .get_mctrl = bfin_serial_get_mctrl, | ||
715 | .stop_tx = bfin_serial_stop_tx, | ||
716 | .start_tx = bfin_serial_start_tx, | ||
717 | .stop_rx = bfin_serial_stop_rx, | ||
718 | .enable_ms = bfin_serial_enable_ms, | ||
719 | .break_ctl = bfin_serial_break_ctl, | ||
720 | .startup = bfin_serial_startup, | ||
721 | .shutdown = bfin_serial_shutdown, | ||
722 | .set_termios = bfin_serial_set_termios, | ||
723 | .type = bfin_serial_type, | ||
724 | .release_port = bfin_serial_release_port, | ||
725 | .request_port = bfin_serial_request_port, | ||
726 | .config_port = bfin_serial_config_port, | ||
727 | .verify_port = bfin_serial_verify_port, | ||
728 | }; | ||
729 | |||
730 | static void __init bfin_serial_init_ports(void) | ||
731 | { | ||
732 | static int first = 1; | ||
733 | int i; | ||
734 | |||
735 | if (!first) | ||
736 | return; | ||
737 | first = 0; | ||
738 | |||
739 | for (i = 0; i < nr_ports; i++) { | ||
740 | bfin_serial_ports[i].port.uartclk = get_sclk(); | ||
741 | bfin_serial_ports[i].port.ops = &bfin_serial_pops; | ||
742 | bfin_serial_ports[i].port.line = i; | ||
743 | bfin_serial_ports[i].port.iotype = UPIO_MEM; | ||
744 | bfin_serial_ports[i].port.membase = | ||
745 | (void __iomem *)bfin_serial_resource[i].uart_base_addr; | ||
746 | bfin_serial_ports[i].port.mapbase = | ||
747 | bfin_serial_resource[i].uart_base_addr; | ||
748 | bfin_serial_ports[i].port.irq = | ||
749 | bfin_serial_resource[i].uart_irq; | ||
750 | bfin_serial_ports[i].port.flags = UPF_BOOT_AUTOCONF; | ||
751 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
752 | bfin_serial_ports[i].tx_done = 1; | ||
753 | bfin_serial_ports[i].tx_count = 0; | ||
754 | bfin_serial_ports[i].tx_dma_channel = | ||
755 | bfin_serial_resource[i].uart_tx_dma_channel; | ||
756 | bfin_serial_ports[i].rx_dma_channel = | ||
757 | bfin_serial_resource[i].uart_rx_dma_channel; | ||
758 | init_timer(&(bfin_serial_ports[i].rx_dma_timer)); | ||
759 | #else | ||
760 | INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work); | ||
761 | #endif | ||
762 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
763 | bfin_serial_ports[i].cts_pin = | ||
764 | bfin_serial_resource[i].uart_cts_pin; | ||
765 | bfin_serial_ports[i].rts_pin = | ||
766 | bfin_serial_resource[i].uart_rts_pin; | ||
767 | #endif | ||
768 | bfin_serial_hw_init(&bfin_serial_ports[i]); | ||
769 | |||
770 | } | ||
771 | } | ||
772 | |||
773 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE | ||
774 | static void bfin_serial_console_putchar(struct uart_port *port, int ch) | ||
775 | { | ||
776 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
777 | while (!(UART_GET_LSR(uart))) | ||
778 | barrier(); | ||
779 | UART_PUT_CHAR(uart, ch); | ||
780 | SSYNC(); | ||
781 | } | ||
782 | |||
783 | /* | ||
784 | * Interrupts are disabled on entering | ||
785 | */ | ||
786 | static void | ||
787 | bfin_serial_console_write(struct console *co, const char *s, unsigned int count) | ||
788 | { | ||
789 | struct bfin_serial_port *uart = &bfin_serial_ports[co->index]; | ||
790 | int flags = 0; | ||
791 | |||
792 | spin_lock_irqsave(&uart->port.lock, flags); | ||
793 | uart_console_write(&uart->port, s, count, bfin_serial_console_putchar); | ||
794 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
795 | |||
796 | } | ||
797 | |||
798 | /* | ||
799 | * If the port was already initialised (eg, by a boot loader), | ||
800 | * try to determine the current setup. | ||
801 | */ | ||
802 | static void __init | ||
803 | bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, | ||
804 | int *parity, int *bits) | ||
805 | { | ||
806 | unsigned short status; | ||
807 | |||
808 | status = UART_GET_IER(uart) & (ERBFI | ETBEI); | ||
809 | if (status == (ERBFI | ETBEI)) { | ||
810 | /* ok, the port was enabled */ | ||
811 | unsigned short lcr, val; | ||
812 | unsigned short dlh, dll; | ||
813 | |||
814 | lcr = UART_GET_LCR(uart); | ||
815 | |||
816 | *parity = 'n'; | ||
817 | if (lcr & PEN) { | ||
818 | if (lcr & EPS) | ||
819 | *parity = 'e'; | ||
820 | else | ||
821 | *parity = 'o'; | ||
822 | } | ||
823 | switch (lcr & 0x03) { | ||
824 | case 0: *bits = 5; break; | ||
825 | case 1: *bits = 6; break; | ||
826 | case 2: *bits = 7; break; | ||
827 | case 3: *bits = 8; break; | ||
828 | } | ||
829 | /* Set DLAB in LCR to Access DLL and DLH */ | ||
830 | val = UART_GET_LCR(uart); | ||
831 | val |= DLAB; | ||
832 | UART_PUT_LCR(uart, val); | ||
833 | |||
834 | dll = UART_GET_DLL(uart); | ||
835 | dlh = UART_GET_DLH(uart); | ||
836 | |||
837 | /* Clear DLAB in LCR to Access THR RBR IER */ | ||
838 | val = UART_GET_LCR(uart); | ||
839 | val &= ~DLAB; | ||
840 | UART_PUT_LCR(uart, val); | ||
841 | |||
842 | *baud = get_sclk() / (16*(dll | dlh << 8)); | ||
843 | } | ||
844 | pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits); | ||
845 | } | ||
846 | |||
847 | static int __init | ||
848 | bfin_serial_console_setup(struct console *co, char *options) | ||
849 | { | ||
850 | struct bfin_serial_port *uart; | ||
851 | int baud = 57600; | ||
852 | int bits = 8; | ||
853 | int parity = 'n'; | ||
854 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
855 | int flow = 'r'; | ||
856 | #else | ||
857 | int flow = 'n'; | ||
858 | #endif | ||
859 | |||
860 | /* | ||
861 | * Check whether an invalid uart number has been specified, and | ||
862 | * if so, search for the first available port that does have | ||
863 | * console support. | ||
864 | */ | ||
865 | if (co->index == -1 || co->index >= nr_ports) | ||
866 | co->index = 0; | ||
867 | uart = &bfin_serial_ports[co->index]; | ||
868 | |||
869 | if (options) | ||
870 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
871 | else | ||
872 | bfin_serial_console_get_options(uart, &baud, &parity, &bits); | ||
873 | |||
874 | return uart_set_options(&uart->port, co, baud, parity, bits, flow); | ||
875 | } | ||
876 | |||
877 | static struct uart_driver bfin_serial_reg; | ||
878 | static struct console bfin_serial_console = { | ||
879 | .name = BFIN_SERIAL_NAME, | ||
880 | .write = bfin_serial_console_write, | ||
881 | .device = uart_console_device, | ||
882 | .setup = bfin_serial_console_setup, | ||
883 | .flags = CON_PRINTBUFFER, | ||
884 | .index = -1, | ||
885 | .data = &bfin_serial_reg, | ||
886 | }; | ||
887 | |||
888 | static int __init bfin_serial_rs_console_init(void) | ||
889 | { | ||
890 | bfin_serial_init_ports(); | ||
891 | register_console(&bfin_serial_console); | ||
892 | return 0; | ||
893 | } | ||
894 | console_initcall(bfin_serial_rs_console_init); | ||
895 | |||
896 | #define BFIN_SERIAL_CONSOLE &bfin_serial_console | ||
897 | #else | ||
898 | #define BFIN_SERIAL_CONSOLE NULL | ||
899 | #endif | ||
900 | |||
901 | static struct uart_driver bfin_serial_reg = { | ||
902 | .owner = THIS_MODULE, | ||
903 | .driver_name = "bfin-uart", | ||
904 | .dev_name = BFIN_SERIAL_NAME, | ||
905 | .major = BFIN_SERIAL_MAJOR, | ||
906 | .minor = BFIN_SERIAL_MINOR, | ||
907 | .nr = NR_PORTS, | ||
908 | .cons = BFIN_SERIAL_CONSOLE, | ||
909 | }; | ||
910 | |||
911 | static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state) | ||
912 | { | ||
913 | struct bfin_serial_port *uart = platform_get_drvdata(dev); | ||
914 | |||
915 | if (uart) | ||
916 | uart_suspend_port(&bfin_serial_reg, &uart->port); | ||
917 | |||
918 | return 0; | ||
919 | } | ||
920 | |||
921 | static int bfin_serial_resume(struct platform_device *dev) | ||
922 | { | ||
923 | struct bfin_serial_port *uart = platform_get_drvdata(dev); | ||
924 | |||
925 | if (uart) | ||
926 | uart_resume_port(&bfin_serial_reg, &uart->port); | ||
927 | |||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | static int bfin_serial_probe(struct platform_device *dev) | ||
932 | { | ||
933 | struct resource *res = dev->resource; | ||
934 | int i; | ||
935 | |||
936 | for (i = 0; i < dev->num_resources; i++, res++) | ||
937 | if (res->flags & IORESOURCE_MEM) | ||
938 | break; | ||
939 | |||
940 | if (i < dev->num_resources) { | ||
941 | for (i = 0; i < nr_ports; i++, res++) { | ||
942 | if (bfin_serial_ports[i].port.mapbase != res->start) | ||
943 | continue; | ||
944 | bfin_serial_ports[i].port.dev = &dev->dev; | ||
945 | uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | ||
946 | platform_set_drvdata(dev, &bfin_serial_ports[i]); | ||
947 | } | ||
948 | } | ||
949 | |||
950 | return 0; | ||
951 | } | ||
952 | |||
953 | static int bfin_serial_remove(struct platform_device *pdev) | ||
954 | { | ||
955 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); | ||
956 | |||
957 | |||
958 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
959 | gpio_free(uart->cts_pin); | ||
960 | gpio_free(uart->rts_pin); | ||
961 | #endif | ||
962 | |||
963 | platform_set_drvdata(pdev, NULL); | ||
964 | |||
965 | if (uart) | ||
966 | uart_remove_one_port(&bfin_serial_reg, &uart->port); | ||
967 | |||
968 | return 0; | ||
969 | } | ||
970 | |||
971 | static struct platform_driver bfin_serial_driver = { | ||
972 | .probe = bfin_serial_probe, | ||
973 | .remove = bfin_serial_remove, | ||
974 | .suspend = bfin_serial_suspend, | ||
975 | .resume = bfin_serial_resume, | ||
976 | .driver = { | ||
977 | .name = "bfin-uart", | ||
978 | }, | ||
979 | }; | ||
980 | |||
981 | static int __init bfin_serial_init(void) | ||
982 | { | ||
983 | int ret; | ||
984 | |||
985 | pr_info("Serial: Blackfin serial driver\n"); | ||
986 | |||
987 | bfin_serial_init_ports(); | ||
988 | |||
989 | ret = uart_register_driver(&bfin_serial_reg); | ||
990 | if (ret == 0) { | ||
991 | ret = platform_driver_register(&bfin_serial_driver); | ||
992 | if (ret) { | ||
993 | pr_debug("uart register failed\n"); | ||
994 | uart_unregister_driver(&bfin_serial_reg); | ||
995 | } | ||
996 | } | ||
997 | return ret; | ||
998 | } | ||
999 | |||
1000 | static void __exit bfin_serial_exit(void) | ||
1001 | { | ||
1002 | platform_driver_unregister(&bfin_serial_driver); | ||
1003 | uart_unregister_driver(&bfin_serial_reg); | ||
1004 | } | ||
1005 | |||
1006 | module_init(bfin_serial_init); | ||
1007 | module_exit(bfin_serial_exit); | ||
1008 | |||
1009 | MODULE_AUTHOR("Aubrey.Li <aubrey.li@analog.com>"); | ||
1010 | MODULE_DESCRIPTION("Blackfin generic serial port driver"); | ||
1011 | MODULE_LICENSE("GPL"); | ||
1012 | MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR); | ||
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h deleted file mode 100644 index 4a23340663a..00000000000 --- a/drivers/serial/crisv10.h +++ /dev/null | |||
@@ -1,136 +0,0 @@ | |||
1 | /* | ||
2 | * serial.h: Arch-dep definitions for the Etrax100 serial driver. | ||
3 | * | ||
4 | * Copyright (C) 1998, 1999, 2000 Axis Communications AB | ||
5 | */ | ||
6 | |||
7 | #ifndef _ETRAX_SERIAL_H | ||
8 | #define _ETRAX_SERIAL_H | ||
9 | |||
10 | #include <linux/circ_buf.h> | ||
11 | #include <asm/termios.h> | ||
12 | |||
13 | /* Software state per channel */ | ||
14 | |||
15 | #ifdef __KERNEL__ | ||
16 | /* | ||
17 | * This is our internal structure for each serial port's state. | ||
18 | * | ||
19 | * Many fields are paralleled by the structure used by the serial_struct | ||
20 | * structure. | ||
21 | * | ||
22 | * For definitions of the flags field, see tty.h | ||
23 | */ | ||
24 | |||
25 | #define SERIAL_RECV_DESCRIPTORS 8 | ||
26 | |||
27 | struct etrax_recv_buffer { | ||
28 | struct etrax_recv_buffer *next; | ||
29 | unsigned short length; | ||
30 | unsigned char error; | ||
31 | unsigned char pad; | ||
32 | |||
33 | unsigned char buffer[0]; | ||
34 | }; | ||
35 | |||
36 | struct e100_serial { | ||
37 | int baud; | ||
38 | volatile u8 *port; /* R_SERIALx_CTRL */ | ||
39 | u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */ | ||
40 | |||
41 | /* Output registers */ | ||
42 | volatile u8 *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR */ | ||
43 | volatile u32 *ofirstadr; /* adr to R_DMA_CHx_FIRST */ | ||
44 | volatile u8 *ocmdadr; /* adr to R_DMA_CHx_CMD */ | ||
45 | const volatile u8 *ostatusadr; /* adr to R_DMA_CHx_STATUS */ | ||
46 | |||
47 | /* Input registers */ | ||
48 | volatile u8 *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR */ | ||
49 | volatile u32 *ifirstadr; /* adr to R_DMA_CHx_FIRST */ | ||
50 | volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */ | ||
51 | volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */ | ||
52 | |||
53 | int flags; /* defined in tty.h */ | ||
54 | |||
55 | u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ | ||
56 | u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ | ||
57 | u8 iseteop; /* bit number for R_SET_EOP for the input dma */ | ||
58 | int enabled; /* Set to 1 if the port is enabled in HW config */ | ||
59 | |||
60 | u8 dma_out_enabled:1; /* Set to 1 if DMA should be used */ | ||
61 | u8 dma_in_enabled:1; /* Set to 1 if DMA should be used */ | ||
62 | |||
63 | /* end of fields defined in rs_table[] in .c-file */ | ||
64 | u8 uses_dma_in; /* Set to 1 if DMA is used */ | ||
65 | u8 uses_dma_out; /* Set to 1 if DMA is used */ | ||
66 | u8 forced_eop; /* a fifo eop has been forced */ | ||
67 | int baud_base; /* For special baudrates */ | ||
68 | int custom_divisor; /* For special baudrates */ | ||
69 | struct etrax_dma_descr tr_descr; | ||
70 | struct etrax_dma_descr rec_descr[SERIAL_RECV_DESCRIPTORS]; | ||
71 | int cur_rec_descr; | ||
72 | |||
73 | volatile int tr_running; /* 1 if output is running */ | ||
74 | |||
75 | struct tty_struct *tty; | ||
76 | int read_status_mask; | ||
77 | int ignore_status_mask; | ||
78 | int x_char; /* xon/xoff character */ | ||
79 | int close_delay; | ||
80 | unsigned short closing_wait; | ||
81 | unsigned short closing_wait2; | ||
82 | unsigned long event; | ||
83 | unsigned long last_active; | ||
84 | int line; | ||
85 | int type; /* PORT_ETRAX */ | ||
86 | int count; /* # of fd on device */ | ||
87 | int blocked_open; /* # of blocked opens */ | ||
88 | struct circ_buf xmit; | ||
89 | struct etrax_recv_buffer *first_recv_buffer; | ||
90 | struct etrax_recv_buffer *last_recv_buffer; | ||
91 | unsigned int recv_cnt; | ||
92 | unsigned int max_recv_cnt; | ||
93 | |||
94 | struct work_struct work; | ||
95 | struct async_icount icount; /* error-statistics etc.*/ | ||
96 | struct ktermios normal_termios; | ||
97 | struct ktermios callout_termios; | ||
98 | #ifdef DECLARE_WAITQUEUE | ||
99 | wait_queue_head_t open_wait; | ||
100 | wait_queue_head_t close_wait; | ||
101 | #else | ||
102 | struct wait_queue *open_wait; | ||
103 | struct wait_queue *close_wait; | ||
104 | #endif | ||
105 | |||
106 | unsigned long char_time_usec; /* The time for 1 char, in usecs */ | ||
107 | unsigned long flush_time_usec; /* How often we should flush */ | ||
108 | unsigned long last_tx_active_usec; /* Last tx usec in the jiffies */ | ||
109 | unsigned long last_tx_active; /* Last tx time in jiffies */ | ||
110 | unsigned long last_rx_active_usec; /* Last rx usec in the jiffies */ | ||
111 | unsigned long last_rx_active; /* Last rx time in jiffies */ | ||
112 | |||
113 | int break_detected_cnt; | ||
114 | int errorcode; | ||
115 | |||
116 | #ifdef CONFIG_ETRAX_RS485 | ||
117 | struct rs485_control rs485; /* RS-485 support */ | ||
118 | #endif | ||
119 | }; | ||
120 | |||
121 | /* this PORT is not in the standard serial.h. it's not actually used for | ||
122 | * anything since we only have one type of async serial-port anyway in this | ||
123 | * system. | ||
124 | */ | ||
125 | |||
126 | #define PORT_ETRAX 1 | ||
127 | |||
128 | /* | ||
129 | * Events are used to schedule things to happen at timer-interrupt | ||
130 | * time, instead of at rs interrupt time. | ||
131 | */ | ||
132 | #define RS_EVENT_WRITE_WAKEUP 0 | ||
133 | |||
134 | #endif /* __KERNEL__ */ | ||
135 | |||
136 | #endif /* !_ETRAX_SERIAL_H */ | ||
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 04cc88cc528..e42faa4e428 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -46,6 +46,122 @@ | |||
46 | #include <asm/hardware.h> | 46 | #include <asm/hardware.h> |
47 | #include <asm/arch/imx-uart.h> | 47 | #include <asm/arch/imx-uart.h> |
48 | 48 | ||
49 | /* Register definitions */ | ||
50 | #define URXD0 0x0 /* Receiver Register */ | ||
51 | #define URTX0 0x40 /* Transmitter Register */ | ||
52 | #define UCR1 0x80 /* Control Register 1 */ | ||
53 | #define UCR2 0x84 /* Control Register 2 */ | ||
54 | #define UCR3 0x88 /* Control Register 3 */ | ||
55 | #define UCR4 0x8c /* Control Register 4 */ | ||
56 | #define UFCR 0x90 /* FIFO Control Register */ | ||
57 | #define USR1 0x94 /* Status Register 1 */ | ||
58 | #define USR2 0x98 /* Status Register 2 */ | ||
59 | #define UESC 0x9c /* Escape Character Register */ | ||
60 | #define UTIM 0xa0 /* Escape Timer Register */ | ||
61 | #define UBIR 0xa4 /* BRM Incremental Register */ | ||
62 | #define UBMR 0xa8 /* BRM Modulator Register */ | ||
63 | #define UBRC 0xac /* Baud Rate Count Register */ | ||
64 | #define BIPR1 0xb0 /* Incremental Preset Register 1 */ | ||
65 | #define BIPR2 0xb4 /* Incremental Preset Register 2 */ | ||
66 | #define BIPR3 0xb8 /* Incremental Preset Register 3 */ | ||
67 | #define BIPR4 0xbc /* Incremental Preset Register 4 */ | ||
68 | #define BMPR1 0xc0 /* BRM Modulator Register 1 */ | ||
69 | #define BMPR2 0xc4 /* BRM Modulator Register 2 */ | ||
70 | #define BMPR3 0xc8 /* BRM Modulator Register 3 */ | ||
71 | #define BMPR4 0xcc /* BRM Modulator Register 4 */ | ||
72 | #define UTS 0xd0 /* UART Test Register */ | ||
73 | |||
74 | /* UART Control Register Bit Fields.*/ | ||
75 | #define URXD_CHARRDY (1<<15) | ||
76 | #define URXD_ERR (1<<14) | ||
77 | #define URXD_OVRRUN (1<<13) | ||
78 | #define URXD_FRMERR (1<<12) | ||
79 | #define URXD_BRK (1<<11) | ||
80 | #define URXD_PRERR (1<<10) | ||
81 | #define UCR1_ADEN (1<<15) /* Auto dectect interrupt */ | ||
82 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ | ||
83 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ | ||
84 | #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ | ||
85 | #define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ | ||
86 | #define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ | ||
87 | #define UCR1_IREN (1<<7) /* Infrared interface enable */ | ||
88 | #define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ | ||
89 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ | ||
90 | #define UCR1_SNDBRK (1<<4) /* Send break */ | ||
91 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ | ||
92 | #define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ | ||
93 | #define UCR1_DOZE (1<<1) /* Doze */ | ||
94 | #define UCR1_UARTEN (1<<0) /* UART enabled */ | ||
95 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ | ||
96 | #define UCR2_IRTS (1<<14) /* Ignore RTS pin */ | ||
97 | #define UCR2_CTSC (1<<13) /* CTS pin control */ | ||
98 | #define UCR2_CTS (1<<12) /* Clear to send */ | ||
99 | #define UCR2_ESCEN (1<<11) /* Escape enable */ | ||
100 | #define UCR2_PREN (1<<8) /* Parity enable */ | ||
101 | #define UCR2_PROE (1<<7) /* Parity odd/even */ | ||
102 | #define UCR2_STPB (1<<6) /* Stop */ | ||
103 | #define UCR2_WS (1<<5) /* Word size */ | ||
104 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ | ||
105 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ | ||
106 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ | ||
107 | #define UCR2_SRST (1<<0) /* SW reset */ | ||
108 | #define UCR3_DTREN (1<<13) /* DTR interrupt enable */ | ||
109 | #define UCR3_PARERREN (1<<12) /* Parity enable */ | ||
110 | #define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ | ||
111 | #define UCR3_DSR (1<<10) /* Data set ready */ | ||
112 | #define UCR3_DCD (1<<9) /* Data carrier detect */ | ||
113 | #define UCR3_RI (1<<8) /* Ring indicator */ | ||
114 | #define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */ | ||
115 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ | ||
116 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ | ||
117 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ | ||
118 | #define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */ | ||
119 | #define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */ | ||
120 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ | ||
121 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ | ||
122 | #define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ | ||
123 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ | ||
124 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ | ||
125 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ | ||
126 | #define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ | ||
127 | #define UCR4_IRSC (1<<5) /* IR special case */ | ||
128 | #define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ | ||
129 | #define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ | ||
130 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ | ||
131 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ | ||
132 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ | ||
133 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ | ||
134 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ | ||
135 | #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ | ||
136 | #define USR1_RTSS (1<<14) /* RTS pin status */ | ||
137 | #define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ | ||
138 | #define USR1_RTSD (1<<12) /* RTS delta */ | ||
139 | #define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ | ||
140 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ | ||
141 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ | ||
142 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ | ||
143 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ | ||
144 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ | ||
145 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ | ||
146 | #define USR2_ADET (1<<15) /* Auto baud rate detect complete */ | ||
147 | #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ | ||
148 | #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ | ||
149 | #define USR2_IDLE (1<<12) /* Idle condition */ | ||
150 | #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ | ||
151 | #define USR2_WAKE (1<<7) /* Wake */ | ||
152 | #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ | ||
153 | #define USR2_TXDC (1<<3) /* Transmitter complete */ | ||
154 | #define USR2_BRCD (1<<2) /* Break condition */ | ||
155 | #define USR2_ORE (1<<1) /* Overrun error */ | ||
156 | #define USR2_RDR (1<<0) /* Recv data ready */ | ||
157 | #define UTS_FRCPERR (1<<13) /* Force parity error */ | ||
158 | #define UTS_LOOP (1<<12) /* Loop tx and rx */ | ||
159 | #define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ | ||
160 | #define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ | ||
161 | #define UTS_TXFULL (1<<4) /* TxFIFO full */ | ||
162 | #define UTS_RXFULL (1<<3) /* RxFIFO full */ | ||
163 | #define UTS_SOFTRST (1<<0) /* Software reset */ | ||
164 | |||
49 | /* We've been assigned a range on the "Low-density serial ports" major */ | 165 | /* We've been assigned a range on the "Low-density serial ports" major */ |
50 | #define SERIAL_IMX_MAJOR 204 | 166 | #define SERIAL_IMX_MAJOR 204 |
51 | #define MINOR_START 41 | 167 | #define MINOR_START 41 |
@@ -128,7 +244,10 @@ static void imx_timeout(unsigned long data) | |||
128 | static void imx_stop_tx(struct uart_port *port) | 244 | static void imx_stop_tx(struct uart_port *port) |
129 | { | 245 | { |
130 | struct imx_port *sport = (struct imx_port *)port; | 246 | struct imx_port *sport = (struct imx_port *)port; |
131 | UCR1((u32)sport->port.membase) &= ~UCR1_TXMPTYEN; | 247 | unsigned long temp; |
248 | |||
249 | temp = readl(sport->port.membase + UCR1); | ||
250 | writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1); | ||
132 | } | 251 | } |
133 | 252 | ||
134 | /* | 253 | /* |
@@ -137,7 +256,10 @@ static void imx_stop_tx(struct uart_port *port) | |||
137 | static void imx_stop_rx(struct uart_port *port) | 256 | static void imx_stop_rx(struct uart_port *port) |
138 | { | 257 | { |
139 | struct imx_port *sport = (struct imx_port *)port; | 258 | struct imx_port *sport = (struct imx_port *)port; |
140 | UCR2((u32)sport->port.membase) &= ~UCR2_RXEN; | 259 | unsigned long temp; |
260 | |||
261 | temp = readl(sport->port.membase + UCR2); | ||
262 | writel(temp &~ UCR2_RXEN, sport->port.membase + UCR2); | ||
141 | } | 263 | } |
142 | 264 | ||
143 | /* | 265 | /* |
@@ -154,10 +276,10 @@ static inline void imx_transmit_buffer(struct imx_port *sport) | |||
154 | { | 276 | { |
155 | struct circ_buf *xmit = &sport->port.info->xmit; | 277 | struct circ_buf *xmit = &sport->port.info->xmit; |
156 | 278 | ||
157 | while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)) { | 279 | while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) { |
158 | /* send xmit->buf[xmit->tail] | 280 | /* send xmit->buf[xmit->tail] |
159 | * out the port here */ | 281 | * out the port here */ |
160 | URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail]; | 282 | writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); |
161 | xmit->tail = (xmit->tail + 1) & | 283 | xmit->tail = (xmit->tail + 1) & |
162 | (UART_XMIT_SIZE - 1); | 284 | (UART_XMIT_SIZE - 1); |
163 | sport->port.icount.tx++; | 285 | sport->port.icount.tx++; |
@@ -175,21 +297,24 @@ static inline void imx_transmit_buffer(struct imx_port *sport) | |||
175 | static void imx_start_tx(struct uart_port *port) | 297 | static void imx_start_tx(struct uart_port *port) |
176 | { | 298 | { |
177 | struct imx_port *sport = (struct imx_port *)port; | 299 | struct imx_port *sport = (struct imx_port *)port; |
300 | unsigned long temp; | ||
178 | 301 | ||
179 | UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN; | 302 | temp = readl(sport->port.membase + UCR1); |
303 | writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1); | ||
180 | 304 | ||
181 | imx_transmit_buffer(sport); | 305 | if (readl(sport->port.membase + UTS) & UTS_TXEMPTY) |
306 | imx_transmit_buffer(sport); | ||
182 | } | 307 | } |
183 | 308 | ||
184 | static irqreturn_t imx_rtsint(int irq, void *dev_id) | 309 | static irqreturn_t imx_rtsint(int irq, void *dev_id) |
185 | { | 310 | { |
186 | struct imx_port *sport = (struct imx_port *)dev_id; | 311 | struct imx_port *sport = (struct imx_port *)dev_id; |
187 | unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS; | 312 | unsigned int val = readl(sport->port.membase + USR1) & USR1_RTSS; |
188 | unsigned long flags; | 313 | unsigned long flags; |
189 | 314 | ||
190 | spin_lock_irqsave(&sport->port.lock, flags); | 315 | spin_lock_irqsave(&sport->port.lock, flags); |
191 | 316 | ||
192 | USR1((u32)sport->port.membase) = USR1_RTSD; | 317 | writel(USR1_RTSD, sport->port.membase + USR1); |
193 | uart_handle_cts_change(&sport->port, !!val); | 318 | uart_handle_cts_change(&sport->port, !!val); |
194 | wake_up_interruptible(&sport->port.info->delta_msr_wait); | 319 | wake_up_interruptible(&sport->port.info->delta_msr_wait); |
195 | 320 | ||
@@ -207,7 +332,7 @@ static irqreturn_t imx_txint(int irq, void *dev_id) | |||
207 | if (sport->port.x_char) | 332 | if (sport->port.x_char) |
208 | { | 333 | { |
209 | /* Send next char */ | 334 | /* Send next char */ |
210 | URTX0((u32)sport->port.membase) = sport->port.x_char; | 335 | writel(sport->port.x_char, sport->port.membase + URTX0); |
211 | goto out; | 336 | goto out; |
212 | } | 337 | } |
213 | 338 | ||
@@ -231,17 +356,18 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
231 | struct imx_port *sport = dev_id; | 356 | struct imx_port *sport = dev_id; |
232 | unsigned int rx,flg,ignored = 0; | 357 | unsigned int rx,flg,ignored = 0; |
233 | struct tty_struct *tty = sport->port.info->tty; | 358 | struct tty_struct *tty = sport->port.info->tty; |
234 | unsigned long flags; | 359 | unsigned long flags, temp; |
235 | 360 | ||
236 | rx = URXD0((u32)sport->port.membase); | 361 | rx = readl(sport->port.membase + URXD0); |
237 | spin_lock_irqsave(&sport->port.lock,flags); | 362 | spin_lock_irqsave(&sport->port.lock,flags); |
238 | 363 | ||
239 | do { | 364 | do { |
240 | flg = TTY_NORMAL; | 365 | flg = TTY_NORMAL; |
241 | sport->port.icount.rx++; | 366 | sport->port.icount.rx++; |
242 | 367 | ||
243 | if( USR2((u32)sport->port.membase) & USR2_BRCD ) { | 368 | temp = readl(sport->port.membase + USR2); |
244 | USR2((u32)sport->port.membase) |= USR2_BRCD; | 369 | if( temp & USR2_BRCD ) { |
370 | writel(temp | USR2_BRCD, sport->port.membase + USR2); | ||
245 | if(uart_handle_break(&sport->port)) | 371 | if(uart_handle_break(&sport->port)) |
246 | goto ignore_char; | 372 | goto ignore_char; |
247 | } | 373 | } |
@@ -257,7 +383,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
257 | tty_insert_flip_char(tty, rx, flg); | 383 | tty_insert_flip_char(tty, rx, flg); |
258 | 384 | ||
259 | ignore_char: | 385 | ignore_char: |
260 | rx = URXD0((u32)sport->port.membase); | 386 | rx = readl(sport->port.membase + URXD0); |
261 | } while(rx & URXD_CHARRDY); | 387 | } while(rx & URXD_CHARRDY); |
262 | 388 | ||
263 | out: | 389 | out: |
@@ -301,7 +427,7 @@ static unsigned int imx_tx_empty(struct uart_port *port) | |||
301 | { | 427 | { |
302 | struct imx_port *sport = (struct imx_port *)port; | 428 | struct imx_port *sport = (struct imx_port *)port; |
303 | 429 | ||
304 | return USR2((u32)sport->port.membase) & USR2_TXDC ? TIOCSER_TEMT : 0; | 430 | return (readl(sport->port.membase + USR2) & USR2_TXDC) ? TIOCSER_TEMT : 0; |
305 | } | 431 | } |
306 | 432 | ||
307 | /* | 433 | /* |
@@ -312,10 +438,10 @@ static unsigned int imx_get_mctrl(struct uart_port *port) | |||
312 | struct imx_port *sport = (struct imx_port *)port; | 438 | struct imx_port *sport = (struct imx_port *)port; |
313 | unsigned int tmp = TIOCM_DSR | TIOCM_CAR; | 439 | unsigned int tmp = TIOCM_DSR | TIOCM_CAR; |
314 | 440 | ||
315 | if (USR1((u32)sport->port.membase) & USR1_RTSS) | 441 | if (readl(sport->port.membase + USR1) & USR1_RTSS) |
316 | tmp |= TIOCM_CTS; | 442 | tmp |= TIOCM_CTS; |
317 | 443 | ||
318 | if (UCR2((u32)sport->port.membase) & UCR2_CTS) | 444 | if (readl(sport->port.membase + UCR2) & UCR2_CTS) |
319 | tmp |= TIOCM_RTS; | 445 | tmp |= TIOCM_RTS; |
320 | 446 | ||
321 | return tmp; | 447 | return tmp; |
@@ -324,11 +450,14 @@ static unsigned int imx_get_mctrl(struct uart_port *port) | |||
324 | static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) | 450 | static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) |
325 | { | 451 | { |
326 | struct imx_port *sport = (struct imx_port *)port; | 452 | struct imx_port *sport = (struct imx_port *)port; |
453 | unsigned long temp; | ||
454 | |||
455 | temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS; | ||
327 | 456 | ||
328 | if (mctrl & TIOCM_RTS) | 457 | if (mctrl & TIOCM_RTS) |
329 | UCR2((u32)sport->port.membase) |= UCR2_CTS; | 458 | temp |= UCR2_CTS; |
330 | else | 459 | |
331 | UCR2((u32)sport->port.membase) &= ~UCR2_CTS; | 460 | writel(temp, sport->port.membase + UCR2); |
332 | } | 461 | } |
333 | 462 | ||
334 | /* | 463 | /* |
@@ -337,14 +466,16 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
337 | static void imx_break_ctl(struct uart_port *port, int break_state) | 466 | static void imx_break_ctl(struct uart_port *port, int break_state) |
338 | { | 467 | { |
339 | struct imx_port *sport = (struct imx_port *)port; | 468 | struct imx_port *sport = (struct imx_port *)port; |
340 | unsigned long flags; | 469 | unsigned long flags, temp; |
341 | 470 | ||
342 | spin_lock_irqsave(&sport->port.lock, flags); | 471 | spin_lock_irqsave(&sport->port.lock, flags); |
343 | 472 | ||
473 | temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK; | ||
474 | |||
344 | if ( break_state != 0 ) | 475 | if ( break_state != 0 ) |
345 | UCR1((u32)sport->port.membase) |= UCR1_SNDBRK; | 476 | temp |= UCR1_SNDBRK; |
346 | else | 477 | |
347 | UCR1((u32)sport->port.membase) &= ~UCR1_SNDBRK; | 478 | writel(temp, sport->port.membase + UCR1); |
348 | 479 | ||
349 | spin_unlock_irqrestore(&sport->port.lock, flags); | 480 | spin_unlock_irqrestore(&sport->port.lock, flags); |
350 | } | 481 | } |
@@ -360,7 +491,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | |||
360 | /* set receiver / transmitter trigger level. | 491 | /* set receiver / transmitter trigger level. |
361 | * RFDIV is set such way to satisfy requested uartclk value | 492 | * RFDIV is set such way to satisfy requested uartclk value |
362 | */ | 493 | */ |
363 | val = TXTL<<10 | RXTL; | 494 | val = TXTL << 10 | RXTL; |
364 | ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; | 495 | ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; |
365 | 496 | ||
366 | if(!ufcr_rfdiv) | 497 | if(!ufcr_rfdiv) |
@@ -373,7 +504,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | |||
373 | 504 | ||
374 | val |= UFCR_RFDIV & (ufcr_rfdiv << 7); | 505 | val |= UFCR_RFDIV & (ufcr_rfdiv << 7); |
375 | 506 | ||
376 | UFCR((u32)sport->port.membase) = val; | 507 | writel(val, sport->port.membase + UFCR); |
377 | 508 | ||
378 | return 0; | 509 | return 0; |
379 | } | 510 | } |
@@ -382,14 +513,15 @@ static int imx_startup(struct uart_port *port) | |||
382 | { | 513 | { |
383 | struct imx_port *sport = (struct imx_port *)port; | 514 | struct imx_port *sport = (struct imx_port *)port; |
384 | int retval; | 515 | int retval; |
385 | unsigned long flags; | 516 | unsigned long flags, temp; |
386 | 517 | ||
387 | imx_setup_ufcr(sport, 0); | 518 | imx_setup_ufcr(sport, 0); |
388 | 519 | ||
389 | /* disable the DREN bit (Data Ready interrupt enable) before | 520 | /* disable the DREN bit (Data Ready interrupt enable) before |
390 | * requesting IRQs | 521 | * requesting IRQs |
391 | */ | 522 | */ |
392 | UCR4((u32)sport->port.membase) &= ~UCR4_DREN; | 523 | temp = readl(sport->port.membase + UCR4); |
524 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); | ||
393 | 525 | ||
394 | /* | 526 | /* |
395 | * Allocate the IRQ | 527 | * Allocate the IRQ |
@@ -411,12 +543,16 @@ static int imx_startup(struct uart_port *port) | |||
411 | /* | 543 | /* |
412 | * Finally, clear and enable interrupts | 544 | * Finally, clear and enable interrupts |
413 | */ | 545 | */ |
546 | writel(USR1_RTSD, sport->port.membase + USR1); | ||
547 | |||
548 | temp = readl(sport->port.membase + UCR1); | ||
549 | temp |= (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); | ||
550 | writel(temp, sport->port.membase + UCR1); | ||
414 | 551 | ||
415 | USR1((u32)sport->port.membase) = USR1_RTSD; | 552 | temp = readl(sport->port.membase + UCR2); |
416 | UCR1((u32)sport->port.membase) |= | 553 | temp |= (UCR2_RXEN | UCR2_TXEN); |
417 | (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); | 554 | writel(temp, sport->port.membase + UCR2); |
418 | 555 | ||
419 | UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN); | ||
420 | /* | 556 | /* |
421 | * Enable modem status interrupts | 557 | * Enable modem status interrupts |
422 | */ | 558 | */ |
@@ -437,6 +573,7 @@ error_out1: | |||
437 | static void imx_shutdown(struct uart_port *port) | 573 | static void imx_shutdown(struct uart_port *port) |
438 | { | 574 | { |
439 | struct imx_port *sport = (struct imx_port *)port; | 575 | struct imx_port *sport = (struct imx_port *)port; |
576 | unsigned long temp; | ||
440 | 577 | ||
441 | /* | 578 | /* |
442 | * Stop our timer. | 579 | * Stop our timer. |
@@ -454,8 +591,9 @@ static void imx_shutdown(struct uart_port *port) | |||
454 | * Disable all interrupts, port and break condition. | 591 | * Disable all interrupts, port and break condition. |
455 | */ | 592 | */ |
456 | 593 | ||
457 | UCR1((u32)sport->port.membase) &= | 594 | temp = readl(sport->port.membase + UCR1); |
458 | ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); | 595 | temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); |
596 | writel(temp, sport->port.membase + UCR1); | ||
459 | } | 597 | } |
460 | 598 | ||
461 | static void | 599 | static void |
@@ -548,18 +686,18 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
548 | /* | 686 | /* |
549 | * disable interrupts and drain transmitter | 687 | * disable interrupts and drain transmitter |
550 | */ | 688 | */ |
551 | old_ucr1 = UCR1((u32)sport->port.membase); | 689 | old_ucr1 = readl(sport->port.membase + UCR1); |
552 | UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); | 690 | writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), |
691 | sport->port.membase + UCR1); | ||
553 | 692 | ||
554 | while ( !(USR2((u32)sport->port.membase) & USR2_TXDC)) | 693 | while ( !(readl(sport->port.membase + USR2) & USR2_TXDC)) |
555 | barrier(); | 694 | barrier(); |
556 | 695 | ||
557 | /* then, disable everything */ | 696 | /* then, disable everything */ |
558 | old_txrxen = UCR2((u32)sport->port.membase) & ( UCR2_TXEN | UCR2_RXEN ); | 697 | old_txrxen = readl(sport->port.membase + UCR2); |
559 | UCR2((u32)sport->port.membase) &= ~( UCR2_TXEN | UCR2_RXEN); | 698 | writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN), |
560 | 699 | sport->port.membase + UCR2); | |
561 | /* set the parity, stop bits and data size */ | 700 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); |
562 | UCR2((u32)sport->port.membase) = ucr2; | ||
563 | 701 | ||
564 | /* set the baud rate. We assume uartclk = 16 MHz | 702 | /* set the baud rate. We assume uartclk = 16 MHz |
565 | * | 703 | * |
@@ -567,11 +705,13 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
567 | * --------- = -------- | 705 | * --------- = -------- |
568 | * uartclk UBMR - 1 | 706 | * uartclk UBMR - 1 |
569 | */ | 707 | */ |
570 | UBIR((u32)sport->port.membase) = (baud / 100) - 1; | 708 | writel((baud / 100) - 1, sport->port.membase + UBIR); |
571 | UBMR((u32)sport->port.membase) = 10000 - 1; | 709 | writel(10000 - 1, sport->port.membase + UBMR); |
710 | |||
711 | writel(old_ucr1, sport->port.membase + UCR1); | ||
572 | 712 | ||
573 | UCR1((u32)sport->port.membase) = old_ucr1; | 713 | /* set the parity, stop bits and data size */ |
574 | UCR2((u32)sport->port.membase) |= old_txrxen; | 714 | writel(ucr2 | old_txrxen, sport->port.membase + UCR2); |
575 | 715 | ||
576 | if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) | 716 | if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) |
577 | imx_enable_ms(&sport->port); | 717 | imx_enable_ms(&sport->port); |
@@ -730,9 +870,11 @@ static void __init imx_init_ports(void) | |||
730 | static void imx_console_putchar(struct uart_port *port, int ch) | 870 | static void imx_console_putchar(struct uart_port *port, int ch) |
731 | { | 871 | { |
732 | struct imx_port *sport = (struct imx_port *)port; | 872 | struct imx_port *sport = (struct imx_port *)port; |
733 | while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) | 873 | |
874 | while (readl(sport->port.membase + UTS) & UTS_TXFULL) | ||
734 | barrier(); | 875 | barrier(); |
735 | URTX0((u32)sport->port.membase) = ch; | 876 | |
877 | writel(ch, sport->port.membase + URTX0); | ||
736 | } | 878 | } |
737 | 879 | ||
738 | /* | 880 | /* |
@@ -747,13 +889,14 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
747 | /* | 889 | /* |
748 | * First, save UCR1/2 and then disable interrupts | 890 | * First, save UCR1/2 and then disable interrupts |
749 | */ | 891 | */ |
750 | old_ucr1 = UCR1((u32)sport->port.membase); | 892 | old_ucr1 = readl(sport->port.membase + UCR1); |
751 | old_ucr2 = UCR2((u32)sport->port.membase); | 893 | old_ucr2 = readl(sport->port.membase + UCR2); |
752 | 894 | ||
753 | UCR1((u32)sport->port.membase) = | 895 | writel((old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) & |
754 | (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) | 896 | ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), |
755 | & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); | 897 | sport->port.membase + UCR1); |
756 | UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; | 898 | |
899 | writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2); | ||
757 | 900 | ||
758 | uart_console_write(&sport->port, s, count, imx_console_putchar); | 901 | uart_console_write(&sport->port, s, count, imx_console_putchar); |
759 | 902 | ||
@@ -761,10 +904,10 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
761 | * Finally, wait for transmitter to become empty | 904 | * Finally, wait for transmitter to become empty |
762 | * and restore UCR1/2 | 905 | * and restore UCR1/2 |
763 | */ | 906 | */ |
764 | while (!(USR2((u32)sport->port.membase) & USR2_TXDC)); | 907 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); |
765 | 908 | ||
766 | UCR1((u32)sport->port.membase) = old_ucr1; | 909 | writel(old_ucr1, sport->port.membase + UCR1); |
767 | UCR2((u32)sport->port.membase) = old_ucr2; | 910 | writel(old_ucr2, sport->port.membase + UCR2); |
768 | } | 911 | } |
769 | 912 | ||
770 | /* | 913 | /* |
@@ -776,13 +919,13 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
776 | int *parity, int *bits) | 919 | int *parity, int *bits) |
777 | { | 920 | { |
778 | 921 | ||
779 | if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) { | 922 | if ( readl(sport->port.membase + UCR1) | UCR1_UARTEN ) { |
780 | /* ok, the port was enabled */ | 923 | /* ok, the port was enabled */ |
781 | unsigned int ucr2, ubir,ubmr, uartclk; | 924 | unsigned int ucr2, ubir,ubmr, uartclk; |
782 | unsigned int baud_raw; | 925 | unsigned int baud_raw; |
783 | unsigned int ucfr_rfdiv; | 926 | unsigned int ucfr_rfdiv; |
784 | 927 | ||
785 | ucr2 = UCR2((u32)sport->port.membase); | 928 | ucr2 = readl(sport->port.membase + UCR2); |
786 | 929 | ||
787 | *parity = 'n'; | 930 | *parity = 'n'; |
788 | if (ucr2 & UCR2_PREN) { | 931 | if (ucr2 & UCR2_PREN) { |
@@ -797,11 +940,10 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
797 | else | 940 | else |
798 | *bits = 7; | 941 | *bits = 7; |
799 | 942 | ||
800 | ubir = UBIR((u32)sport->port.membase) & 0xffff; | 943 | ubir = readl(sport->port.membase + UBIR) & 0xffff; |
801 | ubmr = UBMR((u32)sport->port.membase) & 0xffff; | 944 | ubmr = readl(sport->port.membase + UBMR) & 0xffff; |
802 | |||
803 | 945 | ||
804 | ucfr_rfdiv = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) >> 7; | 946 | ucfr_rfdiv = (readl(sport->port.membase + UFCR) & UFCR_RFDIV) >> 7; |
805 | if (ucfr_rfdiv == 6) | 947 | if (ucfr_rfdiv == 6) |
806 | ucfr_rfdiv = 7; | 948 | ucfr_rfdiv = 7; |
807 | else | 949 | else |
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index 3d2fcc57b1c..d09f2097d5b 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -183,6 +183,7 @@ struct mpsc_port_info { | |||
183 | u8 *txb_p; /* Phys addr of txb */ | 183 | u8 *txb_p; /* Phys addr of txb */ |
184 | int txr_head; /* Where new data goes */ | 184 | int txr_head; /* Where new data goes */ |
185 | int txr_tail; /* Where sent data comes off */ | 185 | int txr_tail; /* Where sent data comes off */ |
186 | spinlock_t tx_lock; /* transmit lock */ | ||
186 | 187 | ||
187 | /* Mirrored values of regs we can't read (if 'mirror_regs' set) */ | 188 | /* Mirrored values of regs we can't read (if 'mirror_regs' set) */ |
188 | u32 MPSC_MPCR_m; | 189 | u32 MPSC_MPCR_m; |
@@ -1212,6 +1213,9 @@ mpsc_tx_intr(struct mpsc_port_info *pi) | |||
1212 | { | 1213 | { |
1213 | struct mpsc_tx_desc *txre; | 1214 | struct mpsc_tx_desc *txre; |
1214 | int rc = 0; | 1215 | int rc = 0; |
1216 | unsigned long iflags; | ||
1217 | |||
1218 | spin_lock_irqsave(&pi->tx_lock, iflags); | ||
1215 | 1219 | ||
1216 | if (!mpsc_sdma_tx_active(pi)) { | 1220 | if (!mpsc_sdma_tx_active(pi)) { |
1217 | txre = (struct mpsc_tx_desc *)(pi->txr + | 1221 | txre = (struct mpsc_tx_desc *)(pi->txr + |
@@ -1248,6 +1252,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi) | |||
1248 | mpsc_sdma_start_tx(pi); /* start next desc if ready */ | 1252 | mpsc_sdma_start_tx(pi); /* start next desc if ready */ |
1249 | } | 1253 | } |
1250 | 1254 | ||
1255 | spin_unlock_irqrestore(&pi->tx_lock, iflags); | ||
1251 | return rc; | 1256 | return rc; |
1252 | } | 1257 | } |
1253 | 1258 | ||
@@ -1338,11 +1343,16 @@ static void | |||
1338 | mpsc_start_tx(struct uart_port *port) | 1343 | mpsc_start_tx(struct uart_port *port) |
1339 | { | 1344 | { |
1340 | struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | 1345 | struct mpsc_port_info *pi = (struct mpsc_port_info *)port; |
1346 | unsigned long iflags; | ||
1347 | |||
1348 | spin_lock_irqsave(&pi->tx_lock, iflags); | ||
1341 | 1349 | ||
1342 | mpsc_unfreeze(pi); | 1350 | mpsc_unfreeze(pi); |
1343 | mpsc_copy_tx_data(pi); | 1351 | mpsc_copy_tx_data(pi); |
1344 | mpsc_sdma_start_tx(pi); | 1352 | mpsc_sdma_start_tx(pi); |
1345 | 1353 | ||
1354 | spin_unlock_irqrestore(&pi->tx_lock, iflags); | ||
1355 | |||
1346 | pr_debug("mpsc_start_tx[%d]\n", port->line); | 1356 | pr_debug("mpsc_start_tx[%d]\n", port->line); |
1347 | return; | 1357 | return; |
1348 | } | 1358 | } |
@@ -1625,6 +1635,16 @@ mpsc_console_write(struct console *co, const char *s, uint count) | |||
1625 | struct mpsc_port_info *pi = &mpsc_ports[co->index]; | 1635 | struct mpsc_port_info *pi = &mpsc_ports[co->index]; |
1626 | u8 *bp, *dp, add_cr = 0; | 1636 | u8 *bp, *dp, add_cr = 0; |
1627 | int i; | 1637 | int i; |
1638 | unsigned long iflags; | ||
1639 | |||
1640 | spin_lock_irqsave(&pi->tx_lock, iflags); | ||
1641 | |||
1642 | while (pi->txr_head != pi->txr_tail) { | ||
1643 | while (mpsc_sdma_tx_active(pi)) | ||
1644 | udelay(100); | ||
1645 | mpsc_sdma_intr_ack(pi); | ||
1646 | mpsc_tx_intr(pi); | ||
1647 | } | ||
1628 | 1648 | ||
1629 | while (mpsc_sdma_tx_active(pi)) | 1649 | while (mpsc_sdma_tx_active(pi)) |
1630 | udelay(100); | 1650 | udelay(100); |
@@ -1668,6 +1688,7 @@ mpsc_console_write(struct console *co, const char *s, uint count) | |||
1668 | pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1); | 1688 | pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1); |
1669 | } | 1689 | } |
1670 | 1690 | ||
1691 | spin_unlock_irqrestore(&pi->tx_lock, iflags); | ||
1671 | return; | 1692 | return; |
1672 | } | 1693 | } |
1673 | 1694 | ||
@@ -2005,7 +2026,8 @@ mpsc_drv_probe(struct platform_device *dev) | |||
2005 | if (!(rc = mpsc_drv_map_regs(pi, dev))) { | 2026 | if (!(rc = mpsc_drv_map_regs(pi, dev))) { |
2006 | mpsc_drv_get_platform_data(pi, dev, dev->id); | 2027 | mpsc_drv_get_platform_data(pi, dev, dev->id); |
2007 | 2028 | ||
2008 | if (!(rc = mpsc_make_ready(pi))) | 2029 | if (!(rc = mpsc_make_ready(pi))) { |
2030 | spin_lock_init(&pi->tx_lock); | ||
2009 | if (!(rc = uart_add_one_port(&mpsc_reg, | 2031 | if (!(rc = uart_add_one_port(&mpsc_reg, |
2010 | &pi->port))) | 2032 | &pi->port))) |
2011 | rc = 0; | 2033 | rc = 0; |
@@ -2014,6 +2036,7 @@ mpsc_drv_probe(struct platform_device *dev) | |||
2014 | (struct uart_port *)pi); | 2036 | (struct uart_port *)pi); |
2015 | mpsc_drv_unmap_regs(pi); | 2037 | mpsc_drv_unmap_regs(pi); |
2016 | } | 2038 | } |
2039 | } | ||
2017 | else | 2040 | else |
2018 | mpsc_drv_unmap_regs(pi); | 2041 | mpsc_drv_unmap_regs(pi); |
2019 | } | 2042 | } |
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index e7928fee833..7ffdaeaf054 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c | |||
@@ -48,7 +48,8 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, | |||
48 | port->iotype = UPIO_MEM; | 48 | port->iotype = UPIO_MEM; |
49 | port->type = type; | 49 | port->type = type; |
50 | port->uartclk = *clk; | 50 | port->uartclk = *clk; |
51 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP; | 51 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
52 | | UPF_FIXED_PORT; | ||
52 | port->dev = &ofdev->dev; | 53 | port->dev = &ofdev->dev; |
53 | port->custom_divisor = *clk / (16 * (*spd)); | 54 | port->custom_divisor = *clk / (16 * (*spd)); |
54 | 55 | ||
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index d403aaa5509..e9c6cb391a2 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -717,7 +717,7 @@ struct uart_ops serial_pxa_pops = { | |||
717 | static struct uart_pxa_port serial_pxa_ports[] = { | 717 | static struct uart_pxa_port serial_pxa_ports[] = { |
718 | { /* FFUART */ | 718 | { /* FFUART */ |
719 | .name = "FFUART", | 719 | .name = "FFUART", |
720 | .cken = CKEN6_FFUART, | 720 | .cken = CKEN_FFUART, |
721 | .port = { | 721 | .port = { |
722 | .type = PORT_PXA, | 722 | .type = PORT_PXA, |
723 | .iotype = UPIO_MEM, | 723 | .iotype = UPIO_MEM, |
@@ -731,7 +731,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { | |||
731 | }, | 731 | }, |
732 | }, { /* BTUART */ | 732 | }, { /* BTUART */ |
733 | .name = "BTUART", | 733 | .name = "BTUART", |
734 | .cken = CKEN7_BTUART, | 734 | .cken = CKEN_BTUART, |
735 | .port = { | 735 | .port = { |
736 | .type = PORT_PXA, | 736 | .type = PORT_PXA, |
737 | .iotype = UPIO_MEM, | 737 | .iotype = UPIO_MEM, |
@@ -745,7 +745,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { | |||
745 | }, | 745 | }, |
746 | }, { /* STUART */ | 746 | }, { /* STUART */ |
747 | .name = "STUART", | 747 | .name = "STUART", |
748 | .cken = CKEN5_STUART, | 748 | .cken = CKEN_STUART, |
749 | .port = { | 749 | .port = { |
750 | .type = PORT_PXA, | 750 | .type = PORT_PXA, |
751 | .iotype = UPIO_MEM, | 751 | .iotype = UPIO_MEM, |
@@ -759,7 +759,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { | |||
759 | }, | 759 | }, |
760 | }, { /* HWUART */ | 760 | }, { /* HWUART */ |
761 | .name = "HWUART", | 761 | .name = "HWUART", |
762 | .cken = CKEN4_HWUART, | 762 | .cken = CKEN_HWUART, |
763 | .port = { | 763 | .port = { |
764 | .type = PORT_PXA, | 764 | .type = PORT_PXA, |
765 | .iotype = UPIO_MEM, | 765 | .iotype = UPIO_MEM, |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 0422c0f1f85..326020f86f7 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -37,13 +37,6 @@ | |||
37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
39 | 39 | ||
40 | #undef DEBUG | ||
41 | #ifdef DEBUG | ||
42 | #define DPRINTK(x...) printk(x) | ||
43 | #else | ||
44 | #define DPRINTK(x...) do { } while (0) | ||
45 | #endif | ||
46 | |||
47 | /* | 40 | /* |
48 | * This is used to lock changes in serial line configuration. | 41 | * This is used to lock changes in serial line configuration. |
49 | */ | 42 | */ |
@@ -552,7 +545,7 @@ static void uart_flush_buffer(struct tty_struct *tty) | |||
552 | return; | 545 | return; |
553 | } | 546 | } |
554 | 547 | ||
555 | DPRINTK("uart_flush_buffer(%d) called\n", tty->index); | 548 | pr_debug("uart_flush_buffer(%d) called\n", tty->index); |
556 | 549 | ||
557 | spin_lock_irqsave(&port->lock, flags); | 550 | spin_lock_irqsave(&port->lock, flags); |
558 | uart_circ_clear(&state->info->xmit); | 551 | uart_circ_clear(&state->info->xmit); |
@@ -672,19 +665,21 @@ static int uart_set_info(struct uart_state *state, | |||
672 | */ | 665 | */ |
673 | mutex_lock(&state->mutex); | 666 | mutex_lock(&state->mutex); |
674 | 667 | ||
675 | change_irq = new_serial.irq != port->irq; | 668 | change_irq = !(port->flags & UPF_FIXED_PORT) |
669 | && new_serial.irq != port->irq; | ||
676 | 670 | ||
677 | /* | 671 | /* |
678 | * Since changing the 'type' of the port changes its resource | 672 | * Since changing the 'type' of the port changes its resource |
679 | * allocations, we should treat type changes the same as | 673 | * allocations, we should treat type changes the same as |
680 | * IO port changes. | 674 | * IO port changes. |
681 | */ | 675 | */ |
682 | change_port = new_port != port->iobase || | 676 | change_port = !(port->flags & UPF_FIXED_PORT) |
683 | (unsigned long)new_serial.iomem_base != port->mapbase || | 677 | && (new_port != port->iobase || |
684 | new_serial.hub6 != port->hub6 || | 678 | (unsigned long)new_serial.iomem_base != port->mapbase || |
685 | new_serial.io_type != port->iotype || | 679 | new_serial.hub6 != port->hub6 || |
686 | new_serial.iomem_reg_shift != port->regshift || | 680 | new_serial.io_type != port->iotype || |
687 | new_serial.type != port->type; | 681 | new_serial.iomem_reg_shift != port->regshift || |
682 | new_serial.type != port->type); | ||
688 | 683 | ||
689 | old_flags = port->flags; | 684 | old_flags = port->flags; |
690 | new_flags = new_serial.flags; | 685 | new_flags = new_serial.flags; |
@@ -796,8 +791,10 @@ static int uart_set_info(struct uart_state *state, | |||
796 | } | 791 | } |
797 | } | 792 | } |
798 | 793 | ||
799 | port->irq = new_serial.irq; | 794 | if (change_irq) |
800 | port->uartclk = new_serial.baud_base * 16; | 795 | port->irq = new_serial.irq; |
796 | if (!(port->flags & UPF_FIXED_PORT)) | ||
797 | port->uartclk = new_serial.baud_base * 16; | ||
801 | port->flags = (port->flags & ~UPF_CHANGE_MASK) | | 798 | port->flags = (port->flags & ~UPF_CHANGE_MASK) | |
802 | (new_flags & UPF_CHANGE_MASK); | 799 | (new_flags & UPF_CHANGE_MASK); |
803 | port->custom_divisor = new_serial.custom_divisor; | 800 | port->custom_divisor = new_serial.custom_divisor; |
@@ -1220,7 +1217,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1220 | 1217 | ||
1221 | port = state->port; | 1218 | port = state->port; |
1222 | 1219 | ||
1223 | DPRINTK("uart_close(%d) called\n", port->line); | 1220 | pr_debug("uart_close(%d) called\n", port->line); |
1224 | 1221 | ||
1225 | mutex_lock(&state->mutex); | 1222 | mutex_lock(&state->mutex); |
1226 | 1223 | ||
@@ -1339,7 +1336,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1339 | 1336 | ||
1340 | expire = jiffies + timeout; | 1337 | expire = jiffies + timeout; |
1341 | 1338 | ||
1342 | DPRINTK("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n", | 1339 | pr_debug("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n", |
1343 | port->line, jiffies, expire); | 1340 | port->line, jiffies, expire); |
1344 | 1341 | ||
1345 | /* | 1342 | /* |
@@ -1368,7 +1365,7 @@ static void uart_hangup(struct tty_struct *tty) | |||
1368 | struct uart_state *state = tty->driver_data; | 1365 | struct uart_state *state = tty->driver_data; |
1369 | 1366 | ||
1370 | BUG_ON(!kernel_locked()); | 1367 | BUG_ON(!kernel_locked()); |
1371 | DPRINTK("uart_hangup(%d)\n", state->port->line); | 1368 | pr_debug("uart_hangup(%d)\n", state->port->line); |
1372 | 1369 | ||
1373 | mutex_lock(&state->mutex); | 1370 | mutex_lock(&state->mutex); |
1374 | if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) { | 1371 | if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) { |
@@ -1566,7 +1563,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1566 | int retval, line = tty->index; | 1563 | int retval, line = tty->index; |
1567 | 1564 | ||
1568 | BUG_ON(!kernel_locked()); | 1565 | BUG_ON(!kernel_locked()); |
1569 | DPRINTK("uart_open(%d) called\n", line); | 1566 | pr_debug("uart_open(%d) called\n", line); |
1570 | 1567 | ||
1571 | /* | 1568 | /* |
1572 | * tty->driver->num won't change, so we won't fail here with | 1569 | * tty->driver->num won't change, so we won't fail here with |
@@ -2064,6 +2061,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) | |||
2064 | case UPIO_MEM32: | 2061 | case UPIO_MEM32: |
2065 | case UPIO_AU: | 2062 | case UPIO_AU: |
2066 | case UPIO_TSI: | 2063 | case UPIO_TSI: |
2064 | case UPIO_DWAPB: | ||
2067 | snprintf(address, sizeof(address), | 2065 | snprintf(address, sizeof(address), |
2068 | "MMIO 0x%lx", port->mapbase); | 2066 | "MMIO 0x%lx", port->mapbase); |
2069 | break; | 2067 | break; |
@@ -2409,6 +2407,7 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) | |||
2409 | case UPIO_MEM32: | 2407 | case UPIO_MEM32: |
2410 | case UPIO_AU: | 2408 | case UPIO_AU: |
2411 | case UPIO_TSI: | 2409 | case UPIO_TSI: |
2410 | case UPIO_DWAPB: | ||
2412 | return (port1->mapbase == port2->mapbase); | 2411 | return (port1->mapbase == port2->mapbase); |
2413 | } | 2412 | } |
2414 | return 0; | 2413 | return 0; |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 46c40bbc4bc..1f89496d530 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 48 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) |
49 | #include <linux/ctype.h> | ||
49 | #include <asm/clock.h> | 50 | #include <asm/clock.h> |
50 | #include <asm/sh_bios.h> | 51 | #include <asm/sh_bios.h> |
51 | #include <asm/kgdb.h> | 52 | #include <asm/kgdb.h> |
@@ -61,7 +62,7 @@ struct sci_port { | |||
61 | unsigned int type; | 62 | unsigned int type; |
62 | 63 | ||
63 | /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ | 64 | /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ |
64 | unsigned int irqs[SCIx_NR_IRQS]; | 65 | unsigned int irqs[SCIx_NR_IRQS]; |
65 | 66 | ||
66 | /* Port pin configuration */ | 67 | /* Port pin configuration */ |
67 | void (*init_pins)(struct uart_port *port, | 68 | void (*init_pins)(struct uart_port *port, |
@@ -76,6 +77,11 @@ struct sci_port { | |||
76 | /* Break timer */ | 77 | /* Break timer */ |
77 | struct timer_list break_timer; | 78 | struct timer_list break_timer; |
78 | int break_flag; | 79 | int break_flag; |
80 | |||
81 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | ||
82 | /* Port clock */ | ||
83 | struct clk *clk; | ||
84 | #endif | ||
79 | }; | 85 | }; |
80 | 86 | ||
81 | #ifdef CONFIG_SH_KGDB | 87 | #ifdef CONFIG_SH_KGDB |
@@ -163,7 +169,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) | |||
163 | usegdb |= sh_bios_in_gdb_mode(); | 169 | usegdb |= sh_bios_in_gdb_mode(); |
164 | #endif | 170 | #endif |
165 | #ifdef CONFIG_SH_KGDB | 171 | #ifdef CONFIG_SH_KGDB |
166 | usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port)); | 172 | usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port)); |
167 | #endif | 173 | #endif |
168 | 174 | ||
169 | if (usegdb) { | 175 | if (usegdb) { |
@@ -204,7 +210,7 @@ static int kgdb_sci_getchar(void) | |||
204 | int c; | 210 | int c; |
205 | 211 | ||
206 | /* Keep trying to read a character, this could be neater */ | 212 | /* Keep trying to read a character, this could be neater */ |
207 | while ((c = get_char(kgdb_sci_port)) < 0) | 213 | while ((c = get_char(&kgdb_sci_port->port)) < 0) |
208 | cpu_relax(); | 214 | cpu_relax(); |
209 | 215 | ||
210 | return c; | 216 | return c; |
@@ -212,7 +218,7 @@ static int kgdb_sci_getchar(void) | |||
212 | 218 | ||
213 | static inline void kgdb_sci_putchar(int c) | 219 | static inline void kgdb_sci_putchar(int c) |
214 | { | 220 | { |
215 | put_char(kgdb_sci_port, c); | 221 | put_char(&kgdb_sci_port->port, c); |
216 | } | 222 | } |
217 | #endif /* CONFIG_SH_KGDB */ | 223 | #endif /* CONFIG_SH_KGDB */ |
218 | 224 | ||
@@ -283,12 +289,23 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) | |||
283 | #endif | 289 | #endif |
284 | 290 | ||
285 | #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF) | 291 | #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF) |
286 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7710) | 292 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) |
287 | /* SH7300 doesn't use RTS/CTS */ | 293 | /* SH7300 doesn't use RTS/CTS */ |
288 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 294 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) |
289 | { | 295 | { |
290 | sci_out(port, SCFCR, 0); | 296 | sci_out(port, SCFCR, 0); |
291 | } | 297 | } |
298 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | ||
299 | static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag) | ||
300 | { | ||
301 | unsigned int fcr_val = 0; | ||
302 | |||
303 | set_sh771x_scif_pfc(port); | ||
304 | if (cflag & CRTSCTS) { | ||
305 | fcr_val |= SCFCR_MCE; | ||
306 | } | ||
307 | sci_out(port, SCFCR, fcr_val); | ||
308 | } | ||
292 | #elif defined(CONFIG_CPU_SH3) | 309 | #elif defined(CONFIG_CPU_SH3) |
293 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ | 310 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ |
294 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 311 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) |
@@ -350,7 +367,7 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | |||
350 | } else { | 367 | } else { |
351 | #ifdef CONFIG_CPU_SUBTYPE_SH7343 | 368 | #ifdef CONFIG_CPU_SUBTYPE_SH7343 |
352 | /* Nothing */ | 369 | /* Nothing */ |
353 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | 370 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) |
354 | ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ | 371 | ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ |
355 | #else | 372 | #else |
356 | ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ | 373 | ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ |
@@ -360,7 +377,9 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | |||
360 | } | 377 | } |
361 | #endif | 378 | #endif |
362 | 379 | ||
363 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) | 380 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ |
381 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | ||
382 | defined(CONFIG_CPU_SUBTYPE_SH7785) | ||
364 | static inline int scif_txroom(struct uart_port *port) | 383 | static inline int scif_txroom(struct uart_port *port) |
365 | { | 384 | { |
366 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f); | 385 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f); |
@@ -735,12 +754,6 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) | |||
735 | 754 | ||
736 | /* Handle BREAKs */ | 755 | /* Handle BREAKs */ |
737 | sci_handle_breaks(port); | 756 | sci_handle_breaks(port); |
738 | |||
739 | #ifdef CONFIG_SH_KGDB | ||
740 | /* Break into the debugger if a break is detected */ | ||
741 | BREAKPOINT(); | ||
742 | #endif | ||
743 | |||
744 | sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); | 757 | sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); |
745 | 758 | ||
746 | return IRQ_HANDLED; | 759 | return IRQ_HANDLED; |
@@ -947,6 +960,10 @@ static int sci_startup(struct uart_port *port) | |||
947 | if (s->enable) | 960 | if (s->enable) |
948 | s->enable(port); | 961 | s->enable(port); |
949 | 962 | ||
963 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | ||
964 | s->clk = clk_get(NULL, "module_clk"); | ||
965 | #endif | ||
966 | |||
950 | sci_request_irq(s); | 967 | sci_request_irq(s); |
951 | sci_start_tx(port); | 968 | sci_start_tx(port); |
952 | sci_start_rx(port, 1); | 969 | sci_start_rx(port, 1); |
@@ -964,6 +981,11 @@ static void sci_shutdown(struct uart_port *port) | |||
964 | 981 | ||
965 | if (s->disable) | 982 | if (s->disable) |
966 | s->disable(port); | 983 | s->disable(port); |
984 | |||
985 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | ||
986 | clk_put(s->clk); | ||
987 | s->clk = NULL; | ||
988 | #endif | ||
967 | } | 989 | } |
968 | 990 | ||
969 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 991 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
@@ -971,7 +993,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
971 | { | 993 | { |
972 | struct sci_port *s = &sci_ports[port->line]; | 994 | struct sci_port *s = &sci_ports[port->line]; |
973 | unsigned int status, baud, smr_val; | 995 | unsigned int status, baud, smr_val; |
974 | unsigned long flags; | ||
975 | int t; | 996 | int t; |
976 | 997 | ||
977 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 998 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
@@ -983,18 +1004,14 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
983 | default: | 1004 | default: |
984 | { | 1005 | { |
985 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 1006 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) |
986 | struct clk *clk = clk_get(NULL, "module_clk"); | 1007 | t = SCBRR_VALUE(baud, clk_get_rate(s->clk)); |
987 | t = SCBRR_VALUE(baud, clk_get_rate(clk)); | ||
988 | clk_put(clk); | ||
989 | #else | 1008 | #else |
990 | t = SCBRR_VALUE(baud); | 1009 | t = SCBRR_VALUE(baud); |
991 | #endif | 1010 | #endif |
992 | } | ||
993 | break; | 1011 | break; |
1012 | } | ||
994 | } | 1013 | } |
995 | 1014 | ||
996 | spin_lock_irqsave(&port->lock, flags); | ||
997 | |||
998 | do { | 1015 | do { |
999 | status = sci_in(port, SCxSR); | 1016 | status = sci_in(port, SCxSR); |
1000 | } while (!(status & SCxSR_TEND(port))); | 1017 | } while (!(status & SCxSR_TEND(port))); |
@@ -1038,8 +1055,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1038 | 1055 | ||
1039 | if ((termios->c_cflag & CREAD) != 0) | 1056 | if ((termios->c_cflag & CREAD) != 0) |
1040 | sci_start_rx(port,0); | 1057 | sci_start_rx(port,0); |
1041 | |||
1042 | spin_unlock_irqrestore(&port->lock, flags); | ||
1043 | } | 1058 | } |
1044 | 1059 | ||
1045 | static const char *sci_type(struct uart_port *port) | 1060 | static const char *sci_type(struct uart_port *port) |
@@ -1220,10 +1235,13 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
1220 | if (!port->membase || !port->mapbase) | 1235 | if (!port->membase || !port->mapbase) |
1221 | return -ENODEV; | 1236 | return -ENODEV; |
1222 | 1237 | ||
1223 | spin_lock_init(&port->lock); | ||
1224 | |||
1225 | port->type = serial_console_port->type; | 1238 | port->type = serial_console_port->type; |
1226 | 1239 | ||
1240 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | ||
1241 | if (!serial_console_port->clk) | ||
1242 | serial_console_port->clk = clk_get(NULL, "module_clk"); | ||
1243 | #endif | ||
1244 | |||
1227 | if (port->flags & UPF_IOREMAP) | 1245 | if (port->flags & UPF_IOREMAP) |
1228 | sci_config_port(port, 0); | 1246 | sci_config_port(port, 0); |
1229 | 1247 | ||
@@ -1247,7 +1265,7 @@ static struct console serial_console = { | |||
1247 | .device = uart_console_device, | 1265 | .device = uart_console_device, |
1248 | .write = serial_console_write, | 1266 | .write = serial_console_write, |
1249 | .setup = serial_console_setup, | 1267 | .setup = serial_console_setup, |
1250 | .flags = CON_PRINTBUFFER, | 1268 | .flags = CON_PRINTBUFFER, |
1251 | .index = -1, | 1269 | .index = -1, |
1252 | .data = &sci_uart_driver, | 1270 | .data = &sci_uart_driver, |
1253 | }; | 1271 | }; |
@@ -1292,11 +1310,23 @@ int __init kgdb_console_setup(struct console *co, char *options) | |||
1292 | int parity = 'n'; | 1310 | int parity = 'n'; |
1293 | int flow = 'n'; | 1311 | int flow = 'n'; |
1294 | 1312 | ||
1295 | spin_lock_init(&port->lock); | ||
1296 | |||
1297 | if (co->index != kgdb_portnum) | 1313 | if (co->index != kgdb_portnum) |
1298 | co->index = kgdb_portnum; | 1314 | co->index = kgdb_portnum; |
1299 | 1315 | ||
1316 | kgdb_sci_port = &sci_ports[co->index]; | ||
1317 | port = &kgdb_sci_port->port; | ||
1318 | |||
1319 | /* | ||
1320 | * Also need to check port->type, we don't actually have any | ||
1321 | * UPIO_PORT ports, but uart_report_port() handily misreports | ||
1322 | * it anyways if we don't have a port available by the time this is | ||
1323 | * called. | ||
1324 | */ | ||
1325 | if (!port->type) | ||
1326 | return -ENODEV; | ||
1327 | if (!port->membase || !port->mapbase) | ||
1328 | return -ENODEV; | ||
1329 | |||
1300 | if (options) | 1330 | if (options) |
1301 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1331 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
1302 | else | 1332 | else |
@@ -1311,11 +1341,12 @@ int __init kgdb_console_setup(struct console *co, char *options) | |||
1311 | 1341 | ||
1312 | #ifdef CONFIG_SH_KGDB_CONSOLE | 1342 | #ifdef CONFIG_SH_KGDB_CONSOLE |
1313 | static struct console kgdb_console = { | 1343 | static struct console kgdb_console = { |
1314 | .name = "ttySC", | 1344 | .name = "ttySC", |
1315 | .write = kgdb_console_write, | 1345 | .device = uart_console_device, |
1316 | .setup = kgdb_console_setup, | 1346 | .write = kgdb_console_write, |
1317 | .flags = CON_PRINTBUFFER | CON_ENABLED, | 1347 | .setup = kgdb_console_setup, |
1318 | .index = -1, | 1348 | .flags = CON_PRINTBUFFER, |
1349 | .index = -1, | ||
1319 | .data = &sci_uart_driver, | 1350 | .data = &sci_uart_driver, |
1320 | }; | 1351 | }; |
1321 | 1352 | ||
@@ -1361,9 +1392,19 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1361 | struct plat_sci_port *p = dev->dev.platform_data; | 1392 | struct plat_sci_port *p = dev->dev.platform_data; |
1362 | int i; | 1393 | int i; |
1363 | 1394 | ||
1364 | for (i = 0; p && p->flags != 0 && i < SCI_NPORTS; p++, i++) { | 1395 | for (i = 0; p && p->flags != 0; p++, i++) { |
1365 | struct sci_port *sciport = &sci_ports[i]; | 1396 | struct sci_port *sciport = &sci_ports[i]; |
1366 | 1397 | ||
1398 | /* Sanity check */ | ||
1399 | if (unlikely(i == SCI_NPORTS)) { | ||
1400 | dev_notice(&dev->dev, "Attempting to register port " | ||
1401 | "%d when only %d are available.\n", | ||
1402 | i+1, SCI_NPORTS); | ||
1403 | dev_notice(&dev->dev, "Consider bumping " | ||
1404 | "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n"); | ||
1405 | break; | ||
1406 | } | ||
1407 | |||
1367 | sciport->port.mapbase = p->mapbase; | 1408 | sciport->port.mapbase = p->mapbase; |
1368 | 1409 | ||
1369 | /* | 1410 | /* |
@@ -1386,6 +1427,12 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1386 | uart_add_one_port(&sci_uart_driver, &sciport->port); | 1427 | uart_add_one_port(&sci_uart_driver, &sciport->port); |
1387 | } | 1428 | } |
1388 | 1429 | ||
1430 | #if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE) | ||
1431 | kgdb_sci_port = &sci_ports[kgdb_portnum]; | ||
1432 | kgdb_getchar = kgdb_sci_getchar; | ||
1433 | kgdb_putchar = kgdb_sci_putchar; | ||
1434 | #endif | ||
1435 | |||
1389 | #ifdef CONFIG_CPU_FREQ | 1436 | #ifdef CONFIG_CPU_FREQ |
1390 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1437 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1391 | dev_info(&dev->dev, "sci: CPU frequency notifier registered\n"); | 1438 | dev_info(&dev->dev, "sci: CPU frequency notifier registered\n"); |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 77f7d6351ab..fb04fb5f984 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -73,9 +73,13 @@ | |||
73 | # define SCPDR 0xA4050136 /* 16 bit SCIF */ | 73 | # define SCPDR 0xA4050136 /* 16 bit SCIF */ |
74 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ | 74 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ |
75 | # define SCIF_ONLY | 75 | # define SCIF_ONLY |
76 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) | 76 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
77 | # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ | 77 | # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ |
78 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ | 78 | # define SCI_NPORTS 2 |
79 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
80 | # define PACR 0xa4050100 | ||
81 | # define PBCR 0xa4050102 | ||
82 | # define SCSCR_INIT(port) 0x3B | ||
79 | # define SCIF_ONLY | 83 | # define SCIF_ONLY |
80 | #elif defined(CONFIG_CPU_SUBTYPE_SH73180) | 84 | #elif defined(CONFIG_CPU_SUBTYPE_SH73180) |
81 | # define SCPDR 0xA4050138 /* 16 bit SCIF */ | 85 | # define SCPDR 0xA4050138 /* 16 bit SCIF */ |
@@ -140,6 +144,16 @@ | |||
140 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | 144 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
141 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 145 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
142 | # define SCIF_ONLY | 146 | # define SCIF_ONLY |
147 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) | ||
148 | # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ | ||
149 | # define SCSPTR1 0xffeb0024 /* 16 bit SCIF */ | ||
150 | # define SCSPTR2 0xffec0024 /* 16 bit SCIF */ | ||
151 | # define SCSPTR3 0xffed0024 /* 16 bit SCIF */ | ||
152 | # define SCSPTR4 0xffee0024 /* 16 bit SCIF */ | ||
153 | # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ | ||
154 | # define SCIF_OPER 0x0001 /* Overrun error bit */ | ||
155 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | ||
156 | # define SCIF_ONLY | ||
143 | #elif defined(CONFIG_CPU_SUBTYPE_SH7206) | 157 | #elif defined(CONFIG_CPU_SUBTYPE_SH7206) |
144 | # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ | 158 | # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ |
145 | # define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ | 159 | # define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ |
@@ -163,7 +177,10 @@ | |||
163 | #define SCI_CTRL_FLAGS_RIE 0x40 /* all */ | 177 | #define SCI_CTRL_FLAGS_RIE 0x40 /* all */ |
164 | #define SCI_CTRL_FLAGS_TE 0x20 /* all */ | 178 | #define SCI_CTRL_FLAGS_TE 0x20 /* all */ |
165 | #define SCI_CTRL_FLAGS_RE 0x10 /* all */ | 179 | #define SCI_CTRL_FLAGS_RE 0x10 /* all */ |
166 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7780) | 180 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ |
181 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | ||
182 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | ||
183 | defined(CONFIG_CPU_SUBTYPE_SH7785) | ||
167 | #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ | 184 | #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ |
168 | #else | 185 | #else |
169 | #define SCI_CTRL_FLAGS_REIE 0 | 186 | #define SCI_CTRL_FLAGS_REIE 0 |
@@ -333,9 +350,15 @@ | |||
333 | } | 350 | } |
334 | 351 | ||
335 | #ifdef CONFIG_CPU_SH3 | 352 | #ifdef CONFIG_CPU_SH3 |
336 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ | 353 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
337 | defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 354 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ |
338 | defined(CONFIG_CPU_SUBTYPE_SH7710) | 355 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ |
356 | h8_sci_offset, h8_sci_size) \ | ||
357 | CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size) | ||
358 | #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ | ||
359 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) | ||
360 | #elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \ | ||
361 | defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
339 | #define SCIF_FNS(name, scif_offset, scif_size) \ | 362 | #define SCIF_FNS(name, scif_offset, scif_size) \ |
340 | CPU_SCIF_FNS(name, scif_offset, scif_size) | 363 | CPU_SCIF_FNS(name, scif_offset, scif_size) |
341 | #else | 364 | #else |
@@ -362,8 +385,8 @@ | |||
362 | #endif | 385 | #endif |
363 | 386 | ||
364 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ | 387 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ |
365 | defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 388 | defined(CONFIG_CPU_SUBTYPE_SH7705) |
366 | defined(CONFIG_CPU_SUBTYPE_SH7710) | 389 | |
367 | SCIF_FNS(SCSMR, 0x00, 16) | 390 | SCIF_FNS(SCSMR, 0x00, 16) |
368 | SCIF_FNS(SCBRR, 0x04, 8) | 391 | SCIF_FNS(SCBRR, 0x04, 8) |
369 | SCIF_FNS(SCSCR, 0x08, 16) | 392 | SCIF_FNS(SCSCR, 0x08, 16) |
@@ -385,7 +408,9 @@ SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8, 0x03, 8) | |||
385 | SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8) | 408 | SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8) |
386 | SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) | 409 | SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) |
387 | SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) | 410 | SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) |
388 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) | 411 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ |
412 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | ||
413 | defined(CONFIG_CPU_SUBTYPE_SH7785) | ||
389 | SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) | 414 | SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) |
390 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) | 415 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) |
391 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) | 416 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) |
@@ -471,13 +496,24 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
471 | return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ | 496 | return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ |
472 | return 1; | 497 | return 1; |
473 | } | 498 | } |
474 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) | 499 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
475 | static inline int sci_rxd_in(struct uart_port *port) | 500 | static inline int sci_rxd_in(struct uart_port *port) |
476 | { | 501 | { |
477 | if (port->mapbase == SCSPTR0) | 502 | return sci_in(port,SCxSR)&0x0010 ? 1 : 0; |
478 | return ctrl_inw(SCSPTR0 + 0x10) & 0x01 ? 1 : 0; | 503 | } |
479 | return 1; | 504 | static inline void set_sh771x_scif_pfc(struct uart_port *port) |
505 | { | ||
506 | if (port->mapbase == 0xA4400000){ | ||
507 | ctrl_outw(ctrl_inw(PACR)&0xffc0,PACR); | ||
508 | ctrl_outw(ctrl_inw(PBCR)&0x0fff,PBCR); | ||
509 | return; | ||
510 | } | ||
511 | if (port->mapbase == 0xA4410000){ | ||
512 | ctrl_outw(ctrl_inw(PBCR)&0xf003,PBCR); | ||
513 | return; | ||
514 | } | ||
480 | } | 515 | } |
516 | |||
481 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | 517 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ |
482 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | 518 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ |
483 | defined(CONFIG_CPU_SUBTYPE_SH4_202) | 519 | defined(CONFIG_CPU_SUBTYPE_SH4_202) |
@@ -576,6 +612,23 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
576 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 612 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
577 | return 1; | 613 | return 1; |
578 | } | 614 | } |
615 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) | ||
616 | static inline int sci_rxd_in(struct uart_port *port) | ||
617 | { | ||
618 | if (port->mapbase == 0xffea0000) | ||
619 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
620 | if (port->mapbase == 0xffeb0000) | ||
621 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
622 | if (port->mapbase == 0xffec0000) | ||
623 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
624 | if (port->mapbase == 0xffed0000) | ||
625 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | ||
626 | if (port->mapbase == 0xffee0000) | ||
627 | return ctrl_inw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */ | ||
628 | if (port->mapbase == 0xffef0000) | ||
629 | return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ | ||
630 | return 1; | ||
631 | } | ||
579 | #elif defined(CONFIG_CPU_SUBTYPE_SH7206) | 632 | #elif defined(CONFIG_CPU_SUBTYPE_SH7206) |
580 | static inline int sci_rxd_in(struct uart_port *port) | 633 | static inline int sci_rxd_in(struct uart_port *port) |
581 | { | 634 | { |
@@ -634,7 +687,9 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
634 | * -- Mitch Davis - 15 Jul 2000 | 687 | * -- Mitch Davis - 15 Jul 2000 |
635 | */ | 688 | */ |
636 | 689 | ||
637 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7780) | 690 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ |
691 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | ||
692 | defined(CONFIG_CPU_SUBTYPE_SH7785) | ||
638 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) | 693 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) |
639 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) | 694 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) |
640 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) | 695 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index bfd44177a21..2a63cdba320 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1312,7 +1312,7 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1312 | * - initialize the serial port | 1312 | * - initialize the serial port |
1313 | * Return non-zero if we didn't find a serial port. | 1313 | * Return non-zero if we didn't find a serial port. |
1314 | */ | 1314 | */ |
1315 | static int sunsu_console_setup(struct console *co, char *options) | 1315 | static int __init sunsu_console_setup(struct console *co, char *options) |
1316 | { | 1316 | { |
1317 | struct uart_port *port; | 1317 | struct uart_port *port; |
1318 | int baud = 9600; | 1318 | int baud = 9600; |
@@ -1343,7 +1343,7 @@ static int sunsu_console_setup(struct console *co, char *options) | |||
1343 | return uart_set_options(port, co, baud, parity, bits, flow); | 1343 | return uart_set_options(port, co, baud, parity, bits, flow); |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | static struct console sunsu_cons = { | 1346 | static struct console sunsu_console = { |
1347 | .name = "ttyS", | 1347 | .name = "ttyS", |
1348 | .write = sunsu_console_write, | 1348 | .write = sunsu_console_write, |
1349 | .device = uart_console_device, | 1349 | .device = uart_console_device, |
@@ -1373,9 +1373,9 @@ static inline struct console *SUNSU_CONSOLE(int num_uart) | |||
1373 | if (i == num_uart) | 1373 | if (i == num_uart) |
1374 | return NULL; | 1374 | return NULL; |
1375 | 1375 | ||
1376 | sunsu_cons.index = i; | 1376 | sunsu_console.index = i; |
1377 | 1377 | ||
1378 | return &sunsu_cons; | 1378 | return &sunsu_console; |
1379 | } | 1379 | } |
1380 | #else | 1380 | #else |
1381 | #define SUNSU_CONSOLE(num_uart) (NULL) | 1381 | #define SUNSU_CONSOLE(num_uart) (NULL) |