aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-08-30 18:30:38 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-08-30 18:30:38 -0400
commit0a7d5f8ce960e74fa22986bda4af488539796e49 (patch)
treee29ad17808a5c3410518e22dae8dfe94801b59f3 /drivers/serial
parent0165508c80a2b5d5268d9c5dfa9b30c534a33693 (diff)
parentdc709bd190c130b299ac19d596594256265c042a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/8250.c25
-rw-r--r--drivers/serial/8250_pci.c14
-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/serial_core.c1
-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
10 files changed, 159 insertions, 76 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..cd1979daf2b8 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -936,6 +936,7 @@ enum pci_board_num_t {
936 pbn_b1_8_1382400, 936 pbn_b1_8_1382400,
937 937
938 pbn_b2_1_115200, 938 pbn_b2_1_115200,
939 pbn_b2_2_115200,
939 pbn_b2_8_115200, 940 pbn_b2_8_115200,
940 941
941 pbn_b2_1_460800, 942 pbn_b2_1_460800,
@@ -1243,6 +1244,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
1243 .base_baud = 115200, 1244 .base_baud = 115200,
1244 .uart_offset = 8, 1245 .uart_offset = 8,
1245 }, 1246 },
1247 [pbn_b2_2_115200] = {
1248 .flags = FL_BASE2,
1249 .num_ports = 2,
1250 .base_baud = 115200,
1251 .uart_offset = 8,
1252 },
1246 [pbn_b2_8_115200] = { 1253 [pbn_b2_8_115200] = {
1247 .flags = FL_BASE2, 1254 .flags = FL_BASE2,
1248 .num_ports = 8, 1255 .num_ports = 8,
@@ -2340,6 +2347,13 @@ static struct pci_device_id serial_pci_tbl[] = {
2340 pbn_b0_1_115200 }, 2347 pbn_b0_1_115200 },
2341 2348
2342 /* 2349 /*
2350 * IntaShield IS-200
2351 */
2352 { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200,
2353 PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */
2354 pbn_b2_2_115200 },
2355
2356 /*
2343 * These entries match devices with class COMMUNICATION_SERIAL, 2357 * These entries match devices with class COMMUNICATION_SERIAL,
2344 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL 2358 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
2345 */ 2359 */
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/serial_core.c b/drivers/serial/serial_core.c
index d5f636fbf29a..80ef7d482756 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;
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