diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-09-09 16:01:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 16:57:27 -0400 |
commit | f5ee56cc184e0944ebc9ff1691985219959596f6 (patch) | |
tree | d882e1c8c670ad33c54c53c5851e08b012b7988d /drivers/serial/serial_txx9.c | |
parent | fef266580e5cf897a1b63528fc6b1185e2d6bb87 (diff) |
[PATCH] txx9 serial update
Support for the new RBHMA4500 eval board for the TX4938. General update
from the 8250 ancestor of this driver. Replace use of deprecated
interfaces.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Acked-by: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/serial/serial_txx9.c')
-rw-r--r-- | drivers/serial/serial_txx9.c | 118 |
1 files changed, 91 insertions, 27 deletions
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 49afadbe461b..f10c86d60b64 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -31,6 +31,8 @@ | |||
31 | * 1.01 Set fifosize to make tx_empry called properly. | 31 | * 1.01 Set fifosize to make tx_empry called properly. |
32 | * Use standard uart_get_divisor. | 32 | * Use standard uart_get_divisor. |
33 | * 1.02 Cleanup. (import 8250.c changes) | 33 | * 1.02 Cleanup. (import 8250.c changes) |
34 | * 1.03 Fix low-latency mode. (import 8250.c changes) | ||
35 | * 1.04 Remove usage of deprecated functions, cleanup. | ||
34 | */ | 36 | */ |
35 | #include <linux/config.h> | 37 | #include <linux/config.h> |
36 | 38 | ||
@@ -54,7 +56,7 @@ | |||
54 | #include <asm/io.h> | 56 | #include <asm/io.h> |
55 | #include <asm/irq.h> | 57 | #include <asm/irq.h> |
56 | 58 | ||
57 | static char *serial_version = "1.02"; | 59 | static char *serial_version = "1.04"; |
58 | static char *serial_name = "TX39/49 Serial driver"; | 60 | static char *serial_name = "TX39/49 Serial driver"; |
59 | 61 | ||
60 | #define PASS_LIMIT 256 | 62 | #define PASS_LIMIT 256 |
@@ -86,9 +88,9 @@ static char *serial_name = "TX39/49 Serial driver"; | |||
86 | */ | 88 | */ |
87 | #ifdef ENABLE_SERIAL_TXX9_PCI | 89 | #ifdef ENABLE_SERIAL_TXX9_PCI |
88 | #define NR_PCI_BOARDS 4 | 90 | #define NR_PCI_BOARDS 4 |
89 | #define UART_NR (2 + NR_PCI_BOARDS) | 91 | #define UART_NR (4 + NR_PCI_BOARDS) |
90 | #else | 92 | #else |
91 | #define UART_NR 2 | 93 | #define UART_NR 4 |
92 | #endif | 94 | #endif |
93 | 95 | ||
94 | struct uart_txx9_port { | 96 | struct uart_txx9_port { |
@@ -304,8 +306,11 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r | |||
304 | /* The following is not allowed by the tty layer and | 306 | /* The following is not allowed by the tty layer and |
305 | unsafe. It should be fixed ASAP */ | 307 | unsafe. It should be fixed ASAP */ |
306 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { | 308 | if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { |
307 | if(tty->low_latency) | 309 | if (tty->low_latency) { |
310 | spin_unlock(&up->port.lock); | ||
308 | tty_flip_buffer_push(tty); | 311 | tty_flip_buffer_push(tty); |
312 | spin_lock(&up->port.lock); | ||
313 | } | ||
309 | /* If this failed then we will throw away the | 314 | /* If this failed then we will throw away the |
310 | bytes but must do so to clear interrupts */ | 315 | bytes but must do so to clear interrupts */ |
311 | } | 316 | } |
@@ -356,7 +361,9 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r | |||
356 | ignore_char: | 361 | ignore_char: |
357 | disr = sio_in(up, TXX9_SIDISR); | 362 | disr = sio_in(up, TXX9_SIDISR); |
358 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); | 363 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); |
364 | spin_unlock(&up->port.lock); | ||
359 | tty_flip_buffer_push(tty); | 365 | tty_flip_buffer_push(tty); |
366 | spin_lock(&up->port.lock); | ||
360 | *status = disr; | 367 | *status = disr; |
361 | } | 368 | } |
362 | 369 | ||
@@ -667,17 +674,8 @@ serial_txx9_pm(struct uart_port *port, unsigned int state, | |||
667 | unsigned int oldstate) | 674 | unsigned int oldstate) |
668 | { | 675 | { |
669 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 676 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; |
670 | if (state) { | 677 | if (up->pm) |
671 | /* sleep */ | 678 | up->pm(port, state, oldstate); |
672 | |||
673 | if (up->pm) | ||
674 | up->pm(port, state, oldstate); | ||
675 | } else { | ||
676 | /* wake */ | ||
677 | |||
678 | if (up->pm) | ||
679 | up->pm(port, state, oldstate); | ||
680 | } | ||
681 | } | 679 | } |
682 | 680 | ||
683 | static int serial_txx9_request_resource(struct uart_txx9_port *up) | 681 | static int serial_txx9_request_resource(struct uart_txx9_port *up) |
@@ -979,14 +977,6 @@ static int __init serial_txx9_console_init(void) | |||
979 | } | 977 | } |
980 | console_initcall(serial_txx9_console_init); | 978 | console_initcall(serial_txx9_console_init); |
981 | 979 | ||
982 | static int __init serial_txx9_late_console_init(void) | ||
983 | { | ||
984 | if (!(serial_txx9_console.flags & CON_ENABLED)) | ||
985 | register_console(&serial_txx9_console); | ||
986 | return 0; | ||
987 | } | ||
988 | late_initcall(serial_txx9_late_console_init); | ||
989 | |||
990 | #define SERIAL_TXX9_CONSOLE &serial_txx9_console | 980 | #define SERIAL_TXX9_CONSOLE &serial_txx9_console |
991 | #else | 981 | #else |
992 | #define SERIAL_TXX9_CONSOLE NULL | 982 | #define SERIAL_TXX9_CONSOLE NULL |
@@ -1039,6 +1029,73 @@ static void serial_txx9_resume_port(int line) | |||
1039 | uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port); | 1029 | uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port); |
1040 | } | 1030 | } |
1041 | 1031 | ||
1032 | static DECLARE_MUTEX(serial_txx9_sem); | ||
1033 | |||
1034 | /** | ||
1035 | * serial_txx9_register_port - register a serial port | ||
1036 | * @port: serial port template | ||
1037 | * | ||
1038 | * Configure the serial port specified by the request. | ||
1039 | * | ||
1040 | * The port is then probed and if necessary the IRQ is autodetected | ||
1041 | * If this fails an error is returned. | ||
1042 | * | ||
1043 | * On success the port is ready to use and the line number is returned. | ||
1044 | */ | ||
1045 | static int __devinit serial_txx9_register_port(struct uart_port *port) | ||
1046 | { | ||
1047 | int i; | ||
1048 | struct uart_txx9_port *uart; | ||
1049 | int ret = -ENOSPC; | ||
1050 | |||
1051 | down(&serial_txx9_sem); | ||
1052 | for (i = 0; i < UART_NR; i++) { | ||
1053 | uart = &serial_txx9_ports[i]; | ||
1054 | if (uart->port.type == PORT_UNKNOWN) | ||
1055 | break; | ||
1056 | } | ||
1057 | if (i < UART_NR) { | ||
1058 | uart_remove_one_port(&serial_txx9_reg, &uart->port); | ||
1059 | uart->port.iobase = port->iobase; | ||
1060 | uart->port.membase = port->membase; | ||
1061 | uart->port.irq = port->irq; | ||
1062 | uart->port.uartclk = port->uartclk; | ||
1063 | uart->port.iotype = port->iotype; | ||
1064 | uart->port.flags = port->flags | UPF_BOOT_AUTOCONF; | ||
1065 | uart->port.mapbase = port->mapbase; | ||
1066 | if (port->dev) | ||
1067 | uart->port.dev = port->dev; | ||
1068 | ret = uart_add_one_port(&serial_txx9_reg, &uart->port); | ||
1069 | if (ret == 0) | ||
1070 | ret = uart->port.line; | ||
1071 | } | ||
1072 | up(&serial_txx9_sem); | ||
1073 | return ret; | ||
1074 | } | ||
1075 | |||
1076 | /** | ||
1077 | * serial_txx9_unregister_port - remove a txx9 serial port at runtime | ||
1078 | * @line: serial line number | ||
1079 | * | ||
1080 | * Remove one serial port. This may not be called from interrupt | ||
1081 | * context. We hand the port back to the our control. | ||
1082 | */ | ||
1083 | static void __devexit serial_txx9_unregister_port(int line) | ||
1084 | { | ||
1085 | struct uart_txx9_port *uart = &serial_txx9_ports[line]; | ||
1086 | |||
1087 | down(&serial_txx9_sem); | ||
1088 | uart_remove_one_port(&serial_txx9_reg, &uart->port); | ||
1089 | uart->port.flags = 0; | ||
1090 | uart->port.type = PORT_UNKNOWN; | ||
1091 | uart->port.iobase = 0; | ||
1092 | uart->port.mapbase = 0; | ||
1093 | uart->port.membase = 0; | ||
1094 | uart->port.dev = NULL; | ||
1095 | uart_add_one_port(&serial_txx9_reg, &uart->port); | ||
1096 | up(&serial_txx9_sem); | ||
1097 | } | ||
1098 | |||
1042 | /* | 1099 | /* |
1043 | * Probe one serial board. Unfortunately, there is no rhyme nor reason | 1100 | * Probe one serial board. Unfortunately, there is no rhyme nor reason |
1044 | * to the arrangement of serial ports on a PCI card. | 1101 | * to the arrangement of serial ports on a PCI card. |
@@ -1056,13 +1113,13 @@ pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1056 | 1113 | ||
1057 | memset(&port, 0, sizeof(port)); | 1114 | memset(&port, 0, sizeof(port)); |
1058 | port.ops = &serial_txx9_pops; | 1115 | port.ops = &serial_txx9_pops; |
1059 | port.flags |= UPF_BOOT_AUTOCONF; /* uart_ops.config_port will be called */ | ||
1060 | port.flags |= UPF_TXX9_HAVE_CTS_LINE; | 1116 | port.flags |= UPF_TXX9_HAVE_CTS_LINE; |
1061 | port.uartclk = 66670000; | 1117 | port.uartclk = 66670000; |
1062 | port.irq = dev->irq; | 1118 | port.irq = dev->irq; |
1063 | port.iotype = UPIO_PORT; | 1119 | port.iotype = UPIO_PORT; |
1064 | port.iobase = pci_resource_start(dev, 1); | 1120 | port.iobase = pci_resource_start(dev, 1); |
1065 | line = uart_register_port(&serial_txx9_reg, &port); | 1121 | port.dev = &dev->dev; |
1122 | line = serial_txx9_register_port(&port); | ||
1066 | if (line < 0) { | 1123 | if (line < 0) { |
1067 | printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line); | 1124 | printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line); |
1068 | } | 1125 | } |
@@ -1078,7 +1135,7 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev) | |||
1078 | pci_set_drvdata(dev, NULL); | 1135 | pci_set_drvdata(dev, NULL); |
1079 | 1136 | ||
1080 | if (line) { | 1137 | if (line) { |
1081 | uart_unregister_port(&serial_txx9_reg, line); | 1138 | serial_txx9_unregister_port(line); |
1082 | pci_disable_device(dev); | 1139 | pci_disable_device(dev); |
1083 | } | 1140 | } |
1084 | } | 1141 | } |
@@ -1089,6 +1146,8 @@ static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state) | |||
1089 | 1146 | ||
1090 | if (line) | 1147 | if (line) |
1091 | serial_txx9_suspend_port(line); | 1148 | serial_txx9_suspend_port(line); |
1149 | pci_save_state(dev); | ||
1150 | pci_set_power_state(dev, pci_choose_state(dev, state)); | ||
1092 | return 0; | 1151 | return 0; |
1093 | } | 1152 | } |
1094 | 1153 | ||
@@ -1096,8 +1155,13 @@ static int pciserial_txx9_resume_one(struct pci_dev *dev) | |||
1096 | { | 1155 | { |
1097 | int line = (int)(long)pci_get_drvdata(dev); | 1156 | int line = (int)(long)pci_get_drvdata(dev); |
1098 | 1157 | ||
1099 | if (line) | 1158 | pci_set_power_state(dev, PCI_D0); |
1159 | pci_restore_state(dev); | ||
1160 | |||
1161 | if (line) { | ||
1162 | pci_enable_device(dev); | ||
1100 | serial_txx9_resume_port(line); | 1163 | serial_txx9_resume_port(line); |
1164 | } | ||
1101 | return 0; | 1165 | return 0; |
1102 | } | 1166 | } |
1103 | 1167 | ||