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 | 182 | ||||
-rw-r--r-- | drivers/serial/ip22zilog.c | 3 | ||||
-rw-r--r-- | drivers/serial/jsm/jsm_driver.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 6 | ||||
-rw-r--r-- | drivers/serial/sh-sci.c | 4 | ||||
-rw-r--r-- | drivers/serial/sh-sci.h | 50 | ||||
-rw-r--r-- | drivers/serial/sn_console.c | 4 | ||||
-rw-r--r-- | drivers/serial/sunhv.c | 42 | ||||
-rw-r--r-- | drivers/serial/sunsab.c | 19 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 14 | ||||
-rw-r--r-- | drivers/serial/sunzilog.c | 17 | ||||
-rw-r--r-- | drivers/serial/vr41xx_siu.c | 143 |
17 files changed, 489 insertions, 243 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 22569bd5d821..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. |
@@ -250,10 +347,21 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) | |||
250 | { | 347 | { |
251 | struct bfin_serial_port *uart = dev_id; | 348 | struct bfin_serial_port *uart = dev_id; |
252 | 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 | ||
253 | spin_lock(&uart->port.lock); | 360 | spin_lock(&uart->port.lock); |
254 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) | 361 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) |
255 | bfin_serial_rx_chars(uart); | 362 | bfin_serial_rx_chars(uart); |
256 | spin_unlock(&uart->port.lock); | 363 | spin_unlock(&uart->port.lock); |
364 | #endif | ||
257 | return IRQ_HANDLED; | 365 | return IRQ_HANDLED; |
258 | } | 366 | } |
259 | 367 | ||
@@ -261,10 +369,21 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) | |||
261 | { | 369 | { |
262 | struct bfin_serial_port *uart = dev_id; | 370 | struct bfin_serial_port *uart = dev_id; |
263 | 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 | ||
264 | spin_lock(&uart->port.lock); | 382 | spin_lock(&uart->port.lock); |
265 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) | 383 | while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) |
266 | bfin_serial_tx_chars(uart); | 384 | bfin_serial_tx_chars(uart); |
267 | spin_unlock(&uart->port.lock); | 385 | spin_unlock(&uart->port.lock); |
386 | #endif | ||
268 | return IRQ_HANDLED; | 387 | return IRQ_HANDLED; |
269 | } | 388 | } |
270 | 389 | ||
@@ -275,7 +394,6 @@ static void bfin_serial_do_work(struct work_struct *work) | |||
275 | 394 | ||
276 | bfin_serial_mctrl_check(uart); | 395 | bfin_serial_mctrl_check(uart); |
277 | } | 396 | } |
278 | |||
279 | #endif | 397 | #endif |
280 | 398 | ||
281 | #ifdef CONFIG_SERIAL_BFIN_DMA | 399 | #ifdef CONFIG_SERIAL_BFIN_DMA |
@@ -324,9 +442,13 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
324 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); | 442 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); |
325 | set_dma_x_modify(uart->tx_dma_channel, 1); | 443 | set_dma_x_modify(uart->tx_dma_channel, 1); |
326 | 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 | ||
327 | ier = UART_GET_IER(uart); | 448 | ier = UART_GET_IER(uart); |
328 | ier |= ETBEI; | 449 | ier |= ETBEI; |
329 | UART_PUT_IER(uart, ier); | 450 | UART_PUT_IER(uart, ier); |
451 | #endif | ||
330 | spin_unlock_irqrestore(&uart->port.lock, flags); | 452 | spin_unlock_irqrestore(&uart->port.lock, flags); |
331 | } | 453 | } |
332 | 454 | ||
@@ -406,9 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) | |||
406 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { | 528 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { |
407 | clear_dma_irqstat(uart->tx_dma_channel); | 529 | clear_dma_irqstat(uart->tx_dma_channel); |
408 | 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 | ||
409 | ier = UART_GET_IER(uart); | 534 | ier = UART_GET_IER(uart); |
410 | ier &= ~ETBEI; | 535 | ier &= ~ETBEI; |
411 | UART_PUT_IER(uart, ier); | 536 | UART_PUT_IER(uart, ier); |
537 | #endif | ||
412 | xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); | 538 | xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); |
413 | uart->port.icount.tx+=uart->tx_count; | 539 | uart->port.icount.tx+=uart->tx_count; |
414 | 540 | ||
@@ -571,7 +697,11 @@ static int bfin_serial_startup(struct uart_port *port) | |||
571 | uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; | 697 | uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; |
572 | add_timer(&(uart->rx_dma_timer)); | 698 | add_timer(&(uart->rx_dma_timer)); |
573 | #else | 699 | #else |
700 | # ifdef CONFIG_KGDB_UART | ||
701 | if (uart->port.line != CONFIG_KGDB_UART_PORT && request_irq | ||
702 | # else | ||
574 | if (request_irq | 703 | if (request_irq |
704 | # endif | ||
575 | (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, | 705 | (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, |
576 | "BFIN_UART_RX", uart)) { | 706 | "BFIN_UART_RX", uart)) { |
577 | printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); | 707 | printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); |
@@ -586,7 +716,11 @@ static int bfin_serial_startup(struct uart_port *port) | |||
586 | return -EBUSY; | 716 | return -EBUSY; |
587 | } | 717 | } |
588 | #endif | 718 | #endif |
719 | #ifdef CONFIG_BF54x | ||
720 | UART_SET_IER(uart, ERBFI); | ||
721 | #else | ||
589 | UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); | 722 | UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); |
723 | #endif | ||
590 | return 0; | 724 | return 0; |
591 | } | 725 | } |
592 | 726 | ||
@@ -601,6 +735,9 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
601 | free_dma(uart->rx_dma_channel); | 735 | free_dma(uart->rx_dma_channel); |
602 | del_timer(&(uart->rx_dma_timer)); | 736 | del_timer(&(uart->rx_dma_timer)); |
603 | #else | 737 | #else |
738 | #ifdef CONFIG_KGDB_UART | ||
739 | if (uart->port.line != CONFIG_KGDB_UART_PORT) | ||
740 | #endif | ||
604 | free_irq(uart->port.irq, uart); | 741 | free_irq(uart->port.irq, uart); |
605 | free_irq(uart->port.irq+1, uart); | 742 | free_irq(uart->port.irq+1, uart); |
606 | #endif | 743 | #endif |
@@ -674,29 +811,41 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
674 | 811 | ||
675 | /* Disable UART */ | 812 | /* Disable UART */ |
676 | ier = UART_GET_IER(uart); | 813 | ier = UART_GET_IER(uart); |
814 | #ifdef CONFIG_BF54x | ||
815 | UART_CLEAR_IER(uart, 0xF); | ||
816 | #else | ||
677 | UART_PUT_IER(uart, 0); | 817 | UART_PUT_IER(uart, 0); |
818 | #endif | ||
678 | 819 | ||
820 | #ifndef CONFIG_BF54x | ||
679 | /* Set DLAB in LCR to Access DLL and DLH */ | 821 | /* Set DLAB in LCR to Access DLL and DLH */ |
680 | val = UART_GET_LCR(uart); | 822 | val = UART_GET_LCR(uart); |
681 | val |= DLAB; | 823 | val |= DLAB; |
682 | UART_PUT_LCR(uart, val); | 824 | UART_PUT_LCR(uart, val); |
683 | SSYNC(); | 825 | SSYNC(); |
826 | #endif | ||
684 | 827 | ||
685 | UART_PUT_DLL(uart, quot & 0xFF); | 828 | UART_PUT_DLL(uart, quot & 0xFF); |
686 | SSYNC(); | 829 | SSYNC(); |
687 | UART_PUT_DLH(uart, (quot >> 8) & 0xFF); | 830 | UART_PUT_DLH(uart, (quot >> 8) & 0xFF); |
688 | SSYNC(); | 831 | SSYNC(); |
689 | 832 | ||
833 | #ifndef CONFIG_BF54x | ||
690 | /* Clear DLAB in LCR to Access THR RBR IER */ | 834 | /* Clear DLAB in LCR to Access THR RBR IER */ |
691 | val = UART_GET_LCR(uart); | 835 | val = UART_GET_LCR(uart); |
692 | val &= ~DLAB; | 836 | val &= ~DLAB; |
693 | UART_PUT_LCR(uart, val); | 837 | UART_PUT_LCR(uart, val); |
694 | SSYNC(); | 838 | SSYNC(); |
839 | #endif | ||
695 | 840 | ||
696 | UART_PUT_LCR(uart, lcr); | 841 | UART_PUT_LCR(uart, lcr); |
697 | 842 | ||
698 | /* Enable UART */ | 843 | /* Enable UART */ |
844 | #ifdef CONFIG_BF54x | ||
845 | UART_SET_IER(uart, ier); | ||
846 | #else | ||
699 | UART_PUT_IER(uart, ier); | 847 | UART_PUT_IER(uart, ier); |
848 | #endif | ||
700 | 849 | ||
701 | val = UART_GET_GCTL(uart); | 850 | val = UART_GET_GCTL(uart); |
702 | val |= UCEN; | 851 | val |= UCEN; |
@@ -808,15 +957,15 @@ static void __init bfin_serial_init_ports(void) | |||
808 | bfin_serial_resource[i].uart_rts_pin; | 957 | bfin_serial_resource[i].uart_rts_pin; |
809 | #endif | 958 | #endif |
810 | bfin_serial_hw_init(&bfin_serial_ports[i]); | 959 | bfin_serial_hw_init(&bfin_serial_ports[i]); |
811 | |||
812 | } | 960 | } |
961 | |||
813 | } | 962 | } |
814 | 963 | ||
815 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE | 964 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE |
816 | 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) |
817 | { | 966 | { |
818 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 967 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
819 | while (!(UART_GET_LSR(uart))) | 968 | while (!(UART_GET_LSR(uart) & THRE)) |
820 | barrier(); | 969 | barrier(); |
821 | UART_PUT_CHAR(uart, ch); | 970 | UART_PUT_CHAR(uart, ch); |
822 | SSYNC(); | 971 | SSYNC(); |
@@ -868,18 +1017,22 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, | |||
868 | case 2: *bits = 7; break; | 1017 | case 2: *bits = 7; break; |
869 | case 3: *bits = 8; break; | 1018 | case 3: *bits = 8; break; |
870 | } | 1019 | } |
1020 | #ifndef CONFIG_BF54x | ||
871 | /* Set DLAB in LCR to Access DLL and DLH */ | 1021 | /* Set DLAB in LCR to Access DLL and DLH */ |
872 | val = UART_GET_LCR(uart); | 1022 | val = UART_GET_LCR(uart); |
873 | val |= DLAB; | 1023 | val |= DLAB; |
874 | UART_PUT_LCR(uart, val); | 1024 | UART_PUT_LCR(uart, val); |
1025 | #endif | ||
875 | 1026 | ||
876 | dll = UART_GET_DLL(uart); | 1027 | dll = UART_GET_DLL(uart); |
877 | dlh = UART_GET_DLH(uart); | 1028 | dlh = UART_GET_DLH(uart); |
878 | 1029 | ||
1030 | #ifndef CONFIG_BF54x | ||
879 | /* Clear DLAB in LCR to Access THR RBR IER */ | 1031 | /* Clear DLAB in LCR to Access THR RBR IER */ |
880 | val = UART_GET_LCR(uart); | 1032 | val = UART_GET_LCR(uart); |
881 | val &= ~DLAB; | 1033 | val &= ~DLAB; |
882 | UART_PUT_LCR(uart, val); | 1034 | UART_PUT_LCR(uart, val); |
1035 | #endif | ||
883 | 1036 | ||
884 | *baud = get_sclk() / (16*(dll | dlh << 8)); | 1037 | *baud = get_sclk() / (16*(dll | dlh << 8)); |
885 | } | 1038 | } |
@@ -931,6 +1084,10 @@ static int __init bfin_serial_rs_console_init(void) | |||
931 | { | 1084 | { |
932 | bfin_serial_init_ports(); | 1085 | bfin_serial_init_ports(); |
933 | 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 | ||
934 | return 0; | 1091 | return 0; |
935 | } | 1092 | } |
936 | console_initcall(bfin_serial_rs_console_init); | 1093 | console_initcall(bfin_serial_rs_console_init); |
@@ -1023,6 +1180,10 @@ static struct platform_driver bfin_serial_driver = { | |||
1023 | static int __init bfin_serial_init(void) | 1180 | static int __init bfin_serial_init(void) |
1024 | { | 1181 | { |
1025 | 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 | ||
1026 | 1187 | ||
1027 | pr_info("Serial: Blackfin serial driver\n"); | 1188 | pr_info("Serial: Blackfin serial driver\n"); |
1028 | 1189 | ||
@@ -1036,6 +1197,21 @@ static int __init bfin_serial_init(void) | |||
1036 | uart_unregister_driver(&bfin_serial_reg); | 1197 | uart_unregister_driver(&bfin_serial_reg); |
1037 | } | 1198 | } |
1038 | } | 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 | ||
1039 | return ret; | 1215 | return ret; |
1040 | } | 1216 | } |
1041 | 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/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/sh-sci.c b/drivers/serial/sh-sci.c index 1f89496d530e..672cd1042539 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -367,7 +367,9 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | |||
367 | } else { | 367 | } else { |
368 | #ifdef CONFIG_CPU_SUBTYPE_SH7343 | 368 | #ifdef CONFIG_CPU_SUBTYPE_SH7343 |
369 | /* Nothing */ | 369 | /* Nothing */ |
370 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) | 370 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
371 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | ||
372 | defined(CONFIG_CPU_SUBTYPE_SHX3) | ||
371 | ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ | 373 | ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ |
372 | #else | 374 | #else |
373 | ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ | 375 | ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index fb04fb5f9843..247fb66bf0f4 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -53,7 +53,12 @@ | |||
53 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 53 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
54 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 54 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
55 | # define SCIF_ONLY | 55 | # define SCIF_ONLY |
56 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) | 56 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ |
57 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ | ||
58 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | ||
59 | defined(CONFIG_CPU_SUBTYPE_SH7091) || \ | ||
60 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | ||
61 | defined(CONFIG_CPU_SUBTYPE_SH7751R) | ||
57 | # define SCSPTR1 0xffe0001c /* 8 bit SCI */ | 62 | # define SCSPTR1 0xffe0001c /* 8 bit SCI */ |
58 | # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ | 63 | # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ |
59 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 64 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
@@ -73,7 +78,7 @@ | |||
73 | # define SCPDR 0xA4050136 /* 16 bit SCIF */ | 78 | # define SCPDR 0xA4050136 /* 16 bit SCIF */ |
74 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ | 79 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ |
75 | # define SCIF_ONLY | 80 | # define SCIF_ONLY |
76 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | 81 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
77 | # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ | 82 | # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ |
78 | # define SCI_NPORTS 2 | 83 | # define SCI_NPORTS 2 |
79 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 84 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
@@ -168,6 +173,14 @@ | |||
168 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 173 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
169 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 174 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
170 | # define SCIF_ONLY | 175 | # define SCIF_ONLY |
176 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) | ||
177 | # define SCSPTR0 0xffc30020 /* 16 bit SCIF */ | ||
178 | # define SCSPTR1 0xffc40020 /* 16 bit SCIF */ | ||
179 | # define SCSPTR2 0xffc50020 /* 16 bit SCIF */ | ||
180 | # define SCSPTR3 0xffc60020 /* 16 bit SCIF */ | ||
181 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | ||
182 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | ||
183 | # define SCIF_ONLY | ||
171 | #else | 184 | #else |
172 | # error CPU subtype not defined | 185 | # error CPU subtype not defined |
173 | #endif | 186 | #endif |
@@ -177,10 +190,15 @@ | |||
177 | #define SCI_CTRL_FLAGS_RIE 0x40 /* all */ | 190 | #define SCI_CTRL_FLAGS_RIE 0x40 /* all */ |
178 | #define SCI_CTRL_FLAGS_TE 0x20 /* all */ | 191 | #define SCI_CTRL_FLAGS_TE 0x20 /* all */ |
179 | #define SCI_CTRL_FLAGS_RE 0x10 /* all */ | 192 | #define SCI_CTRL_FLAGS_RE 0x10 /* all */ |
180 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | 193 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ |
181 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | 194 | defined(CONFIG_CPU_SUBTYPE_SH7091) || \ |
182 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 195 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ |
183 | defined(CONFIG_CPU_SUBTYPE_SH7785) | 196 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ |
197 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | ||
198 | defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ | ||
199 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | ||
200 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | ||
201 | defined(CONFIG_CPU_SUBTYPE_SHX3) | ||
184 | #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ | 202 | #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ |
185 | #else | 203 | #else |
186 | #define SCI_CTRL_FLAGS_REIE 0 | 204 | #define SCI_CTRL_FLAGS_REIE 0 |
@@ -514,8 +532,12 @@ static inline void set_sh771x_scif_pfc(struct uart_port *port) | |||
514 | } | 532 | } |
515 | } | 533 | } |
516 | 534 | ||
517 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | 535 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ |
518 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | 536 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ |
537 | defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ | ||
538 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ | ||
539 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | ||
540 | defined(CONFIG_CPU_SUBTYPE_SH7091) || \ | ||
519 | defined(CONFIG_CPU_SUBTYPE_SH4_202) | 541 | defined(CONFIG_CPU_SUBTYPE_SH4_202) |
520 | static inline int sci_rxd_in(struct uart_port *port) | 542 | static inline int sci_rxd_in(struct uart_port *port) |
521 | { | 543 | { |
@@ -653,6 +675,18 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
653 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 675 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
654 | return 1; | 676 | return 1; |
655 | } | 677 | } |
678 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) | ||
679 | static inline int sci_rxd_in(struct uart_port *port) | ||
680 | { | ||
681 | if (port->mapbase == 0xffc30000) | ||
682 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
683 | if (port->mapbase == 0xffc40000) | ||
684 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
685 | if (port->mapbase == 0xffc50000) | ||
686 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
687 | if (port->mapbase == 0xffc60000) | ||
688 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | ||
689 | } | ||
656 | #endif | 690 | #endif |
657 | 691 | ||
658 | /* | 692 | /* |
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/sunhv.c b/drivers/serial/sunhv.c index 96557e6dba60..d82be42ff29a 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
@@ -258,17 +258,7 @@ static void sunhv_stop_tx(struct uart_port *port) | |||
258 | /* port->lock held by caller. */ | 258 | /* port->lock held by caller. */ |
259 | static void sunhv_start_tx(struct uart_port *port) | 259 | static void sunhv_start_tx(struct uart_port *port) |
260 | { | 260 | { |
261 | struct circ_buf *xmit = &port->info->xmit; | 261 | transmit_chars(port); |
262 | |||
263 | while (!uart_circ_empty(xmit)) { | ||
264 | long status = sun4v_con_putchar(xmit->buf[xmit->tail]); | ||
265 | |||
266 | if (status != HV_EOK) | ||
267 | break; | ||
268 | |||
269 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
270 | port->icount.tx++; | ||
271 | } | ||
272 | } | 262 | } |
273 | 263 | ||
274 | /* port->lock is not held. */ | 264 | /* port->lock is not held. */ |
@@ -440,8 +430,16 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign | |||
440 | { | 430 | { |
441 | struct uart_port *port = sunhv_port; | 431 | struct uart_port *port = sunhv_port; |
442 | unsigned long flags; | 432 | unsigned long flags; |
433 | int locked = 1; | ||
434 | |||
435 | local_irq_save(flags); | ||
436 | if (port->sysrq) { | ||
437 | locked = 0; | ||
438 | } else if (oops_in_progress) { | ||
439 | locked = spin_trylock(&port->lock); | ||
440 | } else | ||
441 | spin_lock(&port->lock); | ||
443 | 442 | ||
444 | spin_lock_irqsave(&port->lock, flags); | ||
445 | while (n > 0) { | 443 | while (n > 0) { |
446 | unsigned long ra = __pa(con_write_page); | 444 | unsigned long ra = __pa(con_write_page); |
447 | unsigned long page_bytes; | 445 | unsigned long page_bytes; |
@@ -469,7 +467,10 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign | |||
469 | ra += written; | 467 | ra += written; |
470 | } | 468 | } |
471 | } | 469 | } |
472 | spin_unlock_irqrestore(&port->lock, flags); | 470 | |
471 | if (locked) | ||
472 | spin_unlock(&port->lock); | ||
473 | local_irq_restore(flags); | ||
473 | } | 474 | } |
474 | 475 | ||
475 | static inline void sunhv_console_putchar(struct uart_port *port, char c) | 476 | static inline void sunhv_console_putchar(struct uart_port *port, char c) |
@@ -488,7 +489,15 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig | |||
488 | { | 489 | { |
489 | struct uart_port *port = sunhv_port; | 490 | struct uart_port *port = sunhv_port; |
490 | unsigned long flags; | 491 | unsigned long flags; |
491 | int i; | 492 | int i, locked = 1; |
493 | |||
494 | local_irq_save(flags); | ||
495 | if (port->sysrq) { | ||
496 | locked = 0; | ||
497 | } else if (oops_in_progress) { | ||
498 | locked = spin_trylock(&port->lock); | ||
499 | } else | ||
500 | spin_lock(&port->lock); | ||
492 | 501 | ||
493 | spin_lock_irqsave(&port->lock, flags); | 502 | spin_lock_irqsave(&port->lock, flags); |
494 | for (i = 0; i < n; i++) { | 503 | for (i = 0; i < n; i++) { |
@@ -496,7 +505,10 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig | |||
496 | sunhv_console_putchar(port, '\r'); | 505 | sunhv_console_putchar(port, '\r'); |
497 | sunhv_console_putchar(port, *s++); | 506 | sunhv_console_putchar(port, *s++); |
498 | } | 507 | } |
499 | spin_unlock_irqrestore(&port->lock, flags); | 508 | |
509 | if (locked) | ||
510 | spin_unlock(&port->lock); | ||
511 | local_irq_restore(flags); | ||
500 | } | 512 | } |
501 | 513 | ||
502 | static struct console sunhv_console = { | 514 | static struct console sunhv_console = { |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index deb9ab4b5a0b..8a0f9e4408d4 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -860,22 +860,31 @@ static int num_channels; | |||
860 | static void sunsab_console_putchar(struct uart_port *port, int c) | 860 | static void sunsab_console_putchar(struct uart_port *port, int c) |
861 | { | 861 | { |
862 | struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; | 862 | struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; |
863 | unsigned long flags; | ||
864 | |||
865 | spin_lock_irqsave(&up->port.lock, flags); | ||
866 | 863 | ||
867 | sunsab_tec_wait(up); | 864 | sunsab_tec_wait(up); |
868 | writeb(c, &up->regs->w.tic); | 865 | writeb(c, &up->regs->w.tic); |
869 | |||
870 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
871 | } | 866 | } |
872 | 867 | ||
873 | static void sunsab_console_write(struct console *con, const char *s, unsigned n) | 868 | static void sunsab_console_write(struct console *con, const char *s, unsigned n) |
874 | { | 869 | { |
875 | struct uart_sunsab_port *up = &sunsab_ports[con->index]; | 870 | struct uart_sunsab_port *up = &sunsab_ports[con->index]; |
871 | unsigned long flags; | ||
872 | int locked = 1; | ||
873 | |||
874 | local_irq_save(flags); | ||
875 | if (up->port.sysrq) { | ||
876 | locked = 0; | ||
877 | } else if (oops_in_progress) { | ||
878 | locked = spin_trylock(&up->port.lock); | ||
879 | } else | ||
880 | spin_lock(&up->port.lock); | ||
876 | 881 | ||
877 | uart_console_write(&up->port, s, n, sunsab_console_putchar); | 882 | uart_console_write(&up->port, s, n, sunsab_console_putchar); |
878 | sunsab_tec_wait(up); | 883 | sunsab_tec_wait(up); |
884 | |||
885 | if (locked) | ||
886 | spin_unlock(&up->port.lock); | ||
887 | local_irq_restore(flags); | ||
879 | } | 888 | } |
880 | 889 | ||
881 | static int sunsab_console_setup(struct console *con, char *options) | 890 | static int sunsab_console_setup(struct console *con, char *options) |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 2a63cdba3208..26d720baf88c 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1288,7 +1288,17 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1288 | unsigned int count) | 1288 | unsigned int count) |
1289 | { | 1289 | { |
1290 | struct uart_sunsu_port *up = &sunsu_ports[co->index]; | 1290 | struct uart_sunsu_port *up = &sunsu_ports[co->index]; |
1291 | unsigned long flags; | ||
1291 | unsigned int ier; | 1292 | unsigned int ier; |
1293 | int locked = 1; | ||
1294 | |||
1295 | local_irq_save(flags); | ||
1296 | if (up->port.sysrq) { | ||
1297 | locked = 0; | ||
1298 | } else if (oops_in_progress) { | ||
1299 | locked = spin_trylock(&up->port.lock); | ||
1300 | } else | ||
1301 | spin_lock(&up->port.lock); | ||
1292 | 1302 | ||
1293 | /* | 1303 | /* |
1294 | * First save the UER then disable the interrupts | 1304 | * First save the UER then disable the interrupts |
@@ -1304,6 +1314,10 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1304 | */ | 1314 | */ |
1305 | wait_for_xmitr(up); | 1315 | wait_for_xmitr(up); |
1306 | serial_out(up, UART_IER, ier); | 1316 | serial_out(up, UART_IER, ier); |
1317 | |||
1318 | if (locked) | ||
1319 | spin_unlock(&up->port.lock); | ||
1320 | local_irq_restore(flags); | ||
1307 | } | 1321 | } |
1308 | 1322 | ||
1309 | /* | 1323 | /* |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 15b6e1cb040b..0a3e10a4a35d 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their | 9 | * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their |
10 | * work there. | 10 | * work there. |
11 | * | 11 | * |
12 | * Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net) | 12 | * Copyright (C) 2002, 2006, 2007 David S. Miller (davem@davemloft.net) |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -1151,11 +1151,22 @@ sunzilog_console_write(struct console *con, const char *s, unsigned int count) | |||
1151 | { | 1151 | { |
1152 | struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; | 1152 | struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; |
1153 | unsigned long flags; | 1153 | unsigned long flags; |
1154 | int locked = 1; | ||
1155 | |||
1156 | local_irq_save(flags); | ||
1157 | if (up->port.sysrq) { | ||
1158 | locked = 0; | ||
1159 | } else if (oops_in_progress) { | ||
1160 | locked = spin_trylock(&up->port.lock); | ||
1161 | } else | ||
1162 | spin_lock(&up->port.lock); | ||
1154 | 1163 | ||
1155 | spin_lock_irqsave(&up->port.lock, flags); | ||
1156 | uart_console_write(&up->port, s, count, sunzilog_putchar); | 1164 | uart_console_write(&up->port, s, count, sunzilog_putchar); |
1157 | udelay(2); | 1165 | udelay(2); |
1158 | spin_unlock_irqrestore(&up->port.lock, flags); | 1166 | |
1167 | if (locked) | ||
1168 | spin_unlock(&up->port.lock); | ||
1169 | local_irq_restore(flags); | ||
1159 | } | 1170 | } |
1160 | 1171 | ||
1161 | static int __init sunzilog_console_setup(struct console *con, char *options) | 1172 | static int __init sunzilog_console_setup(struct console *con, char *options) |
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); |