aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2008-02-07 03:15:15 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 11:42:24 -0500
commite6ee512f5a77553a6fe08cad68b75d5fdfd2ffb8 (patch)
tree09949c61810dd2824937a0f626fa4ff3e24fe881 /drivers/serial
parentf5519caad5c1828b2ab6d14bd9e7a8e047db12e3 (diff)
dz.c: Resource management
This is a set of changes to implement proper resource management in the driver, including iomem space reservation and operating on physical addresses ioremap()ped appropriately using accessory functions rather than unportable direct assignments. Some adjustments to code are made to reflect the architecture of the interface, which is a centrally controlled multiport (or, as referred to from DEC documentation, a serial line multiplexer, going up to 8 lines originally) rather than a bundle of separate ports. Types are changed, where applicable, to specify the width of hardware registers explicitly. The interrupt handler is now managed in the ->startup() and ->shutdown() calls for consistency with other drivers and also in preparation to handle the handover from the initial firmware-based console gracefully. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/dz.c289
1 files changed, 188 insertions, 101 deletions
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index c054c1bd8b24..116211fcd36f 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -39,6 +39,7 @@
39#include <linux/errno.h> 39#include <linux/errno.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/ioport.h>
42#include <linux/kernel.h> 43#include <linux/kernel.h>
43#include <linux/major.h> 44#include <linux/major.h>
44#include <linux/module.h> 45#include <linux/module.h>
@@ -47,7 +48,9 @@
47#include <linux/sysrq.h> 48#include <linux/sysrq.h>
48#include <linux/tty.h> 49#include <linux/tty.h>
49 50
51#include <asm/atomic.h>
50#include <asm/bootinfo.h> 52#include <asm/bootinfo.h>
53#include <asm/io.h>
51#include <asm/system.h> 54#include <asm/system.h>
52 55
53#include <asm/dec/interrupts.h> 56#include <asm/dec/interrupts.h>
@@ -55,18 +58,32 @@
55#include <asm/dec/kn02.h> 58#include <asm/dec/kn02.h>
56#include <asm/dec/machtype.h> 59#include <asm/dec/machtype.h>
57#include <asm/dec/prom.h> 60#include <asm/dec/prom.h>
61#include <asm/dec/system.h>
58 62
59#include "dz.h" 63#include "dz.h"
60 64
61static char *dz_name = "DECstation DZ serial driver version "; 65
62static char *dz_version = "1.03"; 66MODULE_DESCRIPTION("DECstation DZ serial driver");
67MODULE_LICENSE("GPL");
68
69
70static char dz_name[] __initdata = "DECstation DZ serial driver version ";
71static char dz_version[] __initdata = "1.04";
63 72
64struct dz_port { 73struct dz_port {
74 struct dz_mux *mux;
65 struct uart_port port; 75 struct uart_port port;
66 unsigned int cflag; 76 unsigned int cflag;
67}; 77};
68 78
69static struct dz_port dz_ports[DZ_NB_PORT]; 79struct dz_mux {
80 struct dz_port dport[DZ_NB_PORT];
81 atomic_t map_guard;
82 atomic_t irq_guard;
83 int initialised;
84};
85
86static struct dz_mux dz_mux;
70 87
71static inline struct dz_port *to_dport(struct uart_port *uport) 88static inline struct dz_port *to_dport(struct uart_port *uport)
72{ 89{
@@ -82,21 +99,18 @@ static inline struct dz_port *to_dport(struct uart_port *uport)
82 * ------------------------------------------------------------ 99 * ------------------------------------------------------------
83 */ 100 */
84 101
85static inline unsigned short dz_in(struct dz_port *dport, unsigned offset) 102static u16 dz_in(struct dz_port *dport, unsigned offset)
86{ 103{
87 volatile unsigned short *addr = 104 void __iomem *addr = dport->port.membase + offset;
88 (volatile unsigned short *) (dport->port.membase + offset);
89 105
90 return *addr; 106 return readw(addr);
91} 107}
92 108
93static inline void dz_out(struct dz_port *dport, unsigned offset, 109static void dz_out(struct dz_port *dport, unsigned offset, u16 value)
94 unsigned short value)
95{ 110{
96 volatile unsigned short *addr = 111 void __iomem *addr = dport->port.membase + offset;
97 (volatile unsigned short *) (dport->port.membase + offset);
98 112
99 *addr = value; 113 writew(value, addr);
100} 114}
101 115
102/* 116/*
@@ -112,7 +126,7 @@ static inline void dz_out(struct dz_port *dport, unsigned offset,
112static void dz_stop_tx(struct uart_port *uport) 126static void dz_stop_tx(struct uart_port *uport)
113{ 127{
114 struct dz_port *dport = to_dport(uport); 128 struct dz_port *dport = to_dport(uport);
115 unsigned short tmp, mask = 1 << dport->port.line; 129 u16 tmp, mask = 1 << dport->port.line;
116 130
117 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */ 131 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */
118 tmp &= ~mask; /* clear the TX flag */ 132 tmp &= ~mask; /* clear the TX flag */
@@ -122,7 +136,7 @@ static void dz_stop_tx(struct uart_port *uport)
122static void dz_start_tx(struct uart_port *uport) 136static void dz_start_tx(struct uart_port *uport)
123{ 137{
124 struct dz_port *dport = to_dport(uport); 138 struct dz_port *dport = to_dport(uport);
125 unsigned short tmp, mask = 1 << dport->port.line; 139 u16 tmp, mask = 1 << dport->port.line;
126 140
127 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */ 141 tmp = dz_in(dport, DZ_TCR); /* read the TX flag */
128 tmp |= mask; /* set the TX flag */ 142 tmp |= mask; /* set the TX flag */
@@ -137,7 +151,7 @@ static void dz_stop_rx(struct uart_port *uport)
137 dz_out(dport, DZ_LPR, dport->cflag); 151 dz_out(dport, DZ_LPR, dport->cflag);
138} 152}
139 153
140static void dz_enable_ms(struct uart_port *port) 154static void dz_enable_ms(struct uart_port *uport)
141{ 155{
142 /* nothing to do */ 156 /* nothing to do */
143} 157}
@@ -169,19 +183,19 @@ static void dz_enable_ms(struct uart_port *port)
169 * This routine deals with inputs from any lines. 183 * This routine deals with inputs from any lines.
170 * ------------------------------------------------------------ 184 * ------------------------------------------------------------
171 */ 185 */
172static inline void dz_receive_chars(struct dz_port *dport_in) 186static inline void dz_receive_chars(struct dz_mux *mux)
173{ 187{
174 struct uart_port *uport; 188 struct uart_port *uport;
175 struct dz_port *dport; 189 struct dz_port *dport = &mux->dport[0];
176 struct tty_struct *tty = NULL; 190 struct tty_struct *tty = NULL;
177 struct uart_icount *icount; 191 struct uart_icount *icount;
178 int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; 192 int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 };
179 unsigned short status;
180 unsigned char ch, flag; 193 unsigned char ch, flag;
194 u16 status;
181 int i; 195 int i;
182 196
183 while ((status = dz_in(dport_in, DZ_RBUF)) & DZ_DVAL) { 197 while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) {
184 dport = &dz_ports[LINE(status)]; 198 dport = &mux->dport[LINE(status)];
185 uport = &dport->port; 199 uport = &dport->port;
186 tty = uport->info->tty; /* point to the proper dev */ 200 tty = uport->info->tty; /* point to the proper dev */
187 201
@@ -235,7 +249,7 @@ static inline void dz_receive_chars(struct dz_port *dport_in)
235 } 249 }
236 for (i = 0; i < DZ_NB_PORT; i++) 250 for (i = 0; i < DZ_NB_PORT; i++)
237 if (lines_rx[i]) 251 if (lines_rx[i])
238 tty_flip_buffer_push(dz_ports[i].port.info->tty); 252 tty_flip_buffer_push(mux->dport[i].port.info->tty);
239} 253}
240 254
241/* 255/*
@@ -245,15 +259,15 @@ static inline void dz_receive_chars(struct dz_port *dport_in)
245 * This routine deals with outputs to any lines. 259 * This routine deals with outputs to any lines.
246 * ------------------------------------------------------------ 260 * ------------------------------------------------------------
247 */ 261 */
248static inline void dz_transmit_chars(struct dz_port *dport_in) 262static inline void dz_transmit_chars(struct dz_mux *mux)
249{ 263{
250 struct dz_port *dport; 264 struct dz_port *dport = &mux->dport[0];
251 struct circ_buf *xmit; 265 struct circ_buf *xmit;
252 unsigned short status;
253 unsigned char tmp; 266 unsigned char tmp;
267 u16 status;
254 268
255 status = dz_in(dport_in, DZ_CSR); 269 status = dz_in(dport, DZ_CSR);
256 dport = &dz_ports[LINE(status)]; 270 dport = &mux->dport[LINE(status)];
257 xmit = &dport->port.info->xmit; 271 xmit = &dport->port.info->xmit;
258 272
259 if (dport->port.x_char) { /* XON/XOFF chars */ 273 if (dport->port.x_char) { /* XON/XOFF chars */
@@ -305,7 +319,7 @@ static inline void check_modem_status(struct dz_port *dport)
305 * 1. No status change interrupt; use a timer. 319 * 1. No status change interrupt; use a timer.
306 * 2. Handle the 3100/5000 as appropriate. --macro 320 * 2. Handle the 3100/5000 as appropriate. --macro
307 */ 321 */
308 unsigned short status; 322 u16 status;
309 323
310 /* If not the modem line just return. */ 324 /* If not the modem line just return. */
311 if (dport->port.line != DZ_MODEM) 325 if (dport->port.line != DZ_MODEM)
@@ -326,19 +340,20 @@ static inline void check_modem_status(struct dz_port *dport)
326 * It deals with the multiple ports. 340 * It deals with the multiple ports.
327 * ------------------------------------------------------------ 341 * ------------------------------------------------------------
328 */ 342 */
329static irqreturn_t dz_interrupt(int irq, void *dev) 343static irqreturn_t dz_interrupt(int irq, void *dev_id)
330{ 344{
331 struct dz_port *dport = dev; 345 struct dz_mux *mux = dev_id;
332 unsigned short status; 346 struct dz_port *dport = &mux->dport[0];
347 u16 status;
333 348
334 /* get the reason why we just got an irq */ 349 /* get the reason why we just got an irq */
335 status = dz_in(dport, DZ_CSR); 350 status = dz_in(dport, DZ_CSR);
336 351
337 if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE)) 352 if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE))
338 dz_receive_chars(dport); 353 dz_receive_chars(mux);
339 354
340 if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE)) 355 if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE))
341 dz_transmit_chars(dport); 356 dz_transmit_chars(mux);
342 357
343 return IRQ_HANDLED; 358 return IRQ_HANDLED;
344} 359}
@@ -371,7 +386,7 @@ static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
371 * FIXME: Handle the 3100/5000 as appropriate. --macro 386 * FIXME: Handle the 3100/5000 as appropriate. --macro
372 */ 387 */
373 struct dz_port *dport = to_dport(uport); 388 struct dz_port *dport = to_dport(uport);
374 unsigned short tmp; 389 u16 tmp;
375 390
376 if (dport->port.line == DZ_MODEM) { 391 if (dport->port.line == DZ_MODEM) {
377 tmp = dz_in(dport, DZ_TCR); 392 tmp = dz_in(dport, DZ_TCR);
@@ -393,14 +408,29 @@ static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
393static int dz_startup(struct uart_port *uport) 408static int dz_startup(struct uart_port *uport)
394{ 409{
395 struct dz_port *dport = to_dport(uport); 410 struct dz_port *dport = to_dport(uport);
411 struct dz_mux *mux = dport->mux;
396 unsigned long flags; 412 unsigned long flags;
397 unsigned short tmp; 413 int irq_guard;
414 int ret;
415 u16 tmp;
416
417 irq_guard = atomic_add_return(1, &mux->irq_guard);
418 if (irq_guard != 1)
419 return 0;
420
421 ret = request_irq(dport->port.irq, dz_interrupt,
422 IRQF_SHARED, "dz", mux);
423 if (ret) {
424 atomic_add(-1, &mux->irq_guard);
425 printk(KERN_ERR "dz: Cannot get IRQ %d!\n", dport->port.irq);
426 return ret;
427 }
398 428
399 spin_lock_irqsave(&dport->port.lock, flags); 429 spin_lock_irqsave(&dport->port.lock, flags);
400 430
401 /* enable the interrupt and the scanning */ 431 /* Enable interrupts. */
402 tmp = dz_in(dport, DZ_CSR); 432 tmp = dz_in(dport, DZ_CSR);
403 tmp |= DZ_RIE | DZ_TIE | DZ_MSE; 433 tmp |= DZ_RIE | DZ_TIE;
404 dz_out(dport, DZ_CSR, tmp); 434 dz_out(dport, DZ_CSR, tmp);
405 435
406 spin_unlock_irqrestore(&dport->port.lock, flags); 436 spin_unlock_irqrestore(&dport->port.lock, flags);
@@ -419,11 +449,24 @@ static int dz_startup(struct uart_port *uport)
419static void dz_shutdown(struct uart_port *uport) 449static void dz_shutdown(struct uart_port *uport)
420{ 450{
421 struct dz_port *dport = to_dport(uport); 451 struct dz_port *dport = to_dport(uport);
452 struct dz_mux *mux = dport->mux;
422 unsigned long flags; 453 unsigned long flags;
454 int irq_guard;
455 u16 tmp;
423 456
424 spin_lock_irqsave(&dport->port.lock, flags); 457 spin_lock_irqsave(&dport->port.lock, flags);
425 dz_stop_tx(&dport->port); 458 dz_stop_tx(&dport->port);
426 spin_unlock_irqrestore(&dport->port.lock, flags); 459 spin_unlock_irqrestore(&dport->port.lock, flags);
460
461 irq_guard = atomic_add_return(-1, &mux->irq_guard);
462 if (!irq_guard) {
463 /* Disable interrupts. */
464 tmp = dz_in(dport, DZ_CSR);
465 tmp &= ~(DZ_RIE | DZ_TIE);
466 dz_out(dport, DZ_CSR, tmp);
467
468 free_irq(dport->port.irq, mux);
469 }
427} 470}
428 471
429/* 472/*
@@ -507,6 +550,24 @@ static int dz_encode_baud_rate(unsigned int baud)
507 } 550 }
508} 551}
509 552
553
554static void dz_reset(struct dz_port *dport)
555{
556 struct dz_mux *mux = dport->mux;
557
558 if (mux->initialised)
559 return;
560
561 dz_out(dport, DZ_CSR, DZ_CLR);
562 while (dz_in(dport, DZ_CSR) & DZ_CLR);
563 iob();
564
565 /* Enable scanning. */
566 dz_out(dport, DZ_CSR, DZ_MSE);
567
568 mux->initialised = 1;
569}
570
510static void dz_set_termios(struct uart_port *uport, struct ktermios *termios, 571static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
511 struct ktermios *old_termios) 572 struct ktermios *old_termios)
512{ 573{
@@ -581,36 +642,86 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
581 spin_unlock_irqrestore(&dport->port.lock, flags); 642 spin_unlock_irqrestore(&dport->port.lock, flags);
582} 643}
583 644
584static const char *dz_type(struct uart_port *port) 645static const char *dz_type(struct uart_port *uport)
585{ 646{
586 return "DZ"; 647 return "DZ";
587} 648}
588 649
589static void dz_release_port(struct uart_port *port) 650static void dz_release_port(struct uart_port *uport)
590{ 651{
591 /* nothing to do */ 652 struct dz_mux *mux = to_dport(uport)->mux;
653 int map_guard;
654
655 iounmap(uport->membase);
656 uport->membase = NULL;
657
658 map_guard = atomic_add_return(-1, &mux->map_guard);
659 if (!map_guard)
660 release_mem_region(uport->mapbase, dec_kn_slot_size);
592} 661}
593 662
594static int dz_request_port(struct uart_port *port) 663static int dz_map_port(struct uart_port *uport)
595{ 664{
665 if (!uport->membase)
666 uport->membase = ioremap_nocache(uport->mapbase,
667 dec_kn_slot_size);
668 if (!uport->membase) {
669 printk(KERN_ERR "dz: Cannot map MMIO\n");
670 return -ENOMEM;
671 }
596 return 0; 672 return 0;
597} 673}
598 674
599static void dz_config_port(struct uart_port *port, int flags) 675static int dz_request_port(struct uart_port *uport)
600{ 676{
601 if (flags & UART_CONFIG_TYPE) 677 struct dz_mux *mux = to_dport(uport)->mux;
602 port->type = PORT_DZ; 678 int map_guard;
679 int ret;
680
681 map_guard = atomic_add_return(1, &mux->map_guard);
682 if (map_guard == 1) {
683 if (!request_mem_region(uport->mapbase, dec_kn_slot_size,
684 "dz")) {
685 atomic_add(-1, &mux->map_guard);
686 printk(KERN_ERR
687 "dz: Unable to reserve MMIO resource\n");
688 return -EBUSY;
689 }
690 }
691 ret = dz_map_port(uport);
692 if (ret) {
693 map_guard = atomic_add_return(-1, &mux->map_guard);
694 if (!map_guard)
695 release_mem_region(uport->mapbase, dec_kn_slot_size);
696 return ret;
697 }
698 return 0;
699}
700
701static void dz_config_port(struct uart_port *uport, int flags)
702{
703 struct dz_port *dport = to_dport(uport);
704
705 if (flags & UART_CONFIG_TYPE) {
706 if (dz_request_port(uport))
707 return;
708
709 uport->type = PORT_DZ;
710
711 dz_reset(dport);
712 }
603} 713}
604 714
605/* 715/*
606 * verify the new serial_struct (for TIOCSSERIAL). 716 * Verify the new serial_struct (for TIOCSSERIAL).
607 */ 717 */
608static int dz_verify_port(struct uart_port *port, struct serial_struct *ser) 718static int dz_verify_port(struct uart_port *uport, struct serial_struct *ser)
609{ 719{
610 int ret = 0; 720 int ret = 0;
721
611 if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ) 722 if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ)
612 ret = -EINVAL; 723 ret = -EINVAL;
613 if (ser->irq != port->irq) 724 if (ser->irq != uport->irq)
614 ret = -EINVAL; 725 ret = -EINVAL;
615 return ret; 726 return ret;
616} 727}
@@ -637,40 +748,32 @@ static struct uart_ops dz_ops = {
637static void __init dz_init_ports(void) 748static void __init dz_init_ports(void)
638{ 749{
639 static int first = 1; 750 static int first = 1;
640 struct dz_port *dport;
641 unsigned long base; 751 unsigned long base;
642 int i; 752 int line;
643 753
644 if (!first) 754 if (!first)
645 return; 755 return;
646 first = 0; 756 first = 0;
647 757
648 if (mips_machtype == MACH_DS23100 || 758 if (mips_machtype == MACH_DS23100 || mips_machtype == MACH_DS5100)
649 mips_machtype == MACH_DS5100) 759 base = dec_kn_slot_base + KN01_DZ11;
650 base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11);
651 else 760 else
652 base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11); 761 base = dec_kn_slot_base + KN02_DZ11;
653
654 for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
655 spin_lock_init(&dport->port.lock);
656 dport->port.membase = (char *) base;
657 dport->port.iotype = UPIO_MEM;
658 dport->port.irq = dec_interrupt[DEC_IRQ_DZ11];
659 dport->port.line = i;
660 dport->port.fifosize = 1;
661 dport->port.ops = &dz_ops;
662 dport->port.flags = UPF_BOOT_AUTOCONF;
663 }
664}
665 762
666static void dz_reset(struct dz_port *dport) 763 for (line = 0; line < DZ_NB_PORT; line++) {
667{ 764 struct dz_port *dport = &dz_mux.dport[line];
668 dz_out(dport, DZ_CSR, DZ_CLR); 765 struct uart_port *uport = &dport->port;
669 while (dz_in(dport, DZ_CSR) & DZ_CLR);
670 iob();
671 766
672 /* enable scanning */ 767 dport->mux = &dz_mux;
673 dz_out(dport, DZ_CSR, DZ_MSE); 768
769 uport->irq = dec_interrupt[DEC_IRQ_DZ11];
770 uport->fifosize = 1;
771 uport->iotype = UPIO_MEM;
772 uport->flags = UPF_BOOT_AUTOCONF;
773 uport->ops = &dz_ops;
774 uport->line = line;
775 uport->mapbase = base;
776 }
674} 777}
675 778
676#ifdef CONFIG_SERIAL_DZ_CONSOLE 779#ifdef CONFIG_SERIAL_DZ_CONSOLE
@@ -737,7 +840,7 @@ static void dz_console_print(struct console *co,
737 const char *str, 840 const char *str,
738 unsigned int count) 841 unsigned int count)
739{ 842{
740 struct dz_port *dport = &dz_ports[co->index]; 843 struct dz_port *dport = &dz_mux.dport[co->index];
741#ifdef DEBUG_DZ 844#ifdef DEBUG_DZ
742 prom_printf((char *) str); 845 prom_printf((char *) str);
743#endif 846#endif
@@ -746,17 +849,23 @@ static void dz_console_print(struct console *co,
746 849
747static int __init dz_console_setup(struct console *co, char *options) 850static int __init dz_console_setup(struct console *co, char *options)
748{ 851{
749 struct dz_port *dport = &dz_ports[co->index]; 852 struct dz_port *dport = &dz_mux.dport[co->index];
853 struct uart_port *uport = &dport->port;
750 int baud = 9600; 854 int baud = 9600;
751 int bits = 8; 855 int bits = 8;
752 int parity = 'n'; 856 int parity = 'n';
753 int flow = 'n'; 857 int flow = 'n';
858 int ret;
754 859
755 if (options) 860 ret = dz_map_port(uport);
756 uart_parse_options(options, &baud, &parity, &bits, &flow); 861 if (ret)
862 return ret;
757 863
758 dz_reset(dport); 864 dz_reset(dport);
759 865
866 if (options)
867 uart_parse_options(options, &baud, &parity, &bits, &flow);
868
760 return uart_set_options(&dport->port, co, baud, parity, bits, flow); 869 return uart_set_options(&dport->port, co, baud, parity, bits, flow);
761} 870}
762 871
@@ -809,36 +918,14 @@ static int __init dz_init(void)
809 918
810 dz_init_ports(); 919 dz_init_ports();
811 920
812#ifndef CONFIG_SERIAL_DZ_CONSOLE
813 /* reset the chip */
814 dz_reset(&dz_ports[0]);
815#endif
816
817 ret = uart_register_driver(&dz_reg); 921 ret = uart_register_driver(&dz_reg);
818 if (ret != 0) 922 if (ret)
819 goto out; 923 return ret;
820
821 ret = request_irq(dz_ports[0].port.irq, dz_interrupt, IRQF_DISABLED,
822 "DZ", &dz_ports[0]);
823 if (ret != 0) {
824 printk(KERN_ERR "dz: Cannot get IRQ %d!\n",
825 dz_ports[0].port.irq);
826 goto out_unregister;
827 }
828 924
829 for (i = 0; i < DZ_NB_PORT; i++) 925 for (i = 0; i < DZ_NB_PORT; i++)
830 uart_add_one_port(&dz_reg, &dz_ports[i].port); 926 uart_add_one_port(&dz_reg, &dz_mux.dport[i].port);
831
832 return ret;
833 927
834out_unregister: 928 return 0;
835 uart_unregister_driver(&dz_reg);
836
837out:
838 return ret;
839} 929}
840 930
841module_init(dz_init); 931module_init(dz_init);
842
843MODULE_DESCRIPTION("DECstation DZ serial driver");
844MODULE_LICENSE("GPL");