diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/68360serial.c | 7 | ||||
-rw-r--r-- | drivers/serial/8250.c | 28 | ||||
-rw-r--r-- | drivers/serial/8250_early.c | 117 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 62 | ||||
-rw-r--r-- | drivers/serial/atmel_serial.c | 32 | ||||
-rw-r--r-- | drivers/serial/bfin_5xx.c | 201 | ||||
-rw-r--r-- | drivers/serial/ip22zilog.c | 3 | ||||
-rw-r--r-- | drivers/serial/jsm/jsm_driver.c | 2 | ||||
-rw-r--r-- | drivers/serial/mpsc.c | 3 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 6 | ||||
-rw-r--r-- | drivers/serial/serial_cs.c | 4 | ||||
-rw-r--r-- | drivers/serial/sn_console.c | 4 | ||||
-rw-r--r-- | drivers/serial/vr41xx_siu.c | 143 |
13 files changed, 396 insertions, 216 deletions
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 68817a7d8c0d..2aa6bfe8fdb3 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -934,8 +934,6 @@ static void change_speed(ser_info_t *info) | |||
934 | /* | 934 | /* |
935 | * Set up parity check flag | 935 | * Set up parity check flag |
936 | */ | 936 | */ |
937 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | ||
938 | |||
939 | info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); | 937 | info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); |
940 | if (I_INPCK(info->tty)) | 938 | if (I_INPCK(info->tty)) |
941 | info->read_status_mask |= BD_SC_FR | BD_SC_PR; | 939 | info->read_status_mask |= BD_SC_FR | BD_SC_PR; |
@@ -1527,11 +1525,6 @@ static void rs_360_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
1527 | { | 1525 | { |
1528 | ser_info_t *info = (ser_info_t *)tty->driver_data; | 1526 | ser_info_t *info = (ser_info_t *)tty->driver_data; |
1529 | 1527 | ||
1530 | if ( (tty->termios->c_cflag == old_termios->c_cflag) | ||
1531 | && ( RELEVANT_IFLAG(tty->termios->c_iflag) | ||
1532 | == RELEVANT_IFLAG(old_termios->c_iflag))) | ||
1533 | return; | ||
1534 | |||
1535 | change_speed(info); | 1528 | change_speed(info); |
1536 | 1529 | ||
1537 | #ifdef modem_control | 1530 | #ifdef modem_control |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index c84dab083a85..0b3ec38ae614 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2514,12 +2514,18 @@ static int __init serial8250_console_setup(struct console *co, char *options) | |||
2514 | return uart_set_options(port, co, baud, parity, bits, flow); | 2514 | return uart_set_options(port, co, baud, parity, bits, flow); |
2515 | } | 2515 | } |
2516 | 2516 | ||
2517 | static int __init serial8250_console_early_setup(void) | ||
2518 | { | ||
2519 | return serial8250_find_port_for_earlycon(); | ||
2520 | } | ||
2521 | |||
2517 | static struct uart_driver serial8250_reg; | 2522 | static struct uart_driver serial8250_reg; |
2518 | static struct console serial8250_console = { | 2523 | static struct console serial8250_console = { |
2519 | .name = "ttyS", | 2524 | .name = "ttyS", |
2520 | .write = serial8250_console_write, | 2525 | .write = serial8250_console_write, |
2521 | .device = uart_console_device, | 2526 | .device = uart_console_device, |
2522 | .setup = serial8250_console_setup, | 2527 | .setup = serial8250_console_setup, |
2528 | .early_setup = serial8250_console_early_setup, | ||
2523 | .flags = CON_PRINTBUFFER, | 2529 | .flags = CON_PRINTBUFFER, |
2524 | .index = -1, | 2530 | .index = -1, |
2525 | .data = &serial8250_reg, | 2531 | .data = &serial8250_reg, |
@@ -2533,7 +2539,7 @@ static int __init serial8250_console_init(void) | |||
2533 | } | 2539 | } |
2534 | console_initcall(serial8250_console_init); | 2540 | console_initcall(serial8250_console_init); |
2535 | 2541 | ||
2536 | static int __init find_port(struct uart_port *p) | 2542 | int serial8250_find_port(struct uart_port *p) |
2537 | { | 2543 | { |
2538 | int line; | 2544 | int line; |
2539 | struct uart_port *port; | 2545 | struct uart_port *port; |
@@ -2546,26 +2552,6 @@ static int __init find_port(struct uart_port *p) | |||
2546 | return -ENODEV; | 2552 | return -ENODEV; |
2547 | } | 2553 | } |
2548 | 2554 | ||
2549 | int __init serial8250_start_console(struct uart_port *port, char *options) | ||
2550 | { | ||
2551 | int line; | ||
2552 | |||
2553 | line = find_port(port); | ||
2554 | if (line < 0) | ||
2555 | return -ENODEV; | ||
2556 | |||
2557 | add_preferred_console("ttyS", line, options); | ||
2558 | printk("Adding console on ttyS%d at %s 0x%lx (options '%s')\n", | ||
2559 | line, port->iotype == UPIO_MEM ? "MMIO" : "I/O port", | ||
2560 | port->iotype == UPIO_MEM ? (unsigned long) port->mapbase : | ||
2561 | (unsigned long) port->iobase, options); | ||
2562 | if (!(serial8250_console.flags & CON_ENABLED)) { | ||
2563 | serial8250_console.flags &= ~CON_PRINTBUFFER; | ||
2564 | register_console(&serial8250_console); | ||
2565 | } | ||
2566 | return line; | ||
2567 | } | ||
2568 | |||
2569 | #define SERIAL8250_CONSOLE &serial8250_console | 2555 | #define SERIAL8250_CONSOLE &serial8250_console |
2570 | #else | 2556 | #else |
2571 | #define SERIAL8250_CONSOLE NULL | 2557 | #define SERIAL8250_CONSOLE NULL |
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c index 7e511199b4c5..947c20507e1f 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/serial/8250_early.c | |||
@@ -17,13 +17,11 @@ | |||
17 | * we locate the device directly by its MMIO or I/O port address. | 17 | * we locate the device directly by its MMIO or I/O port address. |
18 | * | 18 | * |
19 | * The user can specify the device directly, e.g., | 19 | * The user can specify the device directly, e.g., |
20 | * console=uart,io,0x3f8,9600n8 | 20 | * earlycon=uart8250,io,0x3f8,9600n8 |
21 | * console=uart,mmio,0xff5e0000,115200n8 | 21 | * earlycon=uart8250,mmio,0xff5e0000,115200n8 |
22 | * or platform code can call early_uart_console_init() to set | 22 | * or |
23 | * the early UART device. | 23 | * console=uart8250,io,0x3f8,9600n8 |
24 | * | 24 | * console=uart8250,mmio,0xff5e0000,115200n8 |
25 | * After the normal serial driver starts, we try to locate the | ||
26 | * matching ttyS device and start a console there. | ||
27 | */ | 25 | */ |
28 | 26 | ||
29 | #include <linux/tty.h> | 27 | #include <linux/tty.h> |
@@ -32,17 +30,21 @@ | |||
32 | #include <linux/serial_core.h> | 30 | #include <linux/serial_core.h> |
33 | #include <linux/serial_reg.h> | 31 | #include <linux/serial_reg.h> |
34 | #include <linux/serial.h> | 32 | #include <linux/serial.h> |
33 | #include <linux/serial_8250.h> | ||
35 | #include <asm/io.h> | 34 | #include <asm/io.h> |
36 | #include <asm/serial.h> | 35 | #include <asm/serial.h> |
36 | #ifdef CONFIG_FIX_EARLYCON_MEM | ||
37 | #include <asm/pgtable.h> | ||
38 | #include <asm/fixmap.h> | ||
39 | #endif | ||
37 | 40 | ||
38 | struct early_uart_device { | 41 | struct early_serial8250_device { |
39 | struct uart_port port; | 42 | struct uart_port port; |
40 | char options[16]; /* e.g., 115200n8 */ | 43 | char options[16]; /* e.g., 115200n8 */ |
41 | unsigned int baud; | 44 | unsigned int baud; |
42 | }; | 45 | }; |
43 | 46 | ||
44 | static struct early_uart_device early_device __initdata; | 47 | static struct early_serial8250_device early_device; |
45 | static int early_uart_registered __initdata; | ||
46 | 48 | ||
47 | static unsigned int __init serial_in(struct uart_port *port, int offset) | 49 | static unsigned int __init serial_in(struct uart_port *port, int offset) |
48 | { | 50 | { |
@@ -80,7 +82,7 @@ static void __init putc(struct uart_port *port, int c) | |||
80 | serial_out(port, UART_TX, c); | 82 | serial_out(port, UART_TX, c); |
81 | } | 83 | } |
82 | 84 | ||
83 | static void __init early_uart_write(struct console *console, const char *s, unsigned int count) | 85 | static void __init early_serial8250_write(struct console *console, const char *s, unsigned int count) |
84 | { | 86 | { |
85 | struct uart_port *port = &early_device.port; | 87 | struct uart_port *port = &early_device.port; |
86 | unsigned int ier; | 88 | unsigned int ier; |
@@ -111,7 +113,7 @@ static unsigned int __init probe_baud(struct uart_port *port) | |||
111 | return (port->uartclk / 16) / quot; | 113 | return (port->uartclk / 16) / quot; |
112 | } | 114 | } |
113 | 115 | ||
114 | static void __init init_port(struct early_uart_device *device) | 116 | static void __init init_port(struct early_serial8250_device *device) |
115 | { | 117 | { |
116 | struct uart_port *port = &device->port; | 118 | struct uart_port *port = &device->port; |
117 | unsigned int divisor; | 119 | unsigned int divisor; |
@@ -130,10 +132,9 @@ static void __init init_port(struct early_uart_device *device) | |||
130 | serial_out(port, UART_LCR, c & ~UART_LCR_DLAB); | 132 | serial_out(port, UART_LCR, c & ~UART_LCR_DLAB); |
131 | } | 133 | } |
132 | 134 | ||
133 | static int __init parse_options(struct early_uart_device *device, char *options) | 135 | static int __init parse_options(struct early_serial8250_device *device, char *options) |
134 | { | 136 | { |
135 | struct uart_port *port = &device->port; | 137 | struct uart_port *port = &device->port; |
136 | int mapsize = 64; | ||
137 | int mmio, length; | 138 | int mmio, length; |
138 | 139 | ||
139 | if (!options) | 140 | if (!options) |
@@ -143,12 +144,18 @@ static int __init parse_options(struct early_uart_device *device, char *options) | |||
143 | if (!strncmp(options, "mmio,", 5)) { | 144 | if (!strncmp(options, "mmio,", 5)) { |
144 | port->iotype = UPIO_MEM; | 145 | port->iotype = UPIO_MEM; |
145 | port->mapbase = simple_strtoul(options + 5, &options, 0); | 146 | port->mapbase = simple_strtoul(options + 5, &options, 0); |
146 | port->membase = ioremap(port->mapbase, mapsize); | 147 | #ifdef CONFIG_FIX_EARLYCON_MEM |
148 | set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, port->mapbase & PAGE_MASK); | ||
149 | port->membase = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE); | ||
150 | port->membase += port->mapbase & ~PAGE_MASK; | ||
151 | #else | ||
152 | port->membase = ioremap(port->mapbase, 64); | ||
147 | if (!port->membase) { | 153 | if (!port->membase) { |
148 | printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n", | 154 | printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n", |
149 | __FUNCTION__, port->mapbase); | 155 | __FUNCTION__, port->mapbase); |
150 | return -ENOMEM; | 156 | return -ENOMEM; |
151 | } | 157 | } |
158 | #endif | ||
152 | mmio = 1; | 159 | mmio = 1; |
153 | } else if (!strncmp(options, "io,", 3)) { | 160 | } else if (!strncmp(options, "io,", 3)) { |
154 | port->iotype = UPIO_PORT; | 161 | port->iotype = UPIO_PORT; |
@@ -175,9 +182,16 @@ static int __init parse_options(struct early_uart_device *device, char *options) | |||
175 | return 0; | 182 | return 0; |
176 | } | 183 | } |
177 | 184 | ||
178 | static int __init early_uart_setup(struct console *console, char *options) | 185 | static struct console early_serial8250_console __initdata = { |
186 | .name = "uart", | ||
187 | .write = early_serial8250_write, | ||
188 | .flags = CON_PRINTBUFFER | CON_BOOT, | ||
189 | .index = -1, | ||
190 | }; | ||
191 | |||
192 | static int __init early_serial8250_setup(char *options) | ||
179 | { | 193 | { |
180 | struct early_uart_device *device = &early_device; | 194 | struct early_serial8250_device *device = &early_device; |
181 | int err; | 195 | int err; |
182 | 196 | ||
183 | if (device->port.membase || device->port.iobase) | 197 | if (device->port.membase || device->port.iobase) |
@@ -190,61 +204,48 @@ static int __init early_uart_setup(struct console *console, char *options) | |||
190 | return 0; | 204 | return 0; |
191 | } | 205 | } |
192 | 206 | ||
193 | static struct console early_uart_console __initdata = { | 207 | int __init setup_early_serial8250_console(char *cmdline) |
194 | .name = "uart", | ||
195 | .write = early_uart_write, | ||
196 | .setup = early_uart_setup, | ||
197 | .flags = CON_PRINTBUFFER, | ||
198 | .index = -1, | ||
199 | }; | ||
200 | |||
201 | static int __init early_uart_console_init(void) | ||
202 | { | ||
203 | if (!early_uart_registered) { | ||
204 | register_console(&early_uart_console); | ||
205 | early_uart_registered = 1; | ||
206 | } | ||
207 | return 0; | ||
208 | } | ||
209 | console_initcall(early_uart_console_init); | ||
210 | |||
211 | int __init early_serial_console_init(char *cmdline) | ||
212 | { | 208 | { |
213 | char *options; | 209 | char *options; |
214 | int err; | 210 | int err; |
215 | 211 | ||
216 | options = strstr(cmdline, "console=uart,"); | 212 | options = strstr(cmdline, "uart8250,"); |
217 | if (!options) | 213 | if (!options) { |
218 | return -ENODEV; | 214 | options = strstr(cmdline, "uart,"); |
215 | if (!options) | ||
216 | return 0; | ||
217 | } | ||
219 | 218 | ||
220 | options = strchr(cmdline, ',') + 1; | 219 | options = strchr(cmdline, ',') + 1; |
221 | if ((err = early_uart_setup(NULL, options)) < 0) | 220 | if ((err = early_serial8250_setup(options)) < 0) |
222 | return err; | 221 | return err; |
223 | return early_uart_console_init(); | 222 | |
223 | register_console(&early_serial8250_console); | ||
224 | |||
225 | return 0; | ||
224 | } | 226 | } |
225 | 227 | ||
226 | static int __init early_uart_console_switch(void) | 228 | int __init serial8250_find_port_for_earlycon(void) |
227 | { | 229 | { |
228 | struct early_uart_device *device = &early_device; | 230 | struct early_serial8250_device *device = &early_device; |
229 | struct uart_port *port = &device->port; | 231 | struct uart_port *port = &device->port; |
230 | int mmio, line; | 232 | int line; |
233 | int ret; | ||
231 | 234 | ||
232 | if (!(early_uart_console.flags & CON_ENABLED)) | 235 | if (!device->port.membase && !device->port.iobase) |
233 | return 0; | 236 | return -ENODEV; |
234 | 237 | ||
235 | /* Try to start the normal driver on a matching line. */ | 238 | line = serial8250_find_port(port); |
236 | mmio = (port->iotype == UPIO_MEM); | ||
237 | line = serial8250_start_console(port, device->options); | ||
238 | if (line < 0) | 239 | if (line < 0) |
239 | printk("No ttyS device at %s 0x%lx for console\n", | 240 | return -ENODEV; |
240 | mmio ? "MMIO" : "I/O port", | ||
241 | mmio ? port->mapbase : | ||
242 | (unsigned long) port->iobase); | ||
243 | 241 | ||
244 | unregister_console(&early_uart_console); | 242 | ret = update_console_cmdline("uart", 8250, |
245 | if (mmio) | 243 | "ttyS", line, device->options); |
246 | iounmap(port->membase); | 244 | if (ret < 0) |
245 | ret = update_console_cmdline("uart", 0, | ||
246 | "ttyS", line, device->options); | ||
247 | 247 | ||
248 | return 0; | 248 | return ret; |
249 | } | 249 | } |
250 | late_initcall(early_uart_console_switch); | 250 | |
251 | early_param("earlycon", setup_early_serial8250_console); | ||
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 315ea9916456..cab42cbd920d 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -62,8 +62,22 @@ config SERIAL_8250_CONSOLE | |||
62 | kernel will automatically use the first serial line, /dev/ttyS0, as | 62 | kernel will automatically use the first serial line, /dev/ttyS0, as |
63 | system console. | 63 | system console. |
64 | 64 | ||
65 | you can set that using a kernel command line option such as | ||
66 | "console=uart8250,io,0x3f8,9600n8" | ||
67 | "console=uart8250,mmio,0xff5e0000,115200n8". | ||
68 | and it will switch to normal serial console when correponding port is | ||
69 | ready. | ||
70 | "earlycon=uart8250,io,0x3f8,9600n8" | ||
71 | "earlycon=uart8250,mmio,0xff5e0000,115200n8". | ||
72 | it will not only setup early console. | ||
73 | |||
65 | If unsure, say N. | 74 | If unsure, say N. |
66 | 75 | ||
76 | config FIX_EARLYCON_MEM | ||
77 | bool | ||
78 | depends on X86 | ||
79 | default y | ||
80 | |||
67 | config SERIAL_8250_GSC | 81 | config SERIAL_8250_GSC |
68 | tristate | 82 | tristate |
69 | depends on SERIAL_8250 && GSC | 83 | depends on SERIAL_8250 && GSC |
@@ -556,7 +570,7 @@ choice | |||
556 | 570 | ||
557 | config SERIAL_BFIN_DMA | 571 | config SERIAL_BFIN_DMA |
558 | bool "DMA mode" | 572 | bool "DMA mode" |
559 | depends on DMA_UNCACHED_1M | 573 | depends on DMA_UNCACHED_1M && !KGDB_UART |
560 | help | 574 | help |
561 | This driver works under DMA mode. If this option is selected, the | 575 | This driver works under DMA mode. If this option is selected, the |
562 | blackfin simple dma driver is also enabled. | 576 | blackfin simple dma driver is also enabled. |
@@ -599,7 +613,7 @@ config UART0_RTS_PIN | |||
599 | 613 | ||
600 | config SERIAL_BFIN_UART1 | 614 | config SERIAL_BFIN_UART1 |
601 | bool "Enable UART1" | 615 | bool "Enable UART1" |
602 | depends on SERIAL_BFIN && (BF534 || BF536 || BF537) | 616 | depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x) |
603 | help | 617 | help |
604 | Enable UART1 | 618 | Enable UART1 |
605 | 619 | ||
@@ -612,18 +626,58 @@ config BFIN_UART1_CTSRTS | |||
612 | 626 | ||
613 | config UART1_CTS_PIN | 627 | config UART1_CTS_PIN |
614 | int "UART1 CTS pin" | 628 | int "UART1 CTS pin" |
615 | depends on BFIN_UART1_CTSRTS | 629 | depends on BFIN_UART1_CTSRTS && (BF53x || BF561) |
616 | default -1 | 630 | default -1 |
617 | help | 631 | help |
618 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | 632 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. |
619 | 633 | ||
620 | config UART1_RTS_PIN | 634 | config UART1_RTS_PIN |
621 | int "UART1 RTS pin" | 635 | int "UART1 RTS pin" |
622 | depends on BFIN_UART1_CTSRTS | 636 | depends on BFIN_UART1_CTSRTS && (BF53x || BF561) |
637 | default -1 | ||
638 | help | ||
639 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | ||
640 | |||
641 | config SERIAL_BFIN_UART2 | ||
642 | bool "Enable UART2" | ||
643 | depends on SERIAL_BFIN && (BF54x) | ||
644 | help | ||
645 | Enable UART2 | ||
646 | |||
647 | config BFIN_UART2_CTSRTS | ||
648 | bool "Enable UART2 hardware flow control" | ||
649 | depends on SERIAL_BFIN_UART2 | ||
650 | help | ||
651 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | ||
652 | signal. | ||
653 | |||
654 | config UART2_CTS_PIN | ||
655 | int "UART2 CTS pin" | ||
656 | depends on BFIN_UART2_CTSRTS | ||
657 | default -1 | ||
658 | help | ||
659 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | ||
660 | |||
661 | config UART2_RTS_PIN | ||
662 | int "UART2 RTS pin" | ||
663 | depends on BFIN_UART2_CTSRTS | ||
623 | default -1 | 664 | default -1 |
624 | help | 665 | help |
625 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. | 666 | Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. |
626 | 667 | ||
668 | config SERIAL_BFIN_UART3 | ||
669 | bool "Enable UART3" | ||
670 | depends on SERIAL_BFIN && (BF54x) | ||
671 | help | ||
672 | Enable UART3 | ||
673 | |||
674 | config BFIN_UART3_CTSRTS | ||
675 | bool "Enable UART3 hardware flow control" | ||
676 | depends on SERIAL_BFIN_UART3 | ||
677 | help | ||
678 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | ||
679 | signal. | ||
680 | |||
627 | config SERIAL_IMX | 681 | config SERIAL_IMX |
628 | bool "IMX serial port support" | 682 | bool "IMX serial port support" |
629 | depends on ARM && ARCH_IMX | 683 | depends on ARM && ARCH_IMX |
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 3320bcd92c0a..4d6b3c56d20e 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -114,6 +114,7 @@ struct atmel_uart_port { | |||
114 | struct uart_port uart; /* uart */ | 114 | struct uart_port uart; /* uart */ |
115 | struct clk *clk; /* uart clock */ | 115 | struct clk *clk; /* uart clock */ |
116 | unsigned short suspended; /* is port suspended? */ | 116 | unsigned short suspended; /* is port suspended? */ |
117 | int break_active; /* break being received */ | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; | 120 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; |
@@ -252,6 +253,7 @@ static void atmel_break_ctl(struct uart_port *port, int break_state) | |||
252 | */ | 253 | */ |
253 | static void atmel_rx_chars(struct uart_port *port) | 254 | static void atmel_rx_chars(struct uart_port *port) |
254 | { | 255 | { |
256 | struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; | ||
255 | struct tty_struct *tty = port->info->tty; | 257 | struct tty_struct *tty = port->info->tty; |
256 | unsigned int status, ch, flg; | 258 | unsigned int status, ch, flg; |
257 | 259 | ||
@@ -267,13 +269,29 @@ static void atmel_rx_chars(struct uart_port *port) | |||
267 | * note that the error handling code is | 269 | * note that the error handling code is |
268 | * out of the main execution path | 270 | * out of the main execution path |
269 | */ | 271 | */ |
270 | if (unlikely(status & (ATMEL_US_PARE | ATMEL_US_FRAME | ATMEL_US_OVRE | ATMEL_US_RXBRK))) { | 272 | if (unlikely(status & (ATMEL_US_PARE | ATMEL_US_FRAME |
273 | | ATMEL_US_OVRE | ATMEL_US_RXBRK) | ||
274 | || atmel_port->break_active)) { | ||
271 | UART_PUT_CR(port, ATMEL_US_RSTSTA); /* clear error */ | 275 | UART_PUT_CR(port, ATMEL_US_RSTSTA); /* clear error */ |
272 | if (status & ATMEL_US_RXBRK) { | 276 | if (status & ATMEL_US_RXBRK |
277 | && !atmel_port->break_active) { | ||
273 | status &= ~(ATMEL_US_PARE | ATMEL_US_FRAME); /* ignore side-effect */ | 278 | status &= ~(ATMEL_US_PARE | ATMEL_US_FRAME); /* ignore side-effect */ |
274 | port->icount.brk++; | 279 | port->icount.brk++; |
280 | atmel_port->break_active = 1; | ||
281 | UART_PUT_IER(port, ATMEL_US_RXBRK); | ||
275 | if (uart_handle_break(port)) | 282 | if (uart_handle_break(port)) |
276 | goto ignore_char; | 283 | goto ignore_char; |
284 | } else { | ||
285 | /* | ||
286 | * This is either the end-of-break | ||
287 | * condition or we've received at | ||
288 | * least one character without RXBRK | ||
289 | * being set. In both cases, the next | ||
290 | * RXBRK will indicate start-of-break. | ||
291 | */ | ||
292 | UART_PUT_IDR(port, ATMEL_US_RXBRK); | ||
293 | status &= ~ATMEL_US_RXBRK; | ||
294 | atmel_port->break_active = 0; | ||
277 | } | 295 | } |
278 | if (status & ATMEL_US_PARE) | 296 | if (status & ATMEL_US_PARE) |
279 | port->icount.parity++; | 297 | port->icount.parity++; |
@@ -352,6 +370,16 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) | |||
352 | /* Interrupt receive */ | 370 | /* Interrupt receive */ |
353 | if (pending & ATMEL_US_RXRDY) | 371 | if (pending & ATMEL_US_RXRDY) |
354 | atmel_rx_chars(port); | 372 | atmel_rx_chars(port); |
373 | else if (pending & ATMEL_US_RXBRK) { | ||
374 | /* | ||
375 | * End of break detected. If it came along | ||
376 | * with a character, atmel_rx_chars will | ||
377 | * handle it. | ||
378 | */ | ||
379 | UART_PUT_CR(port, ATMEL_US_RSTSTA); | ||
380 | UART_PUT_IDR(port, ATMEL_US_RXBRK); | ||
381 | atmel_port->break_active = 0; | ||
382 | } | ||
355 | 383 | ||
356 | // TODO: All reads to CSR will clear these interrupts! | 384 | // TODO: All reads to CSR will clear these interrupts! |
357 | if (pending & ATMEL_US_RIIC) port->icount.rng++; | 385 | if (pending & ATMEL_US_RIIC) port->icount.rng++; |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 787dc7168f3e..66c92bc36f3d 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -41,6 +41,11 @@ | |||
41 | #include <linux/tty_flip.h> | 41 | #include <linux/tty_flip.h> |
42 | #include <linux/serial_core.h> | 42 | #include <linux/serial_core.h> |
43 | 43 | ||
44 | #ifdef CONFIG_KGDB_UART | ||
45 | #include <linux/kgdb.h> | ||
46 | #include <asm/irq_regs.h> | ||
47 | #endif | ||
48 | |||
44 | #include <asm/gpio.h> | 49 | #include <asm/gpio.h> |
45 | #include <asm/mach/bfin_serial_5xx.h> | 50 | #include <asm/mach/bfin_serial_5xx.h> |
46 | 51 | ||
@@ -81,15 +86,29 @@ static void bfin_serial_stop_tx(struct uart_port *port) | |||
81 | { | 86 | { |
82 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 87 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
83 | 88 | ||
89 | #ifdef CONFIG_BF54x | ||
90 | while (!(UART_GET_LSR(uart) & TEMT)) | ||
91 | continue; | ||
92 | #endif | ||
93 | |||
84 | #ifdef CONFIG_SERIAL_BFIN_DMA | 94 | #ifdef CONFIG_SERIAL_BFIN_DMA |
85 | disable_dma(uart->tx_dma_channel); | 95 | disable_dma(uart->tx_dma_channel); |
86 | #else | 96 | #else |
97 | #ifdef CONFIG_BF54x | ||
98 | /* Waiting for Transmission Finished */ | ||
99 | while (!(UART_GET_LSR(uart) & TFI)) | ||
100 | continue; | ||
101 | /* Clear TFI bit */ | ||
102 | UART_PUT_LSR(uart, TFI); | ||
103 | UART_CLEAR_IER(uart, ETBEI); | ||
104 | #else | ||
87 | unsigned short ier; | 105 | unsigned short ier; |
88 | 106 | ||
89 | ier = UART_GET_IER(uart); | 107 | ier = UART_GET_IER(uart); |
90 | ier &= ~ETBEI; | 108 | ier &= ~ETBEI; |
91 | UART_PUT_IER(uart, ier); | 109 | UART_PUT_IER(uart, ier); |
92 | #endif | 110 | #endif |
111 | #endif | ||
93 | } | 112 | } |
94 | 113 | ||
95 | /* | 114 | /* |
@@ -102,12 +121,16 @@ static void bfin_serial_start_tx(struct uart_port *port) | |||
102 | #ifdef CONFIG_SERIAL_BFIN_DMA | 121 | #ifdef CONFIG_SERIAL_BFIN_DMA |
103 | bfin_serial_dma_tx_chars(uart); | 122 | bfin_serial_dma_tx_chars(uart); |
104 | #else | 123 | #else |
124 | #ifdef CONFIG_BF54x | ||
125 | UART_SET_IER(uart, ETBEI); | ||
126 | #else | ||
105 | unsigned short ier; | 127 | unsigned short ier; |
106 | ier = UART_GET_IER(uart); | 128 | ier = UART_GET_IER(uart); |
107 | ier |= ETBEI; | 129 | ier |= ETBEI; |
108 | UART_PUT_IER(uart, ier); | 130 | UART_PUT_IER(uart, ier); |
109 | bfin_serial_tx_chars(uart); | 131 | bfin_serial_tx_chars(uart); |
110 | #endif | 132 | #endif |
133 | #endif | ||
111 | } | 134 | } |
112 | 135 | ||
113 | /* | 136 | /* |
@@ -116,11 +139,18 @@ static void bfin_serial_start_tx(struct uart_port *port) | |||
116 | static void bfin_serial_stop_rx(struct uart_port *port) | 139 | static void bfin_serial_stop_rx(struct uart_port *port) |
117 | { | 140 | { |
118 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 141 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
142 | #ifdef CONFIG_BF54x | ||
143 | UART_CLEAR_IER(uart, ERBFI); | ||
144 | #else | ||
119 | unsigned short ier; | 145 | unsigned short ier; |
120 | 146 | ||
121 | ier = UART_GET_IER(uart); | 147 | ier = UART_GET_IER(uart); |
148 | #ifdef CONFIG_KGDB_UART | ||
149 | if (uart->port.line != CONFIG_KGDB_UART_PORT) | ||
150 | #endif | ||
122 | ier &= ~ERBFI; | 151 | ier &= ~ERBFI; |
123 | UART_PUT_IER(uart, ier); | 152 | UART_PUT_IER(uart, ier); |
153 | #endif | ||
124 | } | 154 | } |
125 | 155 | ||
126 | /* | 156 | /* |
@@ -130,6 +160,49 @@ static void bfin_serial_enable_ms(struct uart_port *port) | |||
130 | { | 160 | { |
131 | } | 161 | } |
132 | 162 | ||
163 | #ifdef CONFIG_KGDB_UART | ||
164 | static int kgdb_entry_state; | ||
165 | |||
166 | void kgdb_put_debug_char(int chr) | ||
167 | { | ||
168 | struct bfin_serial_port *uart; | ||
169 | |||
170 | if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS) | ||
171 | uart = &bfin_serial_ports[0]; | ||
172 | else | ||
173 | uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; | ||
174 | |||
175 | while (!(UART_GET_LSR(uart) & THRE)) { | ||
176 | __builtin_bfin_ssync(); | ||
177 | } | ||
178 | UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB)); | ||
179 | __builtin_bfin_ssync(); | ||
180 | UART_PUT_CHAR(uart, (unsigned char)chr); | ||
181 | __builtin_bfin_ssync(); | ||
182 | } | ||
183 | |||
184 | int kgdb_get_debug_char(void) | ||
185 | { | ||
186 | struct bfin_serial_port *uart; | ||
187 | unsigned char chr; | ||
188 | |||
189 | if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS) | ||
190 | uart = &bfin_serial_ports[0]; | ||
191 | else | ||
192 | uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; | ||
193 | |||
194 | while(!(UART_GET_LSR(uart) & DR)) { | ||
195 | __builtin_bfin_ssync(); | ||
196 | } | ||
197 | UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB)); | ||
198 | __builtin_bfin_ssync(); | ||
199 | chr = UART_GET_CHAR(uart); | ||
200 | __builtin_bfin_ssync(); | ||
201 | |||
202 | return chr; | ||
203 | } | ||
204 | #endif | ||
205 | |||
133 | #ifdef CONFIG_SERIAL_BFIN_PIO | 206 | #ifdef CONFIG_SERIAL_BFIN_PIO |
134 | static void local_put_char(struct bfin_serial_port *uart, char ch) | 207 | static void local_put_char(struct bfin_serial_port *uart, char ch) |
135 | { | 208 | { |
@@ -152,6 +225,9 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
152 | { | 225 | { |
153 | struct tty_struct *tty = uart->port.info->tty; | 226 | struct tty_struct *tty = uart->port.info->tty; |
154 | unsigned int status, ch, flg; | 227 | unsigned int status, ch, flg; |
228 | #ifdef CONFIG_KGDB_UART | ||
229 | struct pt_regs *regs = get_irq_regs(); | ||
230 | #endif | ||
155 | #ifdef BF533_FAMILY | 231 | #ifdef BF533_FAMILY |
156 | static int in_break = 0; | 232 | static int in_break = 0; |
157 | #endif | 233 | #endif |
@@ -160,6 +236,27 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
160 | ch = UART_GET_CHAR(uart); | 236 | ch = UART_GET_CHAR(uart); |
161 | uart->port.icount.rx++; | 237 | uart->port.icount.rx++; |
162 | 238 | ||
239 | #ifdef CONFIG_KGDB_UART | ||
240 | if (uart->port.line == CONFIG_KGDB_UART_PORT) { | ||
241 | if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */ | ||
242 | kgdb_breakkey_pressed(regs); | ||
243 | return; | ||
244 | } else if (kgdb_entry_state == 0 && ch == '$') {/* connection from KGDB */ | ||
245 | kgdb_entry_state = 1; | ||
246 | } else if (kgdb_entry_state == 1 && ch == 'q') { | ||
247 | kgdb_entry_state = 0; | ||
248 | kgdb_breakkey_pressed(regs); | ||
249 | return; | ||
250 | } else if (ch == 0x3) {/* Ctrl + C */ | ||
251 | kgdb_entry_state = 0; | ||
252 | kgdb_breakkey_pressed(regs); | ||
253 | return; | ||
254 | } else { | ||
255 | kgdb_entry_state = 0; | ||
256 | } | ||
257 | } | ||
258 | #endif | ||
259 | |||
163 | #ifdef BF533_FAMILY | 260 | #ifdef BF533_FAMILY |
164 | /* The BF533 family of processors have a nice misbehavior where | 261 | /* The BF533 family of processors have a nice misbehavior where |
165 | * they continuously generate characters for a "single" break. | 262 | * they continuously generate characters for a "single" break. |
@@ -185,6 +282,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
185 | uart->port.icount.brk++; | 282 | uart->port.icount.brk++; |
186 | if (uart_handle_break(&uart->port)) | 283 | if (uart_handle_break(&uart->port)) |
187 | goto ignore_char; | 284 | goto ignore_char; |
285 | status &= ~(PE | FE); | ||
188 | } | 286 | } |
189 | if (status & PE) | 287 | if (status & PE) |
190 | uart->port.icount.parity++; | 288 | uart->port.icount.parity++; |
@@ -249,10 +347,21 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) | |||
249 | { | 347 | { |
250 | struct bfin_serial_port *uart = dev_id; | 348 | struct bfin_serial_port *uart = dev_id; |
251 | 349 | ||
350 | #ifdef CONFIG_BF54x | ||
351 | unsigned short status; | ||
352 | spin_lock(&uart->port.lock); | ||
353 | status = UART_GET_LSR(uart); | ||
354 | while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) { | ||
355 | bfin_serial_rx_chars(uart); | ||
356 | status = UART_GET_LSR(uart); | ||
357 | } | ||
358 | spin_unlock(&uart->port.lock); | ||
359 | #else | ||
252 | spin_lock(&uart->port.lock); | 360 | spin_lock(&uart->port.lock); |
253 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) | 361 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) |
254 | bfin_serial_rx_chars(uart); | 362 | bfin_serial_rx_chars(uart); |
255 | spin_unlock(&uart->port.lock); | 363 | spin_unlock(&uart->port.lock); |
364 | #endif | ||
256 | return IRQ_HANDLED; | 365 | return IRQ_HANDLED; |
257 | } | 366 | } |
258 | 367 | ||
@@ -260,10 +369,21 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) | |||
260 | { | 369 | { |
261 | struct bfin_serial_port *uart = dev_id; | 370 | struct bfin_serial_port *uart = dev_id; |
262 | 371 | ||
372 | #ifdef CONFIG_BF54x | ||
373 | unsigned short status; | ||
374 | spin_lock(&uart->port.lock); | ||
375 | status = UART_GET_LSR(uart); | ||
376 | while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) { | ||
377 | bfin_serial_tx_chars(uart); | ||
378 | status = UART_GET_LSR(uart); | ||
379 | } | ||
380 | spin_unlock(&uart->port.lock); | ||
381 | #else | ||
263 | spin_lock(&uart->port.lock); | 382 | spin_lock(&uart->port.lock); |
264 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) | 383 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) |
265 | bfin_serial_tx_chars(uart); | 384 | bfin_serial_tx_chars(uart); |
266 | spin_unlock(&uart->port.lock); | 385 | spin_unlock(&uart->port.lock); |
386 | #endif | ||
267 | return IRQ_HANDLED; | 387 | return IRQ_HANDLED; |
268 | } | 388 | } |
269 | 389 | ||
@@ -274,7 +394,6 @@ static void bfin_serial_do_work(struct work_struct *work) | |||
274 | 394 | ||
275 | bfin_serial_mctrl_check(uart); | 395 | bfin_serial_mctrl_check(uart); |
276 | } | 396 | } |
277 | |||
278 | #endif | 397 | #endif |
279 | 398 | ||
280 | #ifdef CONFIG_SERIAL_BFIN_DMA | 399 | #ifdef CONFIG_SERIAL_BFIN_DMA |
@@ -323,9 +442,13 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
323 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); | 442 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); |
324 | set_dma_x_modify(uart->tx_dma_channel, 1); | 443 | set_dma_x_modify(uart->tx_dma_channel, 1); |
325 | enable_dma(uart->tx_dma_channel); | 444 | enable_dma(uart->tx_dma_channel); |
445 | #ifdef CONFIG_BF54x | ||
446 | UART_SET_IER(uart, ETBEI); | ||
447 | #else | ||
326 | ier = UART_GET_IER(uart); | 448 | ier = UART_GET_IER(uart); |
327 | ier |= ETBEI; | 449 | ier |= ETBEI; |
328 | UART_PUT_IER(uart, ier); | 450 | UART_PUT_IER(uart, ier); |
451 | #endif | ||
329 | spin_unlock_irqrestore(&uart->port.lock, flags); | 452 | spin_unlock_irqrestore(&uart->port.lock, flags); |
330 | } | 453 | } |
331 | 454 | ||
@@ -341,6 +464,7 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | |||
341 | uart->port.icount.brk++; | 464 | uart->port.icount.brk++; |
342 | if (uart_handle_break(&uart->port)) | 465 | if (uart_handle_break(&uart->port)) |
343 | goto dma_ignore_char; | 466 | goto dma_ignore_char; |
467 | status &= ~(PE | FE); | ||
344 | } | 468 | } |
345 | if (status & PE) | 469 | if (status & PE) |
346 | uart->port.icount.parity++; | 470 | uart->port.icount.parity++; |
@@ -404,9 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) | |||
404 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { | 528 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { |
405 | clear_dma_irqstat(uart->tx_dma_channel); | 529 | clear_dma_irqstat(uart->tx_dma_channel); |
406 | disable_dma(uart->tx_dma_channel); | 530 | disable_dma(uart->tx_dma_channel); |
531 | #ifdef CONFIG_BF54x | ||
532 | UART_CLEAR_IER(uart, ETBEI); | ||
533 | #else | ||
407 | ier = UART_GET_IER(uart); | 534 | ier = UART_GET_IER(uart); |
408 | ier &= ~ETBEI; | 535 | ier &= ~ETBEI; |
409 | UART_PUT_IER(uart, ier); | 536 | UART_PUT_IER(uart, ier); |
537 | #endif | ||
410 | xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); | 538 | xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); |
411 | uart->port.icount.tx+=uart->tx_count; | 539 | uart->port.icount.tx+=uart->tx_count; |
412 | 540 | ||
@@ -517,6 +645,14 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) | |||
517 | */ | 645 | */ |
518 | static void bfin_serial_break_ctl(struct uart_port *port, int break_state) | 646 | static void bfin_serial_break_ctl(struct uart_port *port, int break_state) |
519 | { | 647 | { |
648 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
649 | u16 lcr = UART_GET_LCR(uart); | ||
650 | if (break_state) | ||
651 | lcr |= SB; | ||
652 | else | ||
653 | lcr &= ~SB; | ||
654 | UART_PUT_LCR(uart, lcr); | ||
655 | SSYNC(); | ||
520 | } | 656 | } |
521 | 657 | ||
522 | static int bfin_serial_startup(struct uart_port *port) | 658 | static int bfin_serial_startup(struct uart_port *port) |
@@ -561,7 +697,11 @@ static int bfin_serial_startup(struct uart_port *port) | |||
561 | uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; | 697 | uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; |
562 | add_timer(&(uart->rx_dma_timer)); | 698 | add_timer(&(uart->rx_dma_timer)); |
563 | #else | 699 | #else |
700 | # ifdef CONFIG_KGDB_UART | ||
701 | if (uart->port.line != CONFIG_KGDB_UART_PORT && request_irq | ||
702 | # else | ||
564 | if (request_irq | 703 | if (request_irq |
704 | # endif | ||
565 | (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, | 705 | (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, |
566 | "BFIN_UART_RX", uart)) { | 706 | "BFIN_UART_RX", uart)) { |
567 | printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); | 707 | printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); |
@@ -576,7 +716,11 @@ static int bfin_serial_startup(struct uart_port *port) | |||
576 | return -EBUSY; | 716 | return -EBUSY; |
577 | } | 717 | } |
578 | #endif | 718 | #endif |
719 | #ifdef CONFIG_BF54x | ||
720 | UART_SET_IER(uart, ERBFI); | ||
721 | #else | ||
579 | UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); | 722 | UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); |
723 | #endif | ||
580 | return 0; | 724 | return 0; |
581 | } | 725 | } |
582 | 726 | ||
@@ -591,6 +735,9 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
591 | free_dma(uart->rx_dma_channel); | 735 | free_dma(uart->rx_dma_channel); |
592 | del_timer(&(uart->rx_dma_timer)); | 736 | del_timer(&(uart->rx_dma_timer)); |
593 | #else | 737 | #else |
738 | #ifdef CONFIG_KGDB_UART | ||
739 | if (uart->port.line != CONFIG_KGDB_UART_PORT) | ||
740 | #endif | ||
594 | free_irq(uart->port.irq, uart); | 741 | free_irq(uart->port.irq, uart); |
595 | free_irq(uart->port.irq+1, uart); | 742 | free_irq(uart->port.irq+1, uart); |
596 | #endif | 743 | #endif |
@@ -625,11 +772,12 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
625 | 772 | ||
626 | if (termios->c_cflag & CSTOPB) | 773 | if (termios->c_cflag & CSTOPB) |
627 | lcr |= STB; | 774 | lcr |= STB; |
628 | if (termios->c_cflag & PARENB) { | 775 | if (termios->c_cflag & PARENB) |
629 | lcr |= PEN; | 776 | lcr |= PEN; |
630 | if (!(termios->c_cflag & PARODD)) | 777 | if (!(termios->c_cflag & PARODD)) |
631 | lcr |= EPS; | 778 | lcr |= EPS; |
632 | } | 779 | if (termios->c_cflag & CMSPAR) |
780 | lcr |= STP; | ||
633 | 781 | ||
634 | port->read_status_mask = OE; | 782 | port->read_status_mask = OE; |
635 | if (termios->c_iflag & INPCK) | 783 | if (termios->c_iflag & INPCK) |
@@ -663,29 +811,41 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
663 | 811 | ||
664 | /* Disable UART */ | 812 | /* Disable UART */ |
665 | ier = UART_GET_IER(uart); | 813 | ier = UART_GET_IER(uart); |
814 | #ifdef CONFIG_BF54x | ||
815 | UART_CLEAR_IER(uart, 0xF); | ||
816 | #else | ||
666 | UART_PUT_IER(uart, 0); | 817 | UART_PUT_IER(uart, 0); |
818 | #endif | ||
667 | 819 | ||
820 | #ifndef CONFIG_BF54x | ||
668 | /* Set DLAB in LCR to Access DLL and DLH */ | 821 | /* Set DLAB in LCR to Access DLL and DLH */ |
669 | val = UART_GET_LCR(uart); | 822 | val = UART_GET_LCR(uart); |
670 | val |= DLAB; | 823 | val |= DLAB; |
671 | UART_PUT_LCR(uart, val); | 824 | UART_PUT_LCR(uart, val); |
672 | SSYNC(); | 825 | SSYNC(); |
826 | #endif | ||
673 | 827 | ||
674 | UART_PUT_DLL(uart, quot & 0xFF); | 828 | UART_PUT_DLL(uart, quot & 0xFF); |
675 | SSYNC(); | 829 | SSYNC(); |
676 | UART_PUT_DLH(uart, (quot >> 8) & 0xFF); | 830 | UART_PUT_DLH(uart, (quot >> 8) & 0xFF); |
677 | SSYNC(); | 831 | SSYNC(); |
678 | 832 | ||
833 | #ifndef CONFIG_BF54x | ||
679 | /* Clear DLAB in LCR to Access THR RBR IER */ | 834 | /* Clear DLAB in LCR to Access THR RBR IER */ |
680 | val = UART_GET_LCR(uart); | 835 | val = UART_GET_LCR(uart); |
681 | val &= ~DLAB; | 836 | val &= ~DLAB; |
682 | UART_PUT_LCR(uart, val); | 837 | UART_PUT_LCR(uart, val); |
683 | SSYNC(); | 838 | SSYNC(); |
839 | #endif | ||
684 | 840 | ||
685 | UART_PUT_LCR(uart, lcr); | 841 | UART_PUT_LCR(uart, lcr); |
686 | 842 | ||
687 | /* Enable UART */ | 843 | /* Enable UART */ |
844 | #ifdef CONFIG_BF54x | ||
845 | UART_SET_IER(uart, ier); | ||
846 | #else | ||
688 | UART_PUT_IER(uart, ier); | 847 | UART_PUT_IER(uart, ier); |
848 | #endif | ||
689 | 849 | ||
690 | val = UART_GET_GCTL(uart); | 850 | val = UART_GET_GCTL(uart); |
691 | val |= UCEN; | 851 | val |= UCEN; |
@@ -797,15 +957,15 @@ static void __init bfin_serial_init_ports(void) | |||
797 | bfin_serial_resource[i].uart_rts_pin; | 957 | bfin_serial_resource[i].uart_rts_pin; |
798 | #endif | 958 | #endif |
799 | bfin_serial_hw_init(&bfin_serial_ports[i]); | 959 | bfin_serial_hw_init(&bfin_serial_ports[i]); |
800 | |||
801 | } | 960 | } |
961 | |||
802 | } | 962 | } |
803 | 963 | ||
804 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE | 964 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE |
805 | static void bfin_serial_console_putchar(struct uart_port *port, int ch) | 965 | static void bfin_serial_console_putchar(struct uart_port *port, int ch) |
806 | { | 966 | { |
807 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 967 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
808 | while (!(UART_GET_LSR(uart))) | 968 | while (!(UART_GET_LSR(uart) & THRE)) |
809 | barrier(); | 969 | barrier(); |
810 | UART_PUT_CHAR(uart, ch); | 970 | UART_PUT_CHAR(uart, ch); |
811 | SSYNC(); | 971 | SSYNC(); |
@@ -857,18 +1017,22 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, | |||
857 | case 2: *bits = 7; break; | 1017 | case 2: *bits = 7; break; |
858 | case 3: *bits = 8; break; | 1018 | case 3: *bits = 8; break; |
859 | } | 1019 | } |
1020 | #ifndef CONFIG_BF54x | ||
860 | /* Set DLAB in LCR to Access DLL and DLH */ | 1021 | /* Set DLAB in LCR to Access DLL and DLH */ |
861 | val = UART_GET_LCR(uart); | 1022 | val = UART_GET_LCR(uart); |
862 | val |= DLAB; | 1023 | val |= DLAB; |
863 | UART_PUT_LCR(uart, val); | 1024 | UART_PUT_LCR(uart, val); |
1025 | #endif | ||
864 | 1026 | ||
865 | dll = UART_GET_DLL(uart); | 1027 | dll = UART_GET_DLL(uart); |
866 | dlh = UART_GET_DLH(uart); | 1028 | dlh = UART_GET_DLH(uart); |
867 | 1029 | ||
1030 | #ifndef CONFIG_BF54x | ||
868 | /* Clear DLAB in LCR to Access THR RBR IER */ | 1031 | /* Clear DLAB in LCR to Access THR RBR IER */ |
869 | val = UART_GET_LCR(uart); | 1032 | val = UART_GET_LCR(uart); |
870 | val &= ~DLAB; | 1033 | val &= ~DLAB; |
871 | UART_PUT_LCR(uart, val); | 1034 | UART_PUT_LCR(uart, val); |
1035 | #endif | ||
872 | 1036 | ||
873 | *baud = get_sclk() / (16*(dll | dlh << 8)); | 1037 | *baud = get_sclk() / (16*(dll | dlh << 8)); |
874 | } | 1038 | } |
@@ -920,6 +1084,10 @@ static int __init bfin_serial_rs_console_init(void) | |||
920 | { | 1084 | { |
921 | bfin_serial_init_ports(); | 1085 | bfin_serial_init_ports(); |
922 | register_console(&bfin_serial_console); | 1086 | register_console(&bfin_serial_console); |
1087 | #ifdef CONFIG_KGDB_UART | ||
1088 | kgdb_entry_state = 0; | ||
1089 | init_kgdb_uart(); | ||
1090 | #endif | ||
923 | return 0; | 1091 | return 0; |
924 | } | 1092 | } |
925 | console_initcall(bfin_serial_rs_console_init); | 1093 | console_initcall(bfin_serial_rs_console_init); |
@@ -1012,6 +1180,10 @@ static struct platform_driver bfin_serial_driver = { | |||
1012 | static int __init bfin_serial_init(void) | 1180 | static int __init bfin_serial_init(void) |
1013 | { | 1181 | { |
1014 | int ret; | 1182 | int ret; |
1183 | #ifdef CONFIG_KGDB_UART | ||
1184 | struct bfin_serial_port *uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; | ||
1185 | struct termios t; | ||
1186 | #endif | ||
1015 | 1187 | ||
1016 | pr_info("Serial: Blackfin serial driver\n"); | 1188 | pr_info("Serial: Blackfin serial driver\n"); |
1017 | 1189 | ||
@@ -1025,6 +1197,21 @@ static int __init bfin_serial_init(void) | |||
1025 | uart_unregister_driver(&bfin_serial_reg); | 1197 | uart_unregister_driver(&bfin_serial_reg); |
1026 | } | 1198 | } |
1027 | } | 1199 | } |
1200 | #ifdef CONFIG_KGDB_UART | ||
1201 | if (uart->port.cons->index != CONFIG_KGDB_UART_PORT) { | ||
1202 | request_irq(uart->port.irq, bfin_serial_int, | ||
1203 | IRQF_DISABLED, "BFIN_UART_RX", uart); | ||
1204 | pr_info("Request irq for kgdb uart port\n"); | ||
1205 | UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); | ||
1206 | __builtin_bfin_ssync(); | ||
1207 | t.c_cflag = CS8|B57600; | ||
1208 | t.c_iflag = 0; | ||
1209 | t.c_oflag = 0; | ||
1210 | t.c_lflag = ICANON; | ||
1211 | t.c_line = CONFIG_KGDB_UART_PORT; | ||
1212 | bfin_serial_set_termios(&uart->port, &t, &t); | ||
1213 | } | ||
1214 | #endif | ||
1028 | return ret; | 1215 | return ret; |
1029 | } | 1216 | } |
1030 | 1217 | ||
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index c3abfb39f316..f3257f708ef9 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -862,6 +862,7 @@ ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios, | |||
862 | up->cflag = termios->c_cflag; | 862 | up->cflag = termios->c_cflag; |
863 | 863 | ||
864 | ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port)); | 864 | ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port)); |
865 | uart_update_timeout(port, termios->c_cflag, baud); | ||
865 | 866 | ||
866 | spin_unlock_irqrestore(&up->port.lock, flags); | 867 | spin_unlock_irqrestore(&up->port.lock, flags); |
867 | } | 868 | } |
@@ -1017,6 +1018,8 @@ ip22serial_console_termios(struct console *con, char *options) | |||
1017 | } | 1018 | } |
1018 | 1019 | ||
1019 | con->cflag = cflag | CS8; /* 8N1 */ | 1020 | con->cflag = cflag | CS8; /* 8N1 */ |
1021 | |||
1022 | uart_update_timeout(&ip22zilog_port_table[con->index].port, cflag, baud); | ||
1020 | } | 1023 | } |
1021 | 1024 | ||
1022 | static int __init ip22zilog_console_setup(struct console *con, char *options) | 1025 | static int __init ip22zilog_console_setup(struct console *con, char *options) |
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index 81792e6eeb2d..6767ee381cd1 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c | |||
@@ -88,7 +88,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
88 | spin_lock_init(&brd->bd_intr_lock); | 88 | spin_lock_init(&brd->bd_intr_lock); |
89 | 89 | ||
90 | /* store which revision we have */ | 90 | /* store which revision we have */ |
91 | pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev); | 91 | brd->rev = pdev->revision; |
92 | 92 | ||
93 | brd->irq = pdev->irq; | 93 | brd->irq = pdev->irq; |
94 | 94 | ||
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index d09f2097d5b0..00924feaf621 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -503,7 +503,8 @@ mpsc_sdma_intr_ack(struct mpsc_port_info *pi) | |||
503 | 503 | ||
504 | if (pi->mirror_regs) | 504 | if (pi->mirror_regs) |
505 | pi->shared_regs->SDMA_INTR_CAUSE_m = 0; | 505 | pi->shared_regs->SDMA_INTR_CAUSE_m = 0; |
506 | writel(0, pi->shared_regs->sdma_intr_base + SDMA_INTR_CAUSE); | 506 | writeb(0x00, pi->shared_regs->sdma_intr_base + SDMA_INTR_CAUSE + |
507 | pi->port.line); | ||
507 | return; | 508 | return; |
508 | } | 509 | } |
509 | 510 | ||
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 326020f86f75..9c57486c2e7f 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -1910,6 +1910,12 @@ uart_set_options(struct uart_port *port, struct console *co, | |||
1910 | if (flow == 'r') | 1910 | if (flow == 'r') |
1911 | termios.c_cflag |= CRTSCTS; | 1911 | termios.c_cflag |= CRTSCTS; |
1912 | 1912 | ||
1913 | /* | ||
1914 | * some uarts on other side don't support no flow control. | ||
1915 | * So we set * DTR in host uart to make them happy | ||
1916 | */ | ||
1917 | port->mctrl |= TIOCM_DTR; | ||
1918 | |||
1913 | port->ops->set_termios(port, &termios, NULL); | 1919 | port->ops->set_termios(port, &termios, NULL); |
1914 | co->cflag = termios.c_cflag; | 1920 | co->cflag = termios.c_cflag; |
1915 | 1921 | ||
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 6b76babc7fbf..a0ea43598515 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -842,12 +842,16 @@ static struct pcmcia_device_id serial_ids[] = { | |||
842 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), | 842 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), |
843 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), | 843 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), |
844 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), | 844 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), |
845 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555), | ||
846 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064), | ||
845 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), | 847 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), |
846 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), | 848 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), |
847 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), | 849 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), |
848 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), | 850 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), |
849 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), | 851 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), |
850 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), | 852 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), |
853 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), | ||
854 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), | ||
851 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), | 855 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), |
852 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), | 856 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), |
853 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), | 857 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index a27e9e92cb5e..41fc61264443 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -759,7 +759,7 @@ static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port) | |||
759 | */ | 759 | */ |
760 | 760 | ||
761 | static void sn_sal_console_write(struct console *, const char *, unsigned); | 761 | static void sn_sal_console_write(struct console *, const char *, unsigned); |
762 | static int __init sn_sal_console_setup(struct console *, char *); | 762 | static int sn_sal_console_setup(struct console *, char *); |
763 | static struct uart_driver sal_console_uart; | 763 | static struct uart_driver sal_console_uart; |
764 | extern struct tty_driver *uart_console_device(struct console *, int *); | 764 | extern struct tty_driver *uart_console_device(struct console *, int *); |
765 | 765 | ||
@@ -1006,7 +1006,7 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count) | |||
1006 | * here so providing it is easier. | 1006 | * here so providing it is easier. |
1007 | * | 1007 | * |
1008 | */ | 1008 | */ |
1009 | static int __init sn_sal_console_setup(struct console *co, char *options) | 1009 | static int sn_sal_console_setup(struct console *co, char *options) |
1010 | { | 1010 | { |
1011 | return 0; | 1011 | return 0; |
1012 | } | 1012 | } |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index cf0e663b42ed..85309acb75f6 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for NEC VR4100 series Serial Interface Unit. | 2 | * Driver for NEC VR4100 series Serial Interface Unit. |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2004-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> |
5 | * | 5 | * |
6 | * Based on drivers/serial/8250.c, by Russell King. | 6 | * Based on drivers/serial/8250.c, by Russell King. |
7 | * | 7 | * |
@@ -25,12 +25,12 @@ | |||
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #include <linux/console.h> | 27 | #include <linux/console.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/err.h> | ||
30 | #include <linux/ioport.h> | ||
31 | #include <linux/init.h> | 29 | #include <linux/init.h> |
32 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/ioport.h> | ||
33 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/serial.h> | 34 | #include <linux/serial.h> |
35 | #include <linux/serial_core.h> | 35 | #include <linux/serial_core.h> |
36 | #include <linux/serial_reg.h> | 36 | #include <linux/serial_reg.h> |
@@ -38,11 +38,9 @@ | |||
38 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
39 | 39 | ||
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | #include <asm/vr41xx/irq.h> | ||
42 | #include <asm/vr41xx/siu.h> | 41 | #include <asm/vr41xx/siu.h> |
43 | #include <asm/vr41xx/vr41xx.h> | 42 | #include <asm/vr41xx/vr41xx.h> |
44 | 43 | ||
45 | #define SIU_PORTS_MAX 2 | ||
46 | #define SIU_BAUD_BASE 1152000 | 44 | #define SIU_BAUD_BASE 1152000 |
47 | #define SIU_MAJOR 204 | 45 | #define SIU_MAJOR 204 |
48 | #define SIU_MINOR_BASE 82 | 46 | #define SIU_MINOR_BASE 82 |
@@ -60,32 +58,13 @@ | |||
60 | #define IRUSESEL 0x02 | 58 | #define IRUSESEL 0x02 |
61 | #define SIRSEL 0x01 | 59 | #define SIRSEL 0x01 |
62 | 60 | ||
63 | struct siu_port { | 61 | static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { |
64 | unsigned int type; | 62 | [0 ... SIU_PORTS_MAX-1] = { |
65 | unsigned int irq; | 63 | .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), |
66 | unsigned long start; | 64 | .irq = -1, |
67 | }; | 65 | }, |
68 | |||
69 | static const struct siu_port siu_type1_ports[] = { | ||
70 | { .type = PORT_VR41XX_SIU, | ||
71 | .irq = SIU_IRQ, | ||
72 | .start = 0x0c000000UL, }, | ||
73 | }; | ||
74 | |||
75 | #define SIU_TYPE1_NR_PORTS (sizeof(siu_type1_ports) / sizeof(struct siu_port)) | ||
76 | |||
77 | static const struct siu_port siu_type2_ports[] = { | ||
78 | { .type = PORT_VR41XX_SIU, | ||
79 | .irq = SIU_IRQ, | ||
80 | .start = 0x0f000800UL, }, | ||
81 | { .type = PORT_VR41XX_DSIU, | ||
82 | .irq = DSIU_IRQ, | ||
83 | .start = 0x0f000820UL, }, | ||
84 | }; | 66 | }; |
85 | 67 | ||
86 | #define SIU_TYPE2_NR_PORTS (sizeof(siu_type2_ports) / sizeof(struct siu_port)) | ||
87 | |||
88 | static struct uart_port siu_uart_ports[SIU_PORTS_MAX]; | ||
89 | static uint8_t lsr_break_flag[SIU_PORTS_MAX]; | 68 | static uint8_t lsr_break_flag[SIU_PORTS_MAX]; |
90 | 69 | ||
91 | #define siu_read(port, offset) readb((port)->membase + (offset)) | 70 | #define siu_read(port, offset) readb((port)->membase + (offset)) |
@@ -110,7 +89,6 @@ void vr41xx_select_siu_interface(siu_interface_t interface) | |||
110 | 89 | ||
111 | spin_unlock_irqrestore(&port->lock, flags); | 90 | spin_unlock_irqrestore(&port->lock, flags); |
112 | } | 91 | } |
113 | |||
114 | EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface); | 92 | EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface); |
115 | 93 | ||
116 | void vr41xx_use_irda(irda_use_t use) | 94 | void vr41xx_use_irda(irda_use_t use) |
@@ -132,7 +110,6 @@ void vr41xx_use_irda(irda_use_t use) | |||
132 | 110 | ||
133 | spin_unlock_irqrestore(&port->lock, flags); | 111 | spin_unlock_irqrestore(&port->lock, flags); |
134 | } | 112 | } |
135 | |||
136 | EXPORT_SYMBOL_GPL(vr41xx_use_irda); | 113 | EXPORT_SYMBOL_GPL(vr41xx_use_irda); |
137 | 114 | ||
138 | void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) | 115 | void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) |
@@ -166,7 +143,6 @@ void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed) | |||
166 | 143 | ||
167 | spin_unlock_irqrestore(&port->lock, flags); | 144 | spin_unlock_irqrestore(&port->lock, flags); |
168 | } | 145 | } |
169 | |||
170 | EXPORT_SYMBOL_GPL(vr41xx_select_irda_module); | 146 | EXPORT_SYMBOL_GPL(vr41xx_select_irda_module); |
171 | 147 | ||
172 | static inline void siu_clear_fifo(struct uart_port *port) | 148 | static inline void siu_clear_fifo(struct uart_port *port) |
@@ -177,21 +153,6 @@ static inline void siu_clear_fifo(struct uart_port *port) | |||
177 | siu_write(port, UART_FCR, 0); | 153 | siu_write(port, UART_FCR, 0); |
178 | } | 154 | } |
179 | 155 | ||
180 | static inline int siu_probe_ports(void) | ||
181 | { | ||
182 | switch (current_cpu_data.cputype) { | ||
183 | case CPU_VR4111: | ||
184 | case CPU_VR4121: | ||
185 | return SIU_TYPE1_NR_PORTS; | ||
186 | case CPU_VR4122: | ||
187 | case CPU_VR4131: | ||
188 | case CPU_VR4133: | ||
189 | return SIU_TYPE2_NR_PORTS; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static inline unsigned long siu_port_size(struct uart_port *port) | 156 | static inline unsigned long siu_port_size(struct uart_port *port) |
196 | { | 157 | { |
197 | switch (port->type) { | 158 | switch (port->type) { |
@@ -206,21 +167,10 @@ static inline unsigned long siu_port_size(struct uart_port *port) | |||
206 | 167 | ||
207 | static inline unsigned int siu_check_type(struct uart_port *port) | 168 | static inline unsigned int siu_check_type(struct uart_port *port) |
208 | { | 169 | { |
209 | switch (current_cpu_data.cputype) { | 170 | if (port->line == 0) |
210 | case CPU_VR4111: | 171 | return PORT_VR41XX_SIU; |
211 | case CPU_VR4121: | 172 | if (port->line == 1 && port->irq != -1) |
212 | if (port->line == 0) | 173 | return PORT_VR41XX_DSIU; |
213 | return PORT_VR41XX_SIU; | ||
214 | break; | ||
215 | case CPU_VR4122: | ||
216 | case CPU_VR4131: | ||
217 | case CPU_VR4133: | ||
218 | if (port->line == 0) | ||
219 | return PORT_VR41XX_SIU; | ||
220 | else if (port->line == 1) | ||
221 | return PORT_VR41XX_DSIU; | ||
222 | break; | ||
223 | } | ||
224 | 174 | ||
225 | return PORT_UNKNOWN; | 175 | return PORT_UNKNOWN; |
226 | } | 176 | } |
@@ -751,44 +701,34 @@ static struct uart_ops siu_uart_ops = { | |||
751 | .verify_port = siu_verify_port, | 701 | .verify_port = siu_verify_port, |
752 | }; | 702 | }; |
753 | 703 | ||
754 | static int siu_init_ports(void) | 704 | static int siu_init_ports(struct platform_device *pdev) |
755 | { | 705 | { |
756 | const struct siu_port *siu; | ||
757 | struct uart_port *port; | 706 | struct uart_port *port; |
758 | int i, num; | 707 | struct resource *res; |
708 | int *type = pdev->dev.platform_data; | ||
709 | int i; | ||
759 | 710 | ||
760 | switch (current_cpu_data.cputype) { | 711 | if (!type) |
761 | case CPU_VR4111: | ||
762 | case CPU_VR4121: | ||
763 | siu = siu_type1_ports; | ||
764 | break; | ||
765 | case CPU_VR4122: | ||
766 | case CPU_VR4131: | ||
767 | case CPU_VR4133: | ||
768 | siu = siu_type2_ports; | ||
769 | break; | ||
770 | default: | ||
771 | return 0; | 712 | return 0; |
772 | } | ||
773 | 713 | ||
774 | port = siu_uart_ports; | 714 | port = siu_uart_ports; |
775 | num = siu_probe_ports(); | 715 | for (i = 0; i < SIU_PORTS_MAX; i++) { |
776 | for (i = 0; i < num; i++) { | 716 | port->type = type[i]; |
777 | spin_lock_init(&port->lock); | 717 | if (port->type == PORT_UNKNOWN) |
778 | port->irq = siu->irq; | 718 | continue; |
719 | port->irq = platform_get_irq(pdev, i); | ||
779 | port->uartclk = SIU_BAUD_BASE * 16; | 720 | port->uartclk = SIU_BAUD_BASE * 16; |
780 | port->fifosize = 16; | 721 | port->fifosize = 16; |
781 | port->regshift = 0; | 722 | port->regshift = 0; |
782 | port->iotype = UPIO_MEM; | 723 | port->iotype = UPIO_MEM; |
783 | port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; | 724 | port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; |
784 | port->type = siu->type; | ||
785 | port->line = i; | 725 | port->line = i; |
786 | port->mapbase = siu->start; | 726 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); |
787 | siu++; | 727 | port->mapbase = res->start; |
788 | port++; | 728 | port++; |
789 | } | 729 | } |
790 | 730 | ||
791 | return num; | 731 | return i; |
792 | } | 732 | } |
793 | 733 | ||
794 | #ifdef CONFIG_SERIAL_VR41XX_CONSOLE | 734 | #ifdef CONFIG_SERIAL_VR41XX_CONSOLE |
@@ -883,13 +823,9 @@ static struct console siu_console = { | |||
883 | static int __devinit siu_console_init(void) | 823 | static int __devinit siu_console_init(void) |
884 | { | 824 | { |
885 | struct uart_port *port; | 825 | struct uart_port *port; |
886 | int num, i; | 826 | int i; |
887 | |||
888 | num = siu_init_ports(); | ||
889 | if (num <= 0) | ||
890 | return -ENODEV; | ||
891 | 827 | ||
892 | for (i = 0; i < num; i++) { | 828 | for (i = 0; i < SIU_PORTS_MAX; i++) { |
893 | port = &siu_uart_ports[i]; | 829 | port = &siu_uart_ports[i]; |
894 | port->ops = &siu_uart_ops; | 830 | port->ops = &siu_uart_ops; |
895 | } | 831 | } |
@@ -920,7 +856,7 @@ static int __devinit siu_probe(struct platform_device *dev) | |||
920 | struct uart_port *port; | 856 | struct uart_port *port; |
921 | int num, i, retval; | 857 | int num, i, retval; |
922 | 858 | ||
923 | num = siu_init_ports(); | 859 | num = siu_init_ports(dev); |
924 | if (num <= 0) | 860 | if (num <= 0) |
925 | return -ENODEV; | 861 | return -ENODEV; |
926 | 862 | ||
@@ -998,8 +934,6 @@ static int siu_resume(struct platform_device *dev) | |||
998 | return 0; | 934 | return 0; |
999 | } | 935 | } |
1000 | 936 | ||
1001 | static struct platform_device *siu_platform_device; | ||
1002 | |||
1003 | static struct platform_driver siu_device_driver = { | 937 | static struct platform_driver siu_device_driver = { |
1004 | .probe = siu_probe, | 938 | .probe = siu_probe, |
1005 | .remove = __devexit_p(siu_remove), | 939 | .remove = __devexit_p(siu_remove), |
@@ -1013,29 +947,12 @@ static struct platform_driver siu_device_driver = { | |||
1013 | 947 | ||
1014 | static int __init vr41xx_siu_init(void) | 948 | static int __init vr41xx_siu_init(void) |
1015 | { | 949 | { |
1016 | int retval; | 950 | return platform_driver_register(&siu_device_driver); |
1017 | |||
1018 | siu_platform_device = platform_device_alloc("SIU", -1); | ||
1019 | if (!siu_platform_device) | ||
1020 | return -ENOMEM; | ||
1021 | |||
1022 | retval = platform_device_add(siu_platform_device); | ||
1023 | if (retval < 0) { | ||
1024 | platform_device_put(siu_platform_device); | ||
1025 | return retval; | ||
1026 | } | ||
1027 | |||
1028 | retval = platform_driver_register(&siu_device_driver); | ||
1029 | if (retval < 0) | ||
1030 | platform_device_unregister(siu_platform_device); | ||
1031 | |||
1032 | return retval; | ||
1033 | } | 951 | } |
1034 | 952 | ||
1035 | static void __exit vr41xx_siu_exit(void) | 953 | static void __exit vr41xx_siu_exit(void) |
1036 | { | 954 | { |
1037 | platform_driver_unregister(&siu_device_driver); | 955 | platform_driver_unregister(&siu_device_driver); |
1038 | platform_device_unregister(siu_platform_device); | ||
1039 | } | 956 | } |
1040 | 957 | ||
1041 | module_init(vr41xx_siu_init); | 958 | module_init(vr41xx_siu_init); |