aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/8250.c25
-rw-r--r--drivers/serial/8250_pci.c31
-rw-r--r--drivers/serial/at91_serial.c5
-rw-r--r--drivers/serial/dz.c2
-rw-r--r--drivers/serial/ip22zilog.c3
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/serial_core.c4
-rw-r--r--drivers/serial/sh-sci.c4
-rw-r--r--drivers/serial/sunsab.c16
-rw-r--r--drivers/serial/sunsu.c40
-rw-r--r--drivers/serial/sunzilog.c128
-rw-r--r--drivers/serial/vr41xx_siu.c1
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
300static unsigned int serial_in(struct uart_8250_port *up, int offset) 300static 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
2271static int serial8250_console_setup(struct console *co, char *options) 2288static 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 */
461static unsigned short timedia_single_port[] = { 461static const unsigned short timedia_single_port[] = {
462 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 462 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0
463}; 463};
464 464
465static unsigned short timedia_dual_port[] = { 465static 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
473static unsigned short timedia_quad_port[] = { 473static 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
480static unsigned short timedia_eight_port[] = { 480static 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
485static const struct timedia_struct { 485static 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
496static int pci_timedia_init(struct pci_dev *dev) 495static 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
676static void dz_console_putchar(struct uart_port *port, int ch) 676static 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 = {
1621static int s3c2412_serial_probe(struct platform_device *dev) 1621static 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
1627static struct platform_driver s3c2412_serial_drv = { 1627static 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
1246static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel) 1244static 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
1321static 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
1337static int zilog_irq = -1; 1321static int zilog_irq = -1;
1338 1322
1339static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match) 1323static 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 = {
1462static int __init sunzilog_init(void) 1451static 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
1498out:
1499 return err;
1500
1501out_unregister_driver:
1502 of_unregister_driver(&zs_driver);
1503
1504out_unregister_uart:
1505 if (NUM_SUNZILOG) {
1506 uart_unregister_driver(&sunzilog_reg);
1507 sunzilog_reg.cons = NULL;
1508 }
1509
1510out_free_tables:
1511 sunzilog_free_tables();
1512 goto out;
1495} 1513}
1496 1514
1497static void __exit sunzilog_exit(void) 1515static 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