diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/8250.c | 25 | ||||
-rw-r--r-- | drivers/serial/8250_pci.c | 31 | ||||
-rw-r--r-- | drivers/serial/at91_serial.c | 5 | ||||
-rw-r--r-- | drivers/serial/dz.c | 2 | ||||
-rw-r--r-- | drivers/serial/ip22zilog.c | 3 | ||||
-rw-r--r-- | drivers/serial/s3c2410.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 4 | ||||
-rw-r--r-- | drivers/serial/sh-sci.c | 4 | ||||
-rw-r--r-- | drivers/serial/sunsab.c | 16 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 40 | ||||
-rw-r--r-- | drivers/serial/sunzilog.c | 128 | ||||
-rw-r--r-- | drivers/serial/vr41xx_siu.c | 1 |
12 files changed, 173 insertions, 88 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 0995430e4cf1..0ae9ced00ed4 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -299,6 +299,7 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) | |||
299 | 299 | ||
300 | static unsigned int serial_in(struct uart_8250_port *up, int offset) | 300 | static unsigned int serial_in(struct uart_8250_port *up, int offset) |
301 | { | 301 | { |
302 | unsigned int tmp; | ||
302 | offset = map_8250_in_reg(up, offset) << up->port.regshift; | 303 | offset = map_8250_in_reg(up, offset) << up->port.regshift; |
303 | 304 | ||
304 | switch (up->port.iotype) { | 305 | switch (up->port.iotype) { |
@@ -317,6 +318,13 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) | |||
317 | return __raw_readl(up->port.membase + offset); | 318 | return __raw_readl(up->port.membase + offset); |
318 | #endif | 319 | #endif |
319 | 320 | ||
321 | case UPIO_TSI: | ||
322 | if (offset == UART_IIR) { | ||
323 | tmp = readl((u32 *)(up->port.membase + UART_RX)); | ||
324 | return (cpu_to_le32(tmp) >> 8) & 0xff; | ||
325 | } else | ||
326 | return readb(up->port.membase + offset); | ||
327 | |||
320 | default: | 328 | default: |
321 | return inb(up->port.iobase + offset); | 329 | return inb(up->port.iobase + offset); |
322 | } | 330 | } |
@@ -346,6 +354,10 @@ serial_out(struct uart_8250_port *up, int offset, int value) | |||
346 | __raw_writel(value, up->port.membase + offset); | 354 | __raw_writel(value, up->port.membase + offset); |
347 | break; | 355 | break; |
348 | #endif | 356 | #endif |
357 | case UPIO_TSI: | ||
358 | if (!((offset == UART_IER) && (value & UART_IER_UUE))) | ||
359 | writeb(value, up->port.membase + offset); | ||
360 | break; | ||
349 | 361 | ||
350 | default: | 362 | default: |
351 | outb(value, up->port.iobase + offset); | 363 | outb(value, up->port.iobase + offset); |
@@ -2240,10 +2252,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2240 | 2252 | ||
2241 | touch_nmi_watchdog(); | 2253 | touch_nmi_watchdog(); |
2242 | 2254 | ||
2243 | if (oops_in_progress) { | 2255 | local_irq_save(flags); |
2244 | locked = spin_trylock_irqsave(&up->port.lock, flags); | 2256 | if (up->port.sysrq) { |
2257 | /* serial8250_handle_port() already took the lock */ | ||
2258 | locked = 0; | ||
2259 | } else if (oops_in_progress) { | ||
2260 | locked = spin_trylock(&up->port.lock); | ||
2245 | } else | 2261 | } else |
2246 | spin_lock_irqsave(&up->port.lock, flags); | 2262 | spin_lock(&up->port.lock); |
2247 | 2263 | ||
2248 | /* | 2264 | /* |
2249 | * First save the IER then disable the interrupts | 2265 | * First save the IER then disable the interrupts |
@@ -2265,7 +2281,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2265 | serial_out(up, UART_IER, ier); | 2281 | serial_out(up, UART_IER, ier); |
2266 | 2282 | ||
2267 | if (locked) | 2283 | if (locked) |
2268 | spin_unlock_irqrestore(&up->port.lock, flags); | 2284 | spin_unlock(&up->port.lock); |
2285 | local_irq_restore(flags); | ||
2269 | } | 2286 | } |
2270 | 2287 | ||
2271 | static int serial8250_console_setup(struct console *co, char *options) | 2288 | static int serial8250_console_setup(struct console *co, char *options) |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index a1d322f8a16c..851e4839d6d9 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -458,11 +458,11 @@ static int pci_siig_setup(struct serial_private *priv, | |||
458 | * growing *huge*, we use this function to collapse some 70 entries | 458 | * growing *huge*, we use this function to collapse some 70 entries |
459 | * in the PCI table into one, for sanity's and compactness's sake. | 459 | * in the PCI table into one, for sanity's and compactness's sake. |
460 | */ | 460 | */ |
461 | static unsigned short timedia_single_port[] = { | 461 | static const unsigned short timedia_single_port[] = { |
462 | 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 | 462 | 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 |
463 | }; | 463 | }; |
464 | 464 | ||
465 | static unsigned short timedia_dual_port[] = { | 465 | static const unsigned short timedia_dual_port[] = { |
466 | 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085, | 466 | 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085, |
467 | 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, | 467 | 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, |
468 | 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, | 468 | 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, |
@@ -470,35 +470,34 @@ static unsigned short timedia_dual_port[] = { | |||
470 | 0xD079, 0 | 470 | 0xD079, 0 |
471 | }; | 471 | }; |
472 | 472 | ||
473 | static unsigned short timedia_quad_port[] = { | 473 | static const unsigned short timedia_quad_port[] = { |
474 | 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, | 474 | 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, |
475 | 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, | 475 | 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, |
476 | 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056, | 476 | 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056, |
477 | 0xB157, 0 | 477 | 0xB157, 0 |
478 | }; | 478 | }; |
479 | 479 | ||
480 | static unsigned short timedia_eight_port[] = { | 480 | static const unsigned short timedia_eight_port[] = { |
481 | 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, | 481 | 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, |
482 | 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 | 482 | 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 |
483 | }; | 483 | }; |
484 | 484 | ||
485 | static const struct timedia_struct { | 485 | static const struct timedia_struct { |
486 | int num; | 486 | int num; |
487 | unsigned short *ids; | 487 | const unsigned short *ids; |
488 | } timedia_data[] = { | 488 | } timedia_data[] = { |
489 | { 1, timedia_single_port }, | 489 | { 1, timedia_single_port }, |
490 | { 2, timedia_dual_port }, | 490 | { 2, timedia_dual_port }, |
491 | { 4, timedia_quad_port }, | 491 | { 4, timedia_quad_port }, |
492 | { 8, timedia_eight_port }, | 492 | { 8, timedia_eight_port } |
493 | { 0, NULL } | ||
494 | }; | 493 | }; |
495 | 494 | ||
496 | static int pci_timedia_init(struct pci_dev *dev) | 495 | static int pci_timedia_init(struct pci_dev *dev) |
497 | { | 496 | { |
498 | unsigned short *ids; | 497 | const unsigned short *ids; |
499 | int i, j; | 498 | int i, j; |
500 | 499 | ||
501 | for (i = 0; timedia_data[i].num; i++) { | 500 | for (i = 0; i < ARRAY_SIZE(timedia_data); i++) { |
502 | ids = timedia_data[i].ids; | 501 | ids = timedia_data[i].ids; |
503 | for (j = 0; ids[j]; j++) | 502 | for (j = 0; ids[j]; j++) |
504 | if (dev->subsystem_device == ids[j]) | 503 | if (dev->subsystem_device == ids[j]) |
@@ -936,6 +935,7 @@ enum pci_board_num_t { | |||
936 | pbn_b1_8_1382400, | 935 | pbn_b1_8_1382400, |
937 | 936 | ||
938 | pbn_b2_1_115200, | 937 | pbn_b2_1_115200, |
938 | pbn_b2_2_115200, | ||
939 | pbn_b2_8_115200, | 939 | pbn_b2_8_115200, |
940 | 940 | ||
941 | pbn_b2_1_460800, | 941 | pbn_b2_1_460800, |
@@ -1243,6 +1243,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
1243 | .base_baud = 115200, | 1243 | .base_baud = 115200, |
1244 | .uart_offset = 8, | 1244 | .uart_offset = 8, |
1245 | }, | 1245 | }, |
1246 | [pbn_b2_2_115200] = { | ||
1247 | .flags = FL_BASE2, | ||
1248 | .num_ports = 2, | ||
1249 | .base_baud = 115200, | ||
1250 | .uart_offset = 8, | ||
1251 | }, | ||
1246 | [pbn_b2_8_115200] = { | 1252 | [pbn_b2_8_115200] = { |
1247 | .flags = FL_BASE2, | 1253 | .flags = FL_BASE2, |
1248 | .num_ports = 8, | 1254 | .num_ports = 8, |
@@ -2340,6 +2346,13 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2340 | pbn_b0_1_115200 }, | 2346 | pbn_b0_1_115200 }, |
2341 | 2347 | ||
2342 | /* | 2348 | /* |
2349 | * IntaShield IS-200 | ||
2350 | */ | ||
2351 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, | ||
2352 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ | ||
2353 | pbn_b2_2_115200 }, | ||
2354 | |||
2355 | /* | ||
2343 | * These entries match devices with class COMMUNICATION_SERIAL, | 2356 | * These entries match devices with class COMMUNICATION_SERIAL, |
2344 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 2357 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
2345 | */ | 2358 | */ |
diff --git a/drivers/serial/at91_serial.c b/drivers/serial/at91_serial.c index a7d664383dae..54c6b2adf7b7 100644 --- a/drivers/serial/at91_serial.c +++ b/drivers/serial/at91_serial.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/mach/serial_at91.h> | 41 | #include <asm/mach/serial_at91.h> |
42 | #include <asm/arch/board.h> | 42 | #include <asm/arch/board.h> |
43 | #include <asm/arch/system.h> | 43 | #include <asm/arch/system.h> |
44 | #include <asm/arch/gpio.h> | ||
44 | 45 | ||
45 | #if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 46 | #if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
46 | #define SUPPORT_SYSRQ | 47 | #define SUPPORT_SYSRQ |
@@ -140,9 +141,9 @@ static void at91_set_mctrl(struct uart_port *port, u_int mctrl) | |||
140 | */ | 141 | */ |
141 | if (port->mapbase == AT91_BASE_US0) { | 142 | if (port->mapbase == AT91_BASE_US0) { |
142 | if (mctrl & TIOCM_RTS) | 143 | if (mctrl & TIOCM_RTS) |
143 | at91_sys_write(AT91_PIOA + PIO_CODR, AT91_PA21_RTS0); | 144 | at91_set_gpio_value(AT91_PIN_PA21, 0); |
144 | else | 145 | else |
145 | at91_sys_write(AT91_PIOA + PIO_SODR, AT91_PA21_RTS0); | 146 | at91_set_gpio_value(AT91_PIN_PA21, 1); |
146 | } | 147 | } |
147 | } | 148 | } |
148 | 149 | ||
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index d119c8296a78..8a98aae80e22 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -673,7 +673,7 @@ static void dz_reset(struct dz_port *dport) | |||
673 | } | 673 | } |
674 | 674 | ||
675 | #ifdef CONFIG_SERIAL_DZ_CONSOLE | 675 | #ifdef CONFIG_SERIAL_DZ_CONSOLE |
676 | static void dz_console_putchar(struct uart_port *port, int ch) | 676 | static void dz_console_putchar(struct uart_port *uport, int ch) |
677 | { | 677 | { |
678 | struct dz_port *dport = (struct dz_port *)uport; | 678 | struct dz_port *dport = (struct dz_port *)uport; |
679 | unsigned long flags; | 679 | unsigned long flags; |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 342042889f6e..5ff269fb604c 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -1143,9 +1143,8 @@ static void __init ip22zilog_prepare(void) | |||
1143 | up[(chip * 2) + 1].port.fifosize = 1; | 1143 | up[(chip * 2) + 1].port.fifosize = 1; |
1144 | up[(chip * 2) + 1].port.ops = &ip22zilog_pops; | 1144 | up[(chip * 2) + 1].port.ops = &ip22zilog_pops; |
1145 | up[(chip * 2) + 1].port.type = PORT_IP22ZILOG; | 1145 | up[(chip * 2) + 1].port.type = PORT_IP22ZILOG; |
1146 | up[(chip * 2) + 1].port.flags |= IP22ZILOG_FLAG_IS_CHANNEL_A; | ||
1147 | up[(chip * 2) + 1].port.line = (chip * 2) + 1; | 1146 | up[(chip * 2) + 1].port.line = (chip * 2) + 1; |
1148 | up[(chip * 2) + 1].flags = 0; | 1147 | up[(chip * 2) + 1].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A; |
1149 | } | 1148 | } |
1150 | } | 1149 | } |
1151 | 1150 | ||
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 392bffcf96e8..95738a19cde7 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -1621,7 +1621,7 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = { | |||
1621 | static int s3c2412_serial_probe(struct platform_device *dev) | 1621 | static int s3c2412_serial_probe(struct platform_device *dev) |
1622 | { | 1622 | { |
1623 | dbg("s3c2440_serial_probe: dev=%p\n", dev); | 1623 | dbg("s3c2440_serial_probe: dev=%p\n", dev); |
1624 | return s3c24xx_serial_probe(dev, &s3c2440_uart_inf); | 1624 | return s3c24xx_serial_probe(dev, &s3c2412_uart_inf); |
1625 | } | 1625 | } |
1626 | 1626 | ||
1627 | static struct platform_driver s3c2412_serial_drv = { | 1627 | static struct platform_driver s3c2412_serial_drv = { |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index d5f636fbf29a..372e47f7d596 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -2036,6 +2036,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) | |||
2036 | case UPIO_MEM: | 2036 | case UPIO_MEM: |
2037 | case UPIO_MEM32: | 2037 | case UPIO_MEM32: |
2038 | case UPIO_AU: | 2038 | case UPIO_AU: |
2039 | case UPIO_TSI: | ||
2039 | snprintf(address, sizeof(address), | 2040 | snprintf(address, sizeof(address), |
2040 | "MMIO 0x%lx", port->mapbase); | 2041 | "MMIO 0x%lx", port->mapbase); |
2041 | break; | 2042 | break; |
@@ -2376,6 +2377,9 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) | |||
2376 | return (port1->iobase == port2->iobase) && | 2377 | return (port1->iobase == port2->iobase) && |
2377 | (port1->hub6 == port2->hub6); | 2378 | (port1->hub6 == port2->hub6); |
2378 | case UPIO_MEM: | 2379 | case UPIO_MEM: |
2380 | case UPIO_MEM32: | ||
2381 | case UPIO_AU: | ||
2382 | case UPIO_TSI: | ||
2379 | return (port1->mapbase == port2->mapbase); | 2383 | return (port1->mapbase == port2->mapbase); |
2380 | } | 2384 | } |
2381 | return 0; | 2385 | return 0; |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 301573373c30..cbede06cac27 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -1579,7 +1579,7 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
1579 | h8300_sci_enable(port, sci_enable); | 1579 | h8300_sci_enable(port, sci_enable); |
1580 | #endif | 1580 | #endif |
1581 | #elif defined(CONFIG_SUPERH64) | 1581 | #elif defined(CONFIG_SUPERH64) |
1582 | port->uartclk = current_cpu_info.module_clock * 16; | 1582 | port->uartclk = current_cpu_data.module_clock * 16; |
1583 | #else | 1583 | #else |
1584 | { | 1584 | { |
1585 | struct clk *clk = clk_get("module_clk"); | 1585 | struct clk *clk = clk_get("module_clk"); |
@@ -1720,7 +1720,7 @@ static int __init sci_init(void) | |||
1720 | #if defined(__H8300H__) || defined(__H8300S__) | 1720 | #if defined(__H8300H__) || defined(__H8300S__) |
1721 | sciport->port.uartclk = CONFIG_CPU_CLOCK; | 1721 | sciport->port.uartclk = CONFIG_CPU_CLOCK; |
1722 | #elif defined(CONFIG_SUPERH64) | 1722 | #elif defined(CONFIG_SUPERH64) |
1723 | sciport->port.uartclk = current_cpu_info.module_clock * 16; | 1723 | sciport->port.uartclk = current_cpu_data.module_clock * 16; |
1724 | #else | 1724 | #else |
1725 | struct clk *clk = clk_get("module_clk"); | 1725 | struct clk *clk = clk_get("module_clk"); |
1726 | sciport->port.uartclk = clk_get_rate(clk) * 16; | 1726 | sciport->port.uartclk = clk_get_rate(clk) * 16; |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 0dbd4df44c05..cfe20f730436 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -886,6 +886,15 @@ static int sunsab_console_setup(struct console *con, char *options) | |||
886 | unsigned long flags; | 886 | unsigned long flags; |
887 | unsigned int baud, quot; | 887 | unsigned int baud, quot; |
888 | 888 | ||
889 | /* | ||
890 | * The console framework calls us for each and every port | ||
891 | * registered. Defer the console setup until the requested | ||
892 | * port has been properly discovered. A bit of a hack, | ||
893 | * though... | ||
894 | */ | ||
895 | if (up->port.type != PORT_SUNSAB) | ||
896 | return -1; | ||
897 | |||
889 | printk("Console: ttyS%d (SAB82532)\n", | 898 | printk("Console: ttyS%d (SAB82532)\n", |
890 | (sunsab_reg.minor - 64) + con->index); | 899 | (sunsab_reg.minor - 64) + con->index); |
891 | 900 | ||
@@ -1047,12 +1056,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * | |||
1047 | up = &sunsab_ports[inst * 2]; | 1056 | up = &sunsab_ports[inst * 2]; |
1048 | 1057 | ||
1049 | err = sunsab_init_one(&up[0], op, | 1058 | err = sunsab_init_one(&up[0], op, |
1050 | sizeof(union sab82532_async_regs), | 1059 | 0, |
1051 | (inst * 2) + 0); | 1060 | (inst * 2) + 0); |
1052 | if (err) | 1061 | if (err) |
1053 | return err; | 1062 | return err; |
1054 | 1063 | ||
1055 | err = sunsab_init_one(&up[0], op, 0, | 1064 | err = sunsab_init_one(&up[1], op, |
1065 | sizeof(union sab82532_async_regs), | ||
1056 | (inst * 2) + 1); | 1066 | (inst * 2) + 1); |
1057 | if (err) { | 1067 | if (err) { |
1058 | of_iounmap(up[0].port.membase, | 1068 | of_iounmap(up[0].port.membase, |
@@ -1117,7 +1127,7 @@ static int __init sunsab_init(void) | |||
1117 | int err; | 1127 | int err; |
1118 | 1128 | ||
1119 | num_channels = 0; | 1129 | num_channels = 0; |
1120 | for_each_node_by_name(dp, "su") | 1130 | for_each_node_by_name(dp, "se") |
1121 | num_channels += 2; | 1131 | num_channels += 2; |
1122 | for_each_node_by_name(dp, "serial") { | 1132 | for_each_node_by_name(dp, "serial") { |
1123 | if (of_device_is_compatible(dp, "sab82532")) | 1133 | if (of_device_is_compatible(dp, "sab82532")) |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index f9013baba05b..d3a5aeee73a3 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1200,6 +1200,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up) | |||
1200 | if (up->port.type == PORT_UNKNOWN) | 1200 | if (up->port.type == PORT_UNKNOWN) |
1201 | return -ENODEV; | 1201 | return -ENODEV; |
1202 | 1202 | ||
1203 | printk("%s: %s port at %lx, irq %u\n", | ||
1204 | to_of_device(up->port.dev)->node->full_name, | ||
1205 | (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", | ||
1206 | up->port.mapbase, up->port.irq); | ||
1207 | |||
1203 | #ifdef CONFIG_SERIO | 1208 | #ifdef CONFIG_SERIO |
1204 | serio = &up->serio; | 1209 | serio = &up->serio; |
1205 | serio->port_data = up; | 1210 | serio->port_data = up; |
@@ -1406,25 +1411,35 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1406 | struct device_node *dp = op->node; | 1411 | struct device_node *dp = op->node; |
1407 | struct uart_sunsu_port *up; | 1412 | struct uart_sunsu_port *up; |
1408 | struct resource *rp; | 1413 | struct resource *rp; |
1414 | enum su_type type; | ||
1409 | int err; | 1415 | int err; |
1410 | 1416 | ||
1411 | if (inst >= UART_NR) | 1417 | type = su_get_type(dp); |
1412 | return -EINVAL; | 1418 | if (type == SU_PORT_PORT) { |
1419 | if (inst >= UART_NR) | ||
1420 | return -EINVAL; | ||
1421 | up = &sunsu_ports[inst]; | ||
1422 | } else { | ||
1423 | up = kzalloc(sizeof(*up), GFP_KERNEL); | ||
1424 | if (!up) | ||
1425 | return -ENOMEM; | ||
1426 | } | ||
1413 | 1427 | ||
1414 | up = &sunsu_ports[inst]; | ||
1415 | up->port.line = inst; | 1428 | up->port.line = inst; |
1416 | 1429 | ||
1417 | spin_lock_init(&up->port.lock); | 1430 | spin_lock_init(&up->port.lock); |
1418 | 1431 | ||
1419 | up->su_type = su_get_type(dp); | 1432 | up->su_type = type; |
1420 | 1433 | ||
1421 | rp = &op->resource[0]; | 1434 | rp = &op->resource[0]; |
1422 | up->port.mapbase = op->resource[0].start; | 1435 | up->port.mapbase = rp->start; |
1423 | |||
1424 | up->reg_size = (rp->end - rp->start) + 1; | 1436 | up->reg_size = (rp->end - rp->start) + 1; |
1425 | up->port.membase = of_ioremap(rp, 0, up->reg_size, "su"); | 1437 | up->port.membase = of_ioremap(rp, 0, up->reg_size, "su"); |
1426 | if (!up->port.membase) | 1438 | if (!up->port.membase) { |
1439 | if (type != SU_PORT_PORT) | ||
1440 | kfree(up); | ||
1427 | return -ENOMEM; | 1441 | return -ENOMEM; |
1442 | } | ||
1428 | 1443 | ||
1429 | up->port.irq = op->irqs[0]; | 1444 | up->port.irq = op->irqs[0]; |
1430 | 1445 | ||
@@ -1436,8 +1451,11 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1436 | err = 0; | 1451 | err = 0; |
1437 | if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { | 1452 | if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { |
1438 | err = sunsu_kbd_ms_init(up); | 1453 | err = sunsu_kbd_ms_init(up); |
1439 | if (err) | 1454 | if (err) { |
1455 | kfree(up); | ||
1440 | goto out_unmap; | 1456 | goto out_unmap; |
1457 | } | ||
1458 | dev_set_drvdata(&op->dev, up); | ||
1441 | 1459 | ||
1442 | return 0; | 1460 | return 0; |
1443 | } | 1461 | } |
@@ -1476,8 +1494,12 @@ static int __devexit su_remove(struct of_device *dev) | |||
1476 | #ifdef CONFIG_SERIO | 1494 | #ifdef CONFIG_SERIO |
1477 | serio_unregister_port(&up->serio); | 1495 | serio_unregister_port(&up->serio); |
1478 | #endif | 1496 | #endif |
1479 | } else if (up->port.type != PORT_UNKNOWN) | 1497 | kfree(up); |
1498 | } else if (up->port.type != PORT_UNKNOWN) { | ||
1480 | uart_remove_one_port(&sunsu_reg, &up->port); | 1499 | uart_remove_one_port(&sunsu_reg, &up->port); |
1500 | } | ||
1501 | |||
1502 | dev_set_drvdata(&dev->dev, NULL); | ||
1481 | 1503 | ||
1482 | return 0; | 1504 | return 0; |
1483 | } | 1505 | } |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index a1456d9352cb..d34f336d53d8 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -68,9 +68,6 @@ static int num_sunzilog; | |||
68 | #define NUM_SUNZILOG num_sunzilog | 68 | #define NUM_SUNZILOG num_sunzilog |
69 | #define NUM_CHANNELS (NUM_SUNZILOG * 2) | 69 | #define NUM_CHANNELS (NUM_SUNZILOG * 2) |
70 | 70 | ||
71 | #define KEYBOARD_LINE 0x2 | ||
72 | #define MOUSE_LINE 0x3 | ||
73 | |||
74 | #define ZS_CLOCK 4915200 /* Zilog input clock rate. */ | 71 | #define ZS_CLOCK 4915200 /* Zilog input clock rate. */ |
75 | #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ | 72 | #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ |
76 | 73 | ||
@@ -1149,6 +1146,9 @@ static int __init sunzilog_console_setup(struct console *con, char *options) | |||
1149 | unsigned long flags; | 1146 | unsigned long flags; |
1150 | int baud, brg; | 1147 | int baud, brg; |
1151 | 1148 | ||
1149 | if (up->port.type != PORT_SUNZILOG) | ||
1150 | return -1; | ||
1151 | |||
1152 | printk(KERN_INFO "Console: ttyS%d (SunZilog zs%d)\n", | 1152 | printk(KERN_INFO "Console: ttyS%d (SunZilog zs%d)\n", |
1153 | (sunzilog_reg.minor - 64) + con->index, con->index); | 1153 | (sunzilog_reg.minor - 64) + con->index, con->index); |
1154 | 1154 | ||
@@ -1225,12 +1225,10 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe | |||
1225 | { | 1225 | { |
1226 | int baud, brg; | 1226 | int baud, brg; |
1227 | 1227 | ||
1228 | if (channel == KEYBOARD_LINE) { | 1228 | if (up->flags & SUNZILOG_FLAG_CONS_KEYB) { |
1229 | up->flags |= SUNZILOG_FLAG_CONS_KEYB; | ||
1230 | up->cflag = B1200 | CS8 | CLOCAL | CREAD; | 1229 | up->cflag = B1200 | CS8 | CLOCAL | CREAD; |
1231 | baud = 1200; | 1230 | baud = 1200; |
1232 | } else { | 1231 | } else { |
1233 | up->flags |= SUNZILOG_FLAG_CONS_MOUSE; | ||
1234 | up->cflag = B4800 | CS8 | CLOCAL | CREAD; | 1232 | up->cflag = B4800 | CS8 | CLOCAL | CREAD; |
1235 | baud = 4800; | 1233 | baud = 4800; |
1236 | } | 1234 | } |
@@ -1243,14 +1241,14 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe | |||
1243 | } | 1241 | } |
1244 | 1242 | ||
1245 | #ifdef CONFIG_SERIO | 1243 | #ifdef CONFIG_SERIO |
1246 | static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel) | 1244 | static void __init sunzilog_register_serio(struct uart_sunzilog_port *up) |
1247 | { | 1245 | { |
1248 | struct serio *serio = &up->serio; | 1246 | struct serio *serio = &up->serio; |
1249 | 1247 | ||
1250 | serio->port_data = up; | 1248 | serio->port_data = up; |
1251 | 1249 | ||
1252 | serio->id.type = SERIO_RS232; | 1250 | serio->id.type = SERIO_RS232; |
1253 | if (channel == KEYBOARD_LINE) { | 1251 | if (up->flags & SUNZILOG_FLAG_CONS_KEYB) { |
1254 | serio->id.proto = SERIO_SUNKBD; | 1252 | serio->id.proto = SERIO_SUNKBD; |
1255 | strlcpy(serio->name, "zskbd", sizeof(serio->name)); | 1253 | strlcpy(serio->name, "zskbd", sizeof(serio->name)); |
1256 | } else { | 1254 | } else { |
@@ -1259,7 +1257,8 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int ch | |||
1259 | strlcpy(serio->name, "zsms", sizeof(serio->name)); | 1257 | strlcpy(serio->name, "zsms", sizeof(serio->name)); |
1260 | } | 1258 | } |
1261 | strlcpy(serio->phys, | 1259 | strlcpy(serio->phys, |
1262 | (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"), | 1260 | ((up->flags & SUNZILOG_FLAG_CONS_KEYB) ? |
1261 | "zs/serio0" : "zs/serio1"), | ||
1263 | sizeof(serio->phys)); | 1262 | sizeof(serio->phys)); |
1264 | 1263 | ||
1265 | serio->write = sunzilog_serio_write; | 1264 | serio->write = sunzilog_serio_write; |
@@ -1286,8 +1285,8 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1286 | (void) read_zsreg(channel, R0); | 1285 | (void) read_zsreg(channel, R0); |
1287 | } | 1286 | } |
1288 | 1287 | ||
1289 | if (up->port.line == KEYBOARD_LINE || | 1288 | if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | |
1290 | up->port.line == MOUSE_LINE) { | 1289 | SUNZILOG_FLAG_CONS_MOUSE)) { |
1291 | sunzilog_init_kbdms(up, up->port.line); | 1290 | sunzilog_init_kbdms(up, up->port.line); |
1292 | up->curregs[R9] |= (NV | MIE); | 1291 | up->curregs[R9] |= (NV | MIE); |
1293 | write_zsreg(channel, R9, up->curregs[R9]); | 1292 | write_zsreg(channel, R9, up->curregs[R9]); |
@@ -1313,37 +1312,26 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1313 | spin_unlock_irqrestore(&up->port.lock, flags); | 1312 | spin_unlock_irqrestore(&up->port.lock, flags); |
1314 | 1313 | ||
1315 | #ifdef CONFIG_SERIO | 1314 | #ifdef CONFIG_SERIO |
1316 | if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE) | 1315 | if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | |
1317 | sunzilog_register_serio(up, up->port.line); | 1316 | SUNZILOG_FLAG_CONS_MOUSE)) |
1317 | sunzilog_register_serio(up); | ||
1318 | #endif | 1318 | #endif |
1319 | } | 1319 | } |
1320 | 1320 | ||
1321 | static int __devinit zs_get_instance(struct device_node *dp) | ||
1322 | { | ||
1323 | int ret; | ||
1324 | |||
1325 | ret = of_getintprop_default(dp, "slave", -1); | ||
1326 | if (ret != -1) | ||
1327 | return ret; | ||
1328 | |||
1329 | if (of_find_property(dp, "keyboard", NULL)) | ||
1330 | ret = 1; | ||
1331 | else | ||
1332 | ret = 0; | ||
1333 | |||
1334 | return ret; | ||
1335 | } | ||
1336 | |||
1337 | static int zilog_irq = -1; | 1321 | static int zilog_irq = -1; |
1338 | 1322 | ||
1339 | static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match) | 1323 | static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match) |
1340 | { | 1324 | { |
1341 | struct of_device *op = to_of_device(&dev->dev); | 1325 | static int inst; |
1342 | struct uart_sunzilog_port *up; | 1326 | struct uart_sunzilog_port *up; |
1343 | struct zilog_layout __iomem *rp; | 1327 | struct zilog_layout __iomem *rp; |
1344 | int inst = zs_get_instance(dev->node); | 1328 | int keyboard_mouse; |
1345 | int err; | 1329 | int err; |
1346 | 1330 | ||
1331 | keyboard_mouse = 0; | ||
1332 | if (of_find_property(op->node, "keyboard", NULL)) | ||
1333 | keyboard_mouse = 1; | ||
1334 | |||
1347 | sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, | 1335 | sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, |
1348 | sizeof(struct zilog_layout), | 1336 | sizeof(struct zilog_layout), |
1349 | "zs"); | 1337 | "zs"); |
@@ -1352,16 +1340,8 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * | |||
1352 | 1340 | ||
1353 | rp = sunzilog_chip_regs[inst]; | 1341 | rp = sunzilog_chip_regs[inst]; |
1354 | 1342 | ||
1355 | if (zilog_irq == -1) { | 1343 | if (zilog_irq == -1) |
1356 | zilog_irq = op->irqs[0]; | 1344 | zilog_irq = op->irqs[0]; |
1357 | err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, | ||
1358 | "zs", sunzilog_irq_chain); | ||
1359 | if (err) { | ||
1360 | of_iounmap(rp, sizeof(struct zilog_layout)); | ||
1361 | |||
1362 | return err; | ||
1363 | } | ||
1364 | } | ||
1365 | 1345 | ||
1366 | up = &sunzilog_port_table[inst * 2]; | 1346 | up = &sunzilog_port_table[inst * 2]; |
1367 | 1347 | ||
@@ -1378,7 +1358,7 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * | |||
1378 | up[0].port.line = (inst * 2) + 0; | 1358 | up[0].port.line = (inst * 2) + 0; |
1379 | up[0].port.dev = &op->dev; | 1359 | up[0].port.dev = &op->dev; |
1380 | up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; | 1360 | up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; |
1381 | if (inst == 1) | 1361 | if (keyboard_mouse) |
1382 | up[0].flags |= SUNZILOG_FLAG_CONS_KEYB; | 1362 | up[0].flags |= SUNZILOG_FLAG_CONS_KEYB; |
1383 | sunzilog_init_hw(&up[0]); | 1363 | sunzilog_init_hw(&up[0]); |
1384 | 1364 | ||
@@ -1395,11 +1375,11 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * | |||
1395 | up[1].port.line = (inst * 2) + 1; | 1375 | up[1].port.line = (inst * 2) + 1; |
1396 | up[1].port.dev = &op->dev; | 1376 | up[1].port.dev = &op->dev; |
1397 | up[1].flags |= 0; | 1377 | up[1].flags |= 0; |
1398 | if (inst == 1) | 1378 | if (keyboard_mouse) |
1399 | up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE; | 1379 | up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE; |
1400 | sunzilog_init_hw(&up[1]); | 1380 | sunzilog_init_hw(&up[1]); |
1401 | 1381 | ||
1402 | if (inst != 1) { | 1382 | if (!keyboard_mouse) { |
1403 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); | 1383 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); |
1404 | if (err) { | 1384 | if (err) { |
1405 | of_iounmap(rp, sizeof(struct zilog_layout)); | 1385 | of_iounmap(rp, sizeof(struct zilog_layout)); |
@@ -1411,9 +1391,18 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * | |||
1411 | of_iounmap(rp, sizeof(struct zilog_layout)); | 1391 | of_iounmap(rp, sizeof(struct zilog_layout)); |
1412 | return err; | 1392 | return err; |
1413 | } | 1393 | } |
1394 | } else { | ||
1395 | printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) " | ||
1396 | "is a zs\n", | ||
1397 | op->dev.bus_id, up[0].port.mapbase, op->irqs[0]); | ||
1398 | printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) " | ||
1399 | "is a zs\n", | ||
1400 | op->dev.bus_id, up[1].port.mapbase, op->irqs[0]); | ||
1414 | } | 1401 | } |
1415 | 1402 | ||
1416 | dev_set_drvdata(&dev->dev, &up[0]); | 1403 | dev_set_drvdata(&op->dev, &up[0]); |
1404 | |||
1405 | inst++; | ||
1417 | 1406 | ||
1418 | return 0; | 1407 | return 0; |
1419 | } | 1408 | } |
@@ -1462,36 +1451,65 @@ static struct of_platform_driver zs_driver = { | |||
1462 | static int __init sunzilog_init(void) | 1451 | static int __init sunzilog_init(void) |
1463 | { | 1452 | { |
1464 | struct device_node *dp; | 1453 | struct device_node *dp; |
1465 | int err; | 1454 | int err, uart_count; |
1455 | int num_keybms; | ||
1466 | 1456 | ||
1467 | NUM_SUNZILOG = 0; | 1457 | NUM_SUNZILOG = 0; |
1468 | for_each_node_by_name(dp, "zs") | 1458 | num_keybms = 0; |
1459 | for_each_node_by_name(dp, "zs") { | ||
1469 | NUM_SUNZILOG++; | 1460 | NUM_SUNZILOG++; |
1461 | if (of_find_property(dp, "keyboard", NULL)) | ||
1462 | num_keybms++; | ||
1463 | } | ||
1470 | 1464 | ||
1465 | uart_count = 0; | ||
1471 | if (NUM_SUNZILOG) { | 1466 | if (NUM_SUNZILOG) { |
1472 | int uart_count; | 1467 | int uart_count; |
1473 | 1468 | ||
1474 | err = sunzilog_alloc_tables(); | 1469 | err = sunzilog_alloc_tables(); |
1475 | if (err) | 1470 | if (err) |
1476 | return err; | 1471 | goto out; |
1477 | 1472 | ||
1478 | /* Subtract 1 for keyboard, 1 for mouse. */ | 1473 | uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms); |
1479 | uart_count = (NUM_SUNZILOG * 2) - 2; | ||
1480 | 1474 | ||
1481 | sunzilog_reg.nr = uart_count; | 1475 | sunzilog_reg.nr = uart_count; |
1482 | sunzilog_reg.minor = sunserial_current_minor; | 1476 | sunzilog_reg.minor = sunserial_current_minor; |
1483 | err = uart_register_driver(&sunzilog_reg); | 1477 | err = uart_register_driver(&sunzilog_reg); |
1484 | if (err) { | 1478 | if (err) |
1485 | sunzilog_free_tables(); | 1479 | goto out_free_tables; |
1486 | return err; | 1480 | |
1487 | } | ||
1488 | sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; | 1481 | sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; |
1489 | sunzilog_reg.cons = SUNZILOG_CONSOLE(); | 1482 | sunzilog_reg.cons = SUNZILOG_CONSOLE(); |
1490 | 1483 | ||
1491 | sunserial_current_minor += uart_count; | 1484 | sunserial_current_minor += uart_count; |
1492 | } | 1485 | } |
1493 | 1486 | ||
1494 | return of_register_driver(&zs_driver, &of_bus_type); | 1487 | err = of_register_driver(&zs_driver, &of_bus_type); |
1488 | if (err) | ||
1489 | goto out_unregister_uart; | ||
1490 | |||
1491 | if (zilog_irq != -1) { | ||
1492 | err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, | ||
1493 | "zs", sunzilog_irq_chain); | ||
1494 | if (err) | ||
1495 | goto out_unregister_driver; | ||
1496 | } | ||
1497 | |||
1498 | out: | ||
1499 | return err; | ||
1500 | |||
1501 | out_unregister_driver: | ||
1502 | of_unregister_driver(&zs_driver); | ||
1503 | |||
1504 | out_unregister_uart: | ||
1505 | if (NUM_SUNZILOG) { | ||
1506 | uart_unregister_driver(&sunzilog_reg); | ||
1507 | sunzilog_reg.cons = NULL; | ||
1508 | } | ||
1509 | |||
1510 | out_free_tables: | ||
1511 | sunzilog_free_tables(); | ||
1512 | goto out; | ||
1495 | } | 1513 | } |
1496 | 1514 | ||
1497 | static void __exit sunzilog_exit(void) | 1515 | static void __exit sunzilog_exit(void) |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index e93d0edc2e08..6c8b0ea83c3c 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -38,6 +38,7 @@ | |||
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> | ||
41 | #include <asm/vr41xx/siu.h> | 42 | #include <asm/vr41xx/siu.h> |
42 | #include <asm/vr41xx/vr41xx.h> | 43 | #include <asm/vr41xx/vr41xx.h> |
43 | 44 | ||