aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/serial/sunzilog.c785
1 files changed, 258 insertions, 527 deletions
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 9f42677287ad..cbdf9d605b3f 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1,5 +1,4 @@
1/* 1/* sunzilog.c: Zilog serial driver for Sparc systems.
2 * sunzilog.c
3 * 2 *
4 * Driver for Zilog serial chips found on Sun workstations and 3 * Driver for Zilog serial chips found on Sun workstations and
5 * servers. This driver could actually be made more generic. 4 * servers. This driver could actually be made more generic.
@@ -10,7 +9,7 @@
10 * 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
11 * work there. 10 * work there.
12 * 11 *
13 * Copyright (C) 2002 David S. Miller (davem@redhat.com) 12 * Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net)
14 */ 13 */
15 14
16#include <linux/config.h> 15#include <linux/config.h>
@@ -38,10 +37,8 @@
38 37
39#include <asm/io.h> 38#include <asm/io.h>
40#include <asm/irq.h> 39#include <asm/irq.h>
41#ifdef CONFIG_SPARC64 40#include <asm/prom.h>
42#include <asm/fhc.h> 41#include <asm/of_device.h>
43#endif
44#include <asm/sbus.h>
45 42
46#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 43#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
47#define SUPPORT_SYSRQ 44#define SUPPORT_SYSRQ
@@ -65,7 +62,7 @@
65#define ZSDELAY() 62#define ZSDELAY()
66#define ZSDELAY_LONG() 63#define ZSDELAY_LONG()
67#define ZS_WSYNC(__channel) \ 64#define ZS_WSYNC(__channel) \
68 sbus_readb(&((__channel)->control)) 65 readb(&((__channel)->control))
69#endif 66#endif
70 67
71static int num_sunzilog; 68static int num_sunzilog;
@@ -107,7 +104,7 @@ struct uart_sunzilog_port {
107 unsigned char prev_status; 104 unsigned char prev_status;
108 105
109#ifdef CONFIG_SERIO 106#ifdef CONFIG_SERIO
110 struct serio *serio; 107 struct serio serio;
111 int serio_open; 108 int serio_open;
112#endif 109#endif
113}; 110};
@@ -138,9 +135,9 @@ static unsigned char read_zsreg(struct zilog_channel __iomem *channel,
138{ 135{
139 unsigned char retval; 136 unsigned char retval;
140 137
141 sbus_writeb(reg, &channel->control); 138 writeb(reg, &channel->control);
142 ZSDELAY(); 139 ZSDELAY();
143 retval = sbus_readb(&channel->control); 140 retval = readb(&channel->control);
144 ZSDELAY(); 141 ZSDELAY();
145 142
146 return retval; 143 return retval;
@@ -149,9 +146,9 @@ static unsigned char read_zsreg(struct zilog_channel __iomem *channel,
149static void write_zsreg(struct zilog_channel __iomem *channel, 146static void write_zsreg(struct zilog_channel __iomem *channel,
150 unsigned char reg, unsigned char value) 147 unsigned char reg, unsigned char value)
151{ 148{
152 sbus_writeb(reg, &channel->control); 149 writeb(reg, &channel->control);
153 ZSDELAY(); 150 ZSDELAY();
154 sbus_writeb(value, &channel->control); 151 writeb(value, &channel->control);
155 ZSDELAY(); 152 ZSDELAY();
156} 153}
157 154
@@ -162,17 +159,17 @@ static void sunzilog_clear_fifo(struct zilog_channel __iomem *channel)
162 for (i = 0; i < 32; i++) { 159 for (i = 0; i < 32; i++) {
163 unsigned char regval; 160 unsigned char regval;
164 161
165 regval = sbus_readb(&channel->control); 162 regval = readb(&channel->control);
166 ZSDELAY(); 163 ZSDELAY();
167 if (regval & Rx_CH_AV) 164 if (regval & Rx_CH_AV)
168 break; 165 break;
169 166
170 regval = read_zsreg(channel, R1); 167 regval = read_zsreg(channel, R1);
171 sbus_readb(&channel->data); 168 readb(&channel->data);
172 ZSDELAY(); 169 ZSDELAY();
173 170
174 if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) { 171 if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) {
175 sbus_writeb(ERR_RES, &channel->control); 172 writeb(ERR_RES, &channel->control);
176 ZSDELAY(); 173 ZSDELAY();
177 ZS_WSYNC(channel); 174 ZS_WSYNC(channel);
178 } 175 }
@@ -194,7 +191,7 @@ static void __load_zsregs(struct zilog_channel __iomem *channel, unsigned char *
194 udelay(100); 191 udelay(100);
195 } 192 }
196 193
197 sbus_writeb(ERR_RES, &channel->control); 194 writeb(ERR_RES, &channel->control);
198 ZSDELAY(); 195 ZSDELAY();
199 ZS_WSYNC(channel); 196 ZS_WSYNC(channel);
200 197
@@ -291,7 +288,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
291 /* Stop-A is handled by drivers/char/keyboard.c now. */ 288 /* Stop-A is handled by drivers/char/keyboard.c now. */
292#ifdef CONFIG_SERIO 289#ifdef CONFIG_SERIO
293 if (up->serio_open) 290 if (up->serio_open)
294 serio_interrupt(up->serio, ch, 0, regs); 291 serio_interrupt(&up->serio, ch, 0, regs);
295#endif 292#endif
296 } else if (ZS_IS_MOUSE(up)) { 293 } else if (ZS_IS_MOUSE(up)) {
297 int ret = suncore_mouse_baud_detection(ch, is_break); 294 int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -306,7 +303,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
306 case 0: 303 case 0:
307#ifdef CONFIG_SERIO 304#ifdef CONFIG_SERIO
308 if (up->serio_open) 305 if (up->serio_open)
309 serio_interrupt(up->serio, ch, 0, regs); 306 serio_interrupt(&up->serio, ch, 0, regs);
310#endif 307#endif
311 break; 308 break;
312 }; 309 };
@@ -330,12 +327,12 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
330 327
331 r1 = read_zsreg(channel, R1); 328 r1 = read_zsreg(channel, R1);
332 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { 329 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
333 sbus_writeb(ERR_RES, &channel->control); 330 writeb(ERR_RES, &channel->control);
334 ZSDELAY(); 331 ZSDELAY();
335 ZS_WSYNC(channel); 332 ZS_WSYNC(channel);
336 } 333 }
337 334
338 ch = sbus_readb(&channel->control); 335 ch = readb(&channel->control);
339 ZSDELAY(); 336 ZSDELAY();
340 337
341 /* This funny hack depends upon BRK_ABRT not interfering 338 /* This funny hack depends upon BRK_ABRT not interfering
@@ -347,7 +344,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
347 if (!(ch & Rx_CH_AV)) 344 if (!(ch & Rx_CH_AV))
348 break; 345 break;
349 346
350 ch = sbus_readb(&channel->data); 347 ch = readb(&channel->data);
351 ZSDELAY(); 348 ZSDELAY();
352 349
353 ch &= up->parity_mask; 350 ch &= up->parity_mask;
@@ -406,10 +403,10 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up,
406{ 403{
407 unsigned char status; 404 unsigned char status;
408 405
409 status = sbus_readb(&channel->control); 406 status = readb(&channel->control);
410 ZSDELAY(); 407 ZSDELAY();
411 408
412 sbus_writeb(RES_EXT_INT, &channel->control); 409 writeb(RES_EXT_INT, &channel->control);
413 ZSDELAY(); 410 ZSDELAY();
414 ZS_WSYNC(channel); 411 ZS_WSYNC(channel);
415 412
@@ -421,7 +418,7 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up,
421 * confusing the PROM. 418 * confusing the PROM.
422 */ 419 */
423 while (1) { 420 while (1) {
424 status = sbus_readb(&channel->control); 421 status = readb(&channel->control);
425 ZSDELAY(); 422 ZSDELAY();
426 if (!(status & BRK_ABRT)) 423 if (!(status & BRK_ABRT))
427 break; 424 break;
@@ -458,7 +455,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
458 struct circ_buf *xmit; 455 struct circ_buf *xmit;
459 456
460 if (ZS_IS_CONS(up)) { 457 if (ZS_IS_CONS(up)) {
461 unsigned char status = sbus_readb(&channel->control); 458 unsigned char status = readb(&channel->control);
462 ZSDELAY(); 459 ZSDELAY();
463 460
464 /* TX still busy? Just wait for the next TX done interrupt. 461 /* TX still busy? Just wait for the next TX done interrupt.
@@ -487,7 +484,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
487 484
488 if (up->port.x_char) { 485 if (up->port.x_char) {
489 up->flags |= SUNZILOG_FLAG_TX_ACTIVE; 486 up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
490 sbus_writeb(up->port.x_char, &channel->data); 487 writeb(up->port.x_char, &channel->data);
491 ZSDELAY(); 488 ZSDELAY();
492 ZS_WSYNC(channel); 489 ZS_WSYNC(channel);
493 490
@@ -506,7 +503,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
506 goto ack_tx_int; 503 goto ack_tx_int;
507 504
508 up->flags |= SUNZILOG_FLAG_TX_ACTIVE; 505 up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
509 sbus_writeb(xmit->buf[xmit->tail], &channel->data); 506 writeb(xmit->buf[xmit->tail], &channel->data);
510 ZSDELAY(); 507 ZSDELAY();
511 ZS_WSYNC(channel); 508 ZS_WSYNC(channel);
512 509
@@ -519,7 +516,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
519 return; 516 return;
520 517
521ack_tx_int: 518ack_tx_int:
522 sbus_writeb(RES_Tx_P, &channel->control); 519 writeb(RES_Tx_P, &channel->control);
523 ZSDELAY(); 520 ZSDELAY();
524 ZS_WSYNC(channel); 521 ZS_WSYNC(channel);
525} 522}
@@ -540,7 +537,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
540 /* Channel A */ 537 /* Channel A */
541 tty = NULL; 538 tty = NULL;
542 if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { 539 if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
543 sbus_writeb(RES_H_IUS, &channel->control); 540 writeb(RES_H_IUS, &channel->control);
544 ZSDELAY(); 541 ZSDELAY();
545 ZS_WSYNC(channel); 542 ZS_WSYNC(channel);
546 543
@@ -563,7 +560,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
563 spin_lock(&up->port.lock); 560 spin_lock(&up->port.lock);
564 tty = NULL; 561 tty = NULL;
565 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { 562 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
566 sbus_writeb(RES_H_IUS, &channel->control); 563 writeb(RES_H_IUS, &channel->control);
567 ZSDELAY(); 564 ZSDELAY();
568 ZS_WSYNC(channel); 565 ZS_WSYNC(channel);
569 566
@@ -594,7 +591,7 @@ static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *p
594 unsigned char status; 591 unsigned char status;
595 592
596 channel = ZILOG_CHANNEL_FROM_PORT(port); 593 channel = ZILOG_CHANNEL_FROM_PORT(port);
597 status = sbus_readb(&channel->control); 594 status = readb(&channel->control);
598 ZSDELAY(); 595 ZSDELAY();
599 596
600 return status; 597 return status;
@@ -682,7 +679,7 @@ static void sunzilog_start_tx(struct uart_port *port)
682 up->flags |= SUNZILOG_FLAG_TX_ACTIVE; 679 up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
683 up->flags &= ~SUNZILOG_FLAG_TX_STOPPED; 680 up->flags &= ~SUNZILOG_FLAG_TX_STOPPED;
684 681
685 status = sbus_readb(&channel->control); 682 status = readb(&channel->control);
686 ZSDELAY(); 683 ZSDELAY();
687 684
688 /* TX busy? Just wait for the TX done interrupt. */ 685 /* TX busy? Just wait for the TX done interrupt. */
@@ -693,7 +690,7 @@ static void sunzilog_start_tx(struct uart_port *port)
693 * IRQ sending engine. 690 * IRQ sending engine.
694 */ 691 */
695 if (port->x_char) { 692 if (port->x_char) {
696 sbus_writeb(port->x_char, &channel->data); 693 writeb(port->x_char, &channel->data);
697 ZSDELAY(); 694 ZSDELAY();
698 ZS_WSYNC(channel); 695 ZS_WSYNC(channel);
699 696
@@ -702,7 +699,7 @@ static void sunzilog_start_tx(struct uart_port *port)
702 } else { 699 } else {
703 struct circ_buf *xmit = &port->info->xmit; 700 struct circ_buf *xmit = &port->info->xmit;
704 701
705 sbus_writeb(xmit->buf[xmit->tail], &channel->data); 702 writeb(xmit->buf[xmit->tail], &channel->data);
706 ZSDELAY(); 703 ZSDELAY();
707 ZS_WSYNC(channel); 704 ZS_WSYNC(channel);
708 705
@@ -779,7 +776,7 @@ static void __sunzilog_startup(struct uart_sunzilog_port *up)
779 struct zilog_channel __iomem *channel; 776 struct zilog_channel __iomem *channel;
780 777
781 channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 778 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
782 up->prev_status = sbus_readb(&channel->control); 779 up->prev_status = readb(&channel->control);
783 780
784 /* Enable receiver and transmitter. */ 781 /* Enable receiver and transmitter. */
785 up->curregs[R3] |= RxENAB; 782 up->curregs[R3] |= RxENAB;
@@ -963,7 +960,7 @@ sunzilog_set_termios(struct uart_port *port, struct termios *termios,
963 960
964static const char *sunzilog_type(struct uart_port *port) 961static const char *sunzilog_type(struct uart_port *port)
965{ 962{
966 return "SunZilog"; 963 return "zs";
967} 964}
968 965
969/* We do not request/release mappings of the registers here, this 966/* We do not request/release mappings of the registers here, this
@@ -1012,7 +1009,6 @@ static struct uart_sunzilog_port *sunzilog_port_table;
1012static struct zilog_layout __iomem **sunzilog_chip_regs; 1009static struct zilog_layout __iomem **sunzilog_chip_regs;
1013 1010
1014static struct uart_sunzilog_port *sunzilog_irq_chain; 1011static struct uart_sunzilog_port *sunzilog_irq_chain;
1015static int zilog_irq = -1;
1016 1012
1017static struct uart_driver sunzilog_reg = { 1013static struct uart_driver sunzilog_reg = {
1018 .owner = THIS_MODULE, 1014 .owner = THIS_MODULE,
@@ -1021,232 +1017,47 @@ static struct uart_driver sunzilog_reg = {
1021 .major = TTY_MAJOR, 1017 .major = TTY_MAJOR,
1022}; 1018};
1023 1019
1024static void * __init alloc_one_table(unsigned long size) 1020static int __init sunzilog_alloc_tables(void)
1025{ 1021{
1026 void *ret; 1022 struct uart_sunzilog_port *up;
1027 1023 unsigned long size;
1028 ret = kmalloc(size, GFP_KERNEL); 1024 int i;
1029 if (ret != NULL)
1030 memset(ret, 0, size);
1031 1025
1032 return ret; 1026 size = NUM_CHANNELS * sizeof(struct uart_sunzilog_port);
1033} 1027 sunzilog_port_table = kzalloc(size, GFP_KERNEL);
1028 if (!sunzilog_port_table)
1029 return -ENOMEM;
1034 1030
1035static void __init sunzilog_alloc_tables(void) 1031 for (i = 0; i < NUM_CHANNELS; i++) {
1036{ 1032 up = &sunzilog_port_table[i];
1037 sunzilog_port_table =
1038 alloc_one_table(NUM_CHANNELS * sizeof(struct uart_sunzilog_port));
1039 sunzilog_chip_regs =
1040 alloc_one_table(NUM_SUNZILOG * sizeof(struct zilog_layout __iomem *));
1041
1042 if (sunzilog_port_table == NULL || sunzilog_chip_regs == NULL) {
1043 prom_printf("SunZilog: Cannot allocate tables.\n");
1044 prom_halt();
1045 }
1046}
1047 1033
1048#ifdef CONFIG_SPARC64 1034 spin_lock_init(&up->port.lock);
1049 1035
1050/* We used to attempt to use the address property of the Zilog device node 1036 if (i == 0)
1051 * but that totally is not necessary on sparc64. 1037 sunzilog_irq_chain = up;
1052 */
1053static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
1054{
1055 void __iomem *mapped_addr;
1056 unsigned int sun4u_ino;
1057 struct sbus_bus *sbus = NULL;
1058 struct sbus_dev *sdev = NULL;
1059 int err;
1060 1038
1061 if (central_bus == NULL) { 1039 if (i < NUM_CHANNELS - 1)
1062 for_each_sbus(sbus) { 1040 up->next = up + 1;
1063 for_each_sbusdev(sdev, sbus) { 1041 else
1064 if (sdev->prom_node == zsnode) 1042 up->next = NULL;
1065 goto found;
1066 }
1067 }
1068 }
1069 found:
1070 if (sdev == NULL && central_bus == NULL) {
1071 prom_printf("SunZilog: sdev&&central == NULL for "
1072 "Zilog %d in get_zs_sun4u.\n", chip);
1073 prom_halt();
1074 }
1075 if (central_bus == NULL) {
1076 mapped_addr =
1077 sbus_ioremap(&sdev->resource[0], 0,
1078 PAGE_SIZE,
1079 "Zilog Registers");
1080 } else {
1081 struct linux_prom_registers zsregs[1];
1082
1083 err = prom_getproperty(zsnode, "reg",
1084 (char *) &zsregs[0],
1085 sizeof(zsregs));
1086 if (err == -1) {
1087 prom_printf("SunZilog: Cannot map "
1088 "Zilog %d regs on "
1089 "central bus.\n", chip);
1090 prom_halt();
1091 }
1092 apply_fhc_ranges(central_bus->child,
1093 &zsregs[0], 1);
1094 apply_central_ranges(central_bus, &zsregs[0], 1);
1095 mapped_addr = (void __iomem *)
1096 ((((u64)zsregs[0].which_io)<<32UL) |
1097 ((u64)zsregs[0].phys_addr));
1098 } 1043 }
1099 1044
1100 if (zilog_irq == -1) { 1045 size = NUM_SUNZILOG * sizeof(struct zilog_layout __iomem *);
1101 if (central_bus) { 1046 sunzilog_chip_regs = kzalloc(size, GFP_KERNEL);
1102 unsigned long iclr, imap; 1047 if (!sunzilog_chip_regs) {
1103 1048 kfree(sunzilog_port_table);
1104 iclr = central_bus->child->fhc_regs.uregs 1049 sunzilog_irq_chain = NULL;
1105 + FHC_UREGS_ICLR; 1050 return -ENOMEM;
1106 imap = central_bus->child->fhc_regs.uregs
1107 + FHC_UREGS_IMAP;
1108 zilog_irq = build_irq(0, iclr, imap);
1109 } else {
1110 err = prom_getproperty(zsnode, "interrupts",
1111 (char *) &sun4u_ino,
1112 sizeof(sun4u_ino));
1113 zilog_irq = sbus_build_irq(sbus_root, sun4u_ino);
1114 }
1115 } 1051 }
1116 1052
1117 return (struct zilog_layout __iomem *) mapped_addr; 1053 return 0;
1118} 1054}
1119#else /* CONFIG_SPARC64 */
1120 1055
1121/* 1056static void sunzilog_free_tables(void)
1122 * XXX The sun4d case is utterly screwed: it tries to re-walk the tree
1123 * (for the 3rd time) in order to find bootbus and cpu. Streamline it.
1124 */
1125static struct zilog_layout __iomem * __init get_zs_sun4cmd(int chip, int node)
1126{ 1057{
1127 struct linux_prom_irqs irq_info[2]; 1058 kfree(sunzilog_port_table);
1128 void __iomem *mapped_addr = NULL; 1059 sunzilog_irq_chain = NULL;
1129 int zsnode, cpunode, bbnode; 1060 kfree(sunzilog_chip_regs);
1130 struct linux_prom_registers zsreg[4];
1131 struct resource res;
1132
1133 if (sparc_cpu_model == sun4d) {
1134 int walk;
1135
1136 zsnode = 0;
1137 bbnode = 0;
1138 cpunode = 0;
1139 for (walk = prom_getchild(prom_root_node);
1140 (walk = prom_searchsiblings(walk, "cpu-unit")) != 0;
1141 walk = prom_getsibling(walk)) {
1142 bbnode = prom_getchild(walk);
1143 if (bbnode &&
1144 (bbnode = prom_searchsiblings(bbnode, "bootbus"))) {
1145 if ((zsnode = prom_getchild(bbnode)) == node) {
1146 cpunode = walk;
1147 break;
1148 }
1149 }
1150 }
1151 if (!walk) {
1152 prom_printf("SunZilog: Cannot find the %d'th bootbus on sun4d.\n",
1153 (chip / 2));
1154 prom_halt();
1155 }
1156
1157 if (prom_getproperty(zsnode, "reg",
1158 (char *) zsreg, sizeof(zsreg)) == -1) {
1159 prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
1160 prom_halt();
1161 }
1162 /* XXX Looks like an off by one? */
1163 prom_apply_generic_ranges(bbnode, cpunode, zsreg, 1);
1164 res.start = zsreg[0].phys_addr;
1165 res.end = res.start + (8 - 1);
1166 res.flags = zsreg[0].which_io | IORESOURCE_IO;
1167 mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
1168
1169 } else {
1170 zsnode = node;
1171
1172#if 0 /* XXX When was this used? */
1173 if (prom_getintdefault(zsnode, "slave", -1) != chipid) {
1174 zsnode = prom_getsibling(zsnode);
1175 continue;
1176 }
1177#endif
1178
1179 /*
1180 * "address" is only present on ports that OBP opened
1181 * (from Mitch Bradley's "Hitchhiker's Guide to OBP").
1182 * We do not use it.
1183 */
1184
1185 if (prom_getproperty(zsnode, "reg",
1186 (char *) zsreg, sizeof(zsreg)) == -1) {
1187 prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
1188 prom_halt();
1189 }
1190 if (sparc_cpu_model == sun4m) /* Crude. Pass parent. XXX */
1191 prom_apply_obio_ranges(zsreg, 1);
1192 res.start = zsreg[0].phys_addr;
1193 res.end = res.start + (8 - 1);
1194 res.flags = zsreg[0].which_io | IORESOURCE_IO;
1195 mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
1196 }
1197
1198 if (prom_getproperty(zsnode, "intr",
1199 (char *) irq_info, sizeof(irq_info))
1200 % sizeof(struct linux_prom_irqs)) {
1201 prom_printf("SunZilog: Cannot get IRQ property for Zilog %d.\n",
1202 chip);
1203 prom_halt();
1204 }
1205 if (zilog_irq == -1) {
1206 zilog_irq = irq_info[0].pri;
1207 } else if (zilog_irq != irq_info[0].pri) {
1208 /* XXX. Dumb. Should handle per-chip IRQ, for add-ons. */
1209 prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
1210 chip);
1211 prom_halt();
1212 }
1213
1214 return (struct zilog_layout __iomem *) mapped_addr;
1215}
1216#endif /* !(CONFIG_SPARC64) */
1217
1218/* Get the address of the registers for SunZilog instance CHIP. */
1219static struct zilog_layout __iomem * __init get_zs(int chip, int node)
1220{
1221 if (chip < 0 || chip >= NUM_SUNZILOG) {
1222 prom_printf("SunZilog: Illegal chip number %d in get_zs.\n", chip);
1223 prom_halt();
1224 }
1225
1226#ifdef CONFIG_SPARC64
1227 return get_zs_sun4u(chip, node);
1228#else
1229
1230 if (sparc_cpu_model == sun4) {
1231 struct resource res;
1232
1233 /* Not probe-able, hard code it. */
1234 switch (chip) {
1235 case 0:
1236 res.start = 0xf1000000;
1237 break;
1238 case 1:
1239 res.start = 0xf0000000;
1240 break;
1241 };
1242 zilog_irq = 12;
1243 res.end = (res.start + (8 - 1));
1244 res.flags = IORESOURCE_IO;
1245 return sbus_ioremap(&res, 0, 8, "SunZilog");
1246 }
1247
1248 return get_zs_sun4cmd(chip, node);
1249#endif
1250} 1061}
1251 1062
1252#define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */ 1063#define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */
@@ -1260,7 +1071,7 @@ static void sunzilog_putchar(struct uart_port *port, int ch)
1260 * udelay with ZSDELAY as that is a NOP on some platforms. -DaveM 1071 * udelay with ZSDELAY as that is a NOP on some platforms. -DaveM
1261 */ 1072 */
1262 do { 1073 do {
1263 unsigned char val = sbus_readb(&channel->control); 1074 unsigned char val = readb(&channel->control);
1264 if (val & Tx_BUF_EMP) { 1075 if (val & Tx_BUF_EMP) {
1265 ZSDELAY(); 1076 ZSDELAY();
1266 break; 1077 break;
@@ -1268,7 +1079,7 @@ static void sunzilog_putchar(struct uart_port *port, int ch)
1268 udelay(5); 1079 udelay(5);
1269 } while (--loops); 1080 } while (--loops);
1270 1081
1271 sbus_writeb(ch, &channel->data); 1082 writeb(ch, &channel->data);
1272 ZSDELAY(); 1083 ZSDELAY();
1273 ZS_WSYNC(channel); 1084 ZS_WSYNC(channel);
1274} 1085}
@@ -1385,28 +1196,6 @@ static struct console sunzilog_console = {
1385 .data = &sunzilog_reg, 1196 .data = &sunzilog_reg,
1386}; 1197};
1387 1198
1388static int __init sunzilog_console_init(void)
1389{
1390 int i;
1391
1392 if (con_is_present())
1393 return 0;
1394
1395 for (i = 0; i < NUM_CHANNELS; i++) {
1396 int this_minor = sunzilog_reg.minor + i;
1397
1398 if ((this_minor - 64) == (serial_console - 1))
1399 break;
1400 }
1401 if (i == NUM_CHANNELS)
1402 return 0;
1403
1404 sunzilog_console.index = i;
1405 sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS;
1406 register_console(&sunzilog_console);
1407 return 0;
1408}
1409
1410static inline struct console *SUNZILOG_CONSOLE(void) 1199static inline struct console *SUNZILOG_CONSOLE(void)
1411{ 1200{
1412 int i; 1201 int i;
@@ -1431,101 +1220,8 @@ static inline struct console *SUNZILOG_CONSOLE(void)
1431 1220
1432#else 1221#else
1433#define SUNZILOG_CONSOLE() (NULL) 1222#define SUNZILOG_CONSOLE() (NULL)
1434#define sunzilog_console_init() do { } while (0)
1435#endif 1223#endif
1436 1224
1437/*
1438 * We scan the PROM tree recursively. This is the most reliable way
1439 * to find Zilog nodes on various platforms. However, we face an extreme
1440 * shortage of kernel stack, so we must be very careful. To that end,
1441 * we scan only to a certain depth, and we use a common property buffer
1442 * in the scan structure.
1443 */
1444#define ZS_PROPSIZE 128
1445#define ZS_SCAN_DEPTH 5
1446
1447struct zs_probe_scan {
1448 int depth;
1449 void (*scanner)(struct zs_probe_scan *t, int node);
1450
1451 int devices;
1452 char prop[ZS_PROPSIZE];
1453};
1454
1455static int __inline__ sunzilog_node_ok(int node, const char *name, int len)
1456{
1457 if (strncmp(name, "zs", len) == 0)
1458 return 1;
1459 /* Don't fold this procedure just yet. Compare to su_node_ok(). */
1460 return 0;
1461}
1462
1463static void __init sunzilog_scan(struct zs_probe_scan *t, int node)
1464{
1465 int len;
1466
1467 for (; node != 0; node = prom_getsibling(node)) {
1468 len = prom_getproperty(node, "name", t->prop, ZS_PROPSIZE);
1469 if (len <= 1)
1470 continue; /* Broken PROM node */
1471 if (sunzilog_node_ok(node, t->prop, len)) {
1472 (*t->scanner)(t, node);
1473 } else {
1474 if (t->depth < ZS_SCAN_DEPTH) {
1475 t->depth++;
1476 sunzilog_scan(t, prom_getchild(node));
1477 --t->depth;
1478 }
1479 }
1480 }
1481}
1482
1483static void __init sunzilog_prepare(void)
1484{
1485 struct uart_sunzilog_port *up;
1486 struct zilog_layout __iomem *rp;
1487 int channel, chip;
1488
1489 /*
1490 * Temporary fix.
1491 */
1492 for (channel = 0; channel < NUM_CHANNELS; channel++)
1493 spin_lock_init(&sunzilog_port_table[channel].port.lock);
1494
1495 sunzilog_irq_chain = up = &sunzilog_port_table[0];
1496 for (channel = 0; channel < NUM_CHANNELS - 1; channel++)
1497 up[channel].next = &up[channel + 1];
1498 up[channel].next = NULL;
1499
1500 for (chip = 0; chip < NUM_SUNZILOG; chip++) {
1501 rp = sunzilog_chip_regs[chip];
1502 up[(chip * 2) + 0].port.membase = (void __iomem *)&rp->channelA;
1503 up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB;
1504
1505 /* Channel A */
1506 up[(chip * 2) + 0].port.iotype = UPIO_MEM;
1507 up[(chip * 2) + 0].port.irq = zilog_irq;
1508 up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
1509 up[(chip * 2) + 0].port.fifosize = 1;
1510 up[(chip * 2) + 0].port.ops = &sunzilog_pops;
1511 up[(chip * 2) + 0].port.type = PORT_SUNZILOG;
1512 up[(chip * 2) + 0].port.flags = 0;
1513 up[(chip * 2) + 0].port.line = (chip * 2) + 0;
1514 up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
1515
1516 /* Channel B */
1517 up[(chip * 2) + 1].port.iotype = UPIO_MEM;
1518 up[(chip * 2) + 1].port.irq = zilog_irq;
1519 up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
1520 up[(chip * 2) + 1].port.fifosize = 1;
1521 up[(chip * 2) + 1].port.ops = &sunzilog_pops;
1522 up[(chip * 2) + 1].port.type = PORT_SUNZILOG;
1523 up[(chip * 2) + 1].port.flags = 0;
1524 up[(chip * 2) + 1].port.line = (chip * 2) + 1;
1525 up[(chip * 2) + 1].flags |= 0;
1526 }
1527}
1528
1529static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel) 1225static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
1530{ 1226{
1531 int baud, brg; 1227 int baud, brg;
@@ -1539,8 +1235,6 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
1539 up->cflag = B4800 | CS8 | CLOCAL | CREAD; 1235 up->cflag = B4800 | CS8 | CLOCAL | CREAD;
1540 baud = 4800; 1236 baud = 4800;
1541 } 1237 }
1542 printk(KERN_INFO "zs%d at 0x%p (irq = %d) is a SunZilog\n",
1543 channel, up->port.membase, zilog_irq);
1544 1238
1545 up->curregs[R15] = BRKIE; 1239 up->curregs[R15] = BRKIE;
1546 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); 1240 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
@@ -1552,216 +1246,253 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
1552#ifdef CONFIG_SERIO 1246#ifdef CONFIG_SERIO
1553static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel) 1247static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel)
1554{ 1248{
1555 struct serio *serio; 1249 struct serio *serio = &up->serio;
1556
1557 up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
1558 if (serio) {
1559 memset(serio, 0, sizeof(*serio));
1560 1250
1561 serio->port_data = up; 1251 serio->port_data = up;
1562 1252
1563 serio->id.type = SERIO_RS232; 1253 serio->id.type = SERIO_RS232;
1564 if (channel == KEYBOARD_LINE) { 1254 if (channel == KEYBOARD_LINE) {
1565 serio->id.proto = SERIO_SUNKBD; 1255 serio->id.proto = SERIO_SUNKBD;
1566 strlcpy(serio->name, "zskbd", sizeof(serio->name)); 1256 strlcpy(serio->name, "zskbd", sizeof(serio->name));
1567 } else {
1568 serio->id.proto = SERIO_SUN;
1569 serio->id.extra = 1;
1570 strlcpy(serio->name, "zsms", sizeof(serio->name));
1571 }
1572 strlcpy(serio->phys,
1573 (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
1574 sizeof(serio->phys));
1575
1576 serio->write = sunzilog_serio_write;
1577 serio->open = sunzilog_serio_open;
1578 serio->close = sunzilog_serio_close;
1579
1580 serio_register_port(serio);
1581 } else { 1257 } else {
1582 printk(KERN_WARNING "zs%d: not enough memory for serio port\n", 1258 serio->id.proto = SERIO_SUN;
1583 channel); 1259 serio->id.extra = 1;
1260 strlcpy(serio->name, "zsms", sizeof(serio->name));
1584 } 1261 }
1262 strlcpy(serio->phys,
1263 (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
1264 sizeof(serio->phys));
1265
1266 serio->write = sunzilog_serio_write;
1267 serio->open = sunzilog_serio_open;
1268 serio->close = sunzilog_serio_close;
1269 serio->dev.parent = up->port.dev;
1270
1271 serio_register_port(serio);
1585} 1272}
1586#endif 1273#endif
1587 1274
1588static void __init sunzilog_init_hw(void) 1275static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
1589{ 1276{
1590 int i; 1277 struct zilog_channel __iomem *channel;
1591 1278 unsigned long flags;
1592 for (i = 0; i < NUM_CHANNELS; i++) { 1279 int baud, brg;
1593 struct uart_sunzilog_port *up = &sunzilog_port_table[i];
1594 struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
1595 unsigned long flags;
1596 int baud, brg;
1597 1280
1598 spin_lock_irqsave(&up->port.lock, flags); 1281 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
1599 1282
1600 if (ZS_IS_CHANNEL_A(up)) { 1283 spin_lock_irqsave(&up->port.lock, flags);
1601 write_zsreg(channel, R9, FHWRES); 1284 if (ZS_IS_CHANNEL_A(up)) {
1602 ZSDELAY_LONG(); 1285 write_zsreg(channel, R9, FHWRES);
1603 (void) read_zsreg(channel, R0); 1286 ZSDELAY_LONG();
1604 } 1287 (void) read_zsreg(channel, R0);
1288 }
1605 1289
1606 if (i == KEYBOARD_LINE || i == MOUSE_LINE) { 1290 if (up->port.line == KEYBOARD_LINE ||
1607 sunzilog_init_kbdms(up, i); 1291 up->port.line == MOUSE_LINE) {
1608 up->curregs[R9] |= (NV | MIE); 1292 sunzilog_init_kbdms(up, up->port.line);
1609 write_zsreg(channel, R9, up->curregs[R9]); 1293 up->curregs[R9] |= (NV | MIE);
1610 } else { 1294 write_zsreg(channel, R9, up->curregs[R9]);
1611 /* Normal serial TTY. */ 1295 } else {
1612 up->parity_mask = 0xff; 1296 /* Normal serial TTY. */
1613 up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB; 1297 up->parity_mask = 0xff;
1614 up->curregs[R4] = PAR_EVEN | X16CLK | SB1; 1298 up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
1615 up->curregs[R3] = RxENAB | Rx8; 1299 up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
1616 up->curregs[R5] = TxENAB | Tx8; 1300 up->curregs[R3] = RxENAB | Rx8;
1617 up->curregs[R9] = NV | MIE; 1301 up->curregs[R5] = TxENAB | Tx8;
1618 up->curregs[R10] = NRZ; 1302 up->curregs[R9] = NV | MIE;
1619 up->curregs[R11] = TCBR | RCBR; 1303 up->curregs[R10] = NRZ;
1620 baud = 9600; 1304 up->curregs[R11] = TCBR | RCBR;
1621 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); 1305 baud = 9600;
1622 up->curregs[R12] = (brg & 0xff); 1306 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
1623 up->curregs[R13] = (brg >> 8) & 0xff; 1307 up->curregs[R12] = (brg & 0xff);
1624 up->curregs[R14] = BRSRC | BRENAB; 1308 up->curregs[R13] = (brg >> 8) & 0xff;
1625 __load_zsregs(channel, up->curregs); 1309 up->curregs[R14] = BRSRC | BRENAB;
1626 write_zsreg(channel, R9, up->curregs[R9]); 1310 __load_zsregs(channel, up->curregs);
1627 } 1311 write_zsreg(channel, R9, up->curregs[R9]);
1312 }
1628 1313
1629 spin_unlock_irqrestore(&up->port.lock, flags); 1314 spin_unlock_irqrestore(&up->port.lock, flags);
1630 1315
1631#ifdef CONFIG_SERIO 1316#ifdef CONFIG_SERIO
1632 if (i == KEYBOARD_LINE || i == MOUSE_LINE) 1317 if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE)
1633 sunzilog_register_serio(up, i); 1318 sunzilog_register_serio(up, up->port.line);
1634#endif 1319#endif
1635 }
1636}
1637
1638static struct zilog_layout __iomem * __init get_zs(int chip, int node);
1639
1640static void __init sunzilog_scan_probe(struct zs_probe_scan *t, int node)
1641{
1642 sunzilog_chip_regs[t->devices] = get_zs(t->devices, node);
1643 t->devices++;
1644} 1320}
1645 1321
1646static int __init sunzilog_ports_init(void) 1322static int __devinit zs_get_instance(struct device_node *dp)
1647{ 1323{
1648 struct zs_probe_scan scan;
1649 int ret; 1324 int ret;
1650 int uart_count;
1651 int i;
1652 1325
1653 printk(KERN_DEBUG "SunZilog: %d chips.\n", NUM_SUNZILOG); 1326 ret = of_getintprop_default(dp, "slave", -1);
1327 if (ret != -1)
1328 return ret;
1654 1329
1655 scan.scanner = sunzilog_scan_probe; 1330 if (of_find_property(dp, "keyboard", NULL))
1656 scan.depth = 0; 1331 ret = 1;
1657 scan.devices = 0; 1332 else
1658 sunzilog_scan(&scan, prom_getchild(prom_root_node)); 1333 ret = 0;
1659 1334
1660 sunzilog_prepare(); 1335 return ret;
1336}
1661 1337
1662 if (request_irq(zilog_irq, sunzilog_interrupt, SA_SHIRQ, 1338static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match)
1663 "SunZilog", sunzilog_irq_chain)) { 1339{
1664 prom_printf("SunZilog: Unable to register zs interrupt handler.\n"); 1340 static int zilog_irq = -1;
1665 prom_halt(); 1341 struct of_device *op = to_of_device(&dev->dev);
1666 } 1342 struct uart_sunzilog_port *up;
1343 struct zilog_layout __iomem *rp;
1344 int inst = zs_get_instance(dev->node);
1345 int err;
1667 1346
1668 sunzilog_init_hw(); 1347 sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
1348 sizeof(struct zilog_layout),
1349 "zs");
1350 if (!sunzilog_chip_regs[inst])
1351 return -ENOMEM;
1669 1352
1670 /* We can only init this once we have probed the Zilogs 1353 rp = sunzilog_chip_regs[inst];
1671 * in the system. Do not count channels assigned to keyboards
1672 * or mice when we are deciding how many ports to register.
1673 */
1674 uart_count = 0;
1675 for (i = 0; i < NUM_CHANNELS; i++) {
1676 struct uart_sunzilog_port *up = &sunzilog_port_table[i];
1677 1354
1678 if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) 1355 if (zilog_irq == -1) {
1679 continue; 1356 zilog_irq = op->irqs[0];
1357 err = request_irq(zilog_irq, sunzilog_interrupt, SA_SHIRQ,
1358 "zs", sunzilog_irq_chain);
1359 if (err) {
1360 of_iounmap(rp, sizeof(struct zilog_layout));
1680 1361
1681 uart_count++; 1362 return err;
1363 }
1682 } 1364 }
1683
1684 sunzilog_reg.nr = uart_count;
1685 sunzilog_reg.minor = sunserial_current_minor;
1686
1687 ret = uart_register_driver(&sunzilog_reg);
1688 if (ret == 0) {
1689 sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
1690 sunzilog_reg.cons = SUNZILOG_CONSOLE();
1691 1365
1692 sunserial_current_minor += uart_count; 1366 up = &sunzilog_port_table[inst * 2];
1693 1367
1694 for (i = 0; i < NUM_CHANNELS; i++) { 1368 /* Channel A */
1695 struct uart_sunzilog_port *up = &sunzilog_port_table[i]; 1369 up[0].port.mapbase = op->resource[0].start + 0x00;
1696 1370 up[0].port.membase = (void __iomem *) &rp->channelA;
1697 if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) 1371 up[0].port.iotype = UPIO_MEM;
1698 continue; 1372 up[0].port.irq = op->irqs[0];
1699 1373 up[0].port.uartclk = ZS_CLOCK;
1700 if (uart_add_one_port(&sunzilog_reg, &up->port)) { 1374 up[0].port.fifosize = 1;
1701 printk(KERN_ERR 1375 up[0].port.ops = &sunzilog_pops;
1702 "SunZilog: failed to add port zs%d\n", i); 1376 up[0].port.type = PORT_SUNZILOG;
1703 } 1377 up[0].port.flags = 0;
1378 up[0].port.line = (inst * 2) + 0;
1379 up[0].port.dev = &op->dev;
1380 up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
1381 if (inst == 1)
1382 up[0].flags |= SUNZILOG_FLAG_CONS_KEYB;
1383 sunzilog_init_hw(&up[0]);
1384
1385 /* Channel B */
1386 up[1].port.mapbase = op->resource[0].start + 0x04;
1387 up[1].port.membase = (void __iomem *) &rp->channelB;
1388 up[1].port.iotype = UPIO_MEM;
1389 up[1].port.irq = op->irqs[0];
1390 up[1].port.uartclk = ZS_CLOCK;
1391 up[1].port.fifosize = 1;
1392 up[1].port.ops = &sunzilog_pops;
1393 up[1].port.type = PORT_SUNZILOG;
1394 up[1].port.flags = 0;
1395 up[1].port.line = (inst * 2) + 1;
1396 up[1].port.dev = &op->dev;
1397 up[1].flags |= 0;
1398 if (inst == 1)
1399 up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE;
1400 sunzilog_init_hw(&up[1]);
1401
1402 if (inst != 1) {
1403 err = uart_add_one_port(&sunzilog_reg, &up[0].port);
1404 if (err) {
1405 of_iounmap(rp, sizeof(struct zilog_layout));
1406 return err;
1407 }
1408 err = uart_add_one_port(&sunzilog_reg, &up[1].port);
1409 if (err) {
1410 uart_remove_one_port(&sunzilog_reg, &up[0].port);
1411 of_iounmap(rp, sizeof(struct zilog_layout));
1412 return err;
1704 } 1413 }
1705 } 1414 }
1706 1415
1707 return ret; 1416 return 0;
1708}
1709
1710static void __init sunzilog_scan_count(struct zs_probe_scan *t, int node)
1711{
1712 t->devices++;
1713} 1417}
1714 1418
1715static int __init sunzilog_ports_count(void) 1419static int __devexit zs_remove(struct of_device *dev)
1716{ 1420{
1717 struct zs_probe_scan scan; 1421 struct uart_sunzilog_port *up = dev_get_drvdata(&dev->dev);
1422 struct zilog_channel __iomem *channel;
1718 1423
1719 /* Sun4 Zilog setup is hard coded, no probing to do. */ 1424 if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
1720 if (sparc_cpu_model == sun4) 1425#ifdef CONFIG_SERIO
1721 return 2; 1426 serio_unregister_port(&up->serio);
1427#endif
1428 } else
1429 uart_remove_one_port(&sunzilog_reg, &up->port);
1722 1430
1723 scan.scanner = sunzilog_scan_count; 1431 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
1724 scan.depth = 0;
1725 scan.devices = 0;
1726 1432
1727 sunzilog_scan(&scan, prom_getchild(prom_root_node)); 1433 of_iounmap(channel, sizeof(struct zilog_channel));
1728 1434
1729 return scan.devices; 1435 return 0;
1730} 1436}
1731 1437
1438static struct of_device_id zs_match[] = {
1439 {
1440 .name = "zs",
1441 },
1442 {},
1443};
1444MODULE_DEVICE_TABLE(of, zs_match);
1445
1446static struct of_platform_driver zs_driver = {
1447 .name = "zs",
1448 .match_table = zs_match,
1449 .probe = zs_probe,
1450 .remove = __devexit_p(zs_remove),
1451};
1452
1732static int __init sunzilog_init(void) 1453static int __init sunzilog_init(void)
1733{ 1454{
1455 struct device_node *dp;
1456 int err;
1734 1457
1735 NUM_SUNZILOG = sunzilog_ports_count(); 1458 NUM_SUNZILOG = 0;
1736 if (NUM_SUNZILOG == 0) 1459 for_each_node_by_name(dp, "zs")
1737 return -ENODEV; 1460 NUM_SUNZILOG++;
1738 1461
1739 sunzilog_alloc_tables(); 1462 if (NUM_SUNZILOG) {
1463 int uart_count;
1740 1464
1741 sunzilog_ports_init(); 1465 err = sunzilog_alloc_tables();
1466 if (err)
1467 return err;
1742 1468
1743 return 0; 1469 /* Subtract 1 for keyboard, 1 for mouse. */
1470 uart_count = (NUM_SUNZILOG * 2) - 2;
1471
1472 sunzilog_reg.nr = uart_count;
1473 sunzilog_reg.minor = sunserial_current_minor;
1474 err = uart_register_driver(&sunzilog_reg);
1475 if (err) {
1476 sunzilog_free_tables();
1477 return err;
1478 }
1479 sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
1480 sunzilog_reg.cons = SUNZILOG_CONSOLE();
1481
1482 sunserial_current_minor += uart_count;
1483 }
1484
1485 return of_register_driver(&zs_driver, &of_bus_type);
1744} 1486}
1745 1487
1746static void __exit sunzilog_exit(void) 1488static void __exit sunzilog_exit(void)
1747{ 1489{
1748 int i; 1490 of_unregister_driver(&zs_driver);
1749 1491
1750 for (i = 0; i < NUM_CHANNELS; i++) { 1492 if (NUM_SUNZILOG) {
1751 struct uart_sunzilog_port *up = &sunzilog_port_table[i]; 1493 uart_unregister_driver(&sunzilog_reg);
1752 1494 sunzilog_free_tables();
1753 if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
1754#ifdef CONFIG_SERIO
1755 if (up->serio) {
1756 serio_unregister_port(up->serio);
1757 up->serio = NULL;
1758 }
1759#endif
1760 } else
1761 uart_remove_one_port(&sunzilog_reg, &up->port);
1762 } 1495 }
1763
1764 uart_unregister_driver(&sunzilog_reg);
1765} 1496}
1766 1497
1767module_init(sunzilog_init); 1498module_init(sunzilog_init);