2 * drivers/serial/ubi32_serdes.c
3 * Ubicom32 On-Chip Serial Driver
5 * (C) Copyright 2009, Ubicom, Inc.
7 * This file is part of the Ubicom32 Linux Kernel Port.
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
23 * Ubicom32 implementation derived from (with many thanks):
28 #include <linux/module.h>
29 #include <linux/ioport.h>
30 #include <linux/init.h>
31 #include <linux/console.h>
32 #include <linux/sysrq.h>
33 #include <linux/platform_device.h>
34 #include <linux/tty.h>
35 #include <linux/tty_flip.h>
36 #include <linux/serial_core.h>
38 #include <asm/ip5000.h>
39 #include <asm/ubicom32suart.h>
42 #define SERIAL_UBICOM_PIN_RXD (1 << 0)
43 #define SERIAL_UBICOM_PIN_TXD (1 << 6)
44 #define SERIAL_UBICOM_CTL0 0x8b300000
45 #define SERIAL_UBICOM_CTL1 0x00000009
47 #define SERIAL_UBICOM_DATA_BIT 8 /* Fixed parameter - do not change */
48 #define SERIAL_UBICOM_PAR_BIT 0 /* Fixed parameter - do not change */
49 #define SERIAL_UBICOM_STOP_BIT 1 /* Fixed parameter - do not change */
51 /* UART name and device definitions */
52 #define UBI32_SERDES_NAME "ttyUS" // XXX
53 #define UBI32_SERDES_MAJOR 206 // XXX
54 #define UBI32_SERDES_MINOR 64 // XXX
56 #define PORT_UBI32_SERDES 1234
59 struct uart_port ubi32_serdes_ports
[NR_PORTS
];
61 struct ubi32_serdes_resource
{
65 } ubi32_serdes_resource
[NR_PORTS
] = {
67 * Get params from kernel command line (required for early printk)
68 * or from platform resources.
74 * Can get overridden by 'serdes=' kernel command line.
76 static int ubi32_serdes_default_baud_rate
= 115200;
79 #define IO_PORT(port) ((struct ubicom32_io_port *)port->membase)
80 #define IO_PORT_INT_STATUS(port) (IO_PORT(port)->int_status)
81 #define IO_PORT_INT_MASK(port) (IO_PORT(port)->int_mask)
82 #define IO_PORT_INT_CLR(port) (IO_PORT(port)->int_clr)
86 * ubi32_serdes_get_char()
88 static u8_t
ubi32_serdes_get_char(struct ubicom32_io_port
*io_port
)
91 * Read from hardware (forced 32-bit atomic read).
96 io_port
->int_clr
= IO_PORTX_INT_SERDES_RXBF
;
100 : "m" (*(u32_t
*)&(io_port
->rx_fifo
))
104 return (u8_t
)(data
& 0x000000ff);
108 * ubi32_serdes_put_char()
110 static void ubi32_serdes_put_char(struct ubicom32_io_port
*io_port
, u8_t c
)
112 u32_t data
= 0x0000fe00 | (c
<< 1);
117 * [LSB]1 start bit - 8 data bits - no parity - 1 stop bit[MSB]
119 io_port
->int_clr
= IO_PORTX_INT_SERDES_TXBE
;
120 io_port
->ctl2
= data
;
121 io_port
->int_set
= IO_PORTX_INT_SERDES_TXBUF_VALID
;
125 static void ubi32_serdes_hw_init(struct uart_port
*port
, int baud
)
127 struct ubicom32_io_port
*io_port
= IO_PORT(port
);
131 * Put port functions 1-4 into reset state.
132 * Function 0 (GPIO) does not need or have a reset bit.
134 * Select SERDES function for restart below.
137 IO_FUNC_FUNCTION_RESET(1) | IO_FUNC_FUNCTION_RESET(2) |
138 IO_FUNC_FUNCTION_RESET(3) | IO_FUNC_FUNCTION_RESET(4) |
139 IO_PORTX_FUNC_SERDES
;
142 * Configure SERDES baudrate
145 baud
= ubi32_serdes_default_baud_rate
;
150 ((port
->uartclk
/ (16 * baud
)) - 1);
156 * don't interrupt until startup and start_tx
158 io_port
->int_mask
= 0;
161 * Set TXD pin output, RXD input and prevent GPIO
162 * override on the TXD & RXD pins
164 io_port
->gpio_ctl
&= ~SERIAL_UBICOM_PIN_RXD
;
165 io_port
->gpio_ctl
|= SERIAL_UBICOM_PIN_TXD
;
166 io_port
->gpio_mask
&= ~(SERIAL_UBICOM_PIN_RXD
| SERIAL_UBICOM_PIN_TXD
);
169 * Restart (un-reset) the port's SERDES function.
171 io_port
->function
&= ~(IO_FUNC_FUNCTION_RESET(IO_PORTX_FUNC_SERDES
));
175 #define ULITE_STATUS_RXVALID IO_PORTX_INT_SERDES_RXBF
176 #define ULITE_STATUS_OVERRUN 0
177 #define ULITE_STATUS_FRAME 0
178 #define ULITE_STATUS_PARITY 0
179 #define ULITE_STATUS_TXEMPTY IO_PORTX_INT_SERDES_TXBE
180 #define ULITE_STATUS_TXFULL 0
182 static int ubi32_serdes_receive(struct uart_port
*port
, int stat
)
184 struct tty_struct
*tty
= port
->info
->port
.tty
;
185 unsigned char ch
= 0;
186 char flag
= TTY_NORMAL
;
188 if ((stat
& (ULITE_STATUS_RXVALID
| ULITE_STATUS_OVERRUN
189 | ULITE_STATUS_FRAME
)) == 0)
193 if (stat
& ULITE_STATUS_RXVALID
) {
195 ch
= ubi32_serdes_get_char((struct ubicom32_io_port
*)port
->membase
);
197 if (stat
& ULITE_STATUS_PARITY
)
198 port
->icount
.parity
++;
201 if (stat
& ULITE_STATUS_OVERRUN
)
202 port
->icount
.overrun
++;
204 if (stat
& ULITE_STATUS_FRAME
)
205 port
->icount
.frame
++;
208 /* drop byte with parity error if IGNPAR specificed */
209 if (stat
& port
->ignore_status_mask
& ULITE_STATUS_PARITY
)
210 stat
&= ~ULITE_STATUS_RXVALID
;
212 stat
&= port
->read_status_mask
;
214 if (stat
& ULITE_STATUS_PARITY
)
217 stat
&= ~port
->ignore_status_mask
;
219 if (stat
& ULITE_STATUS_RXVALID
)
220 tty_insert_flip_char(tty
, ch
, flag
);
222 if (stat
& ULITE_STATUS_FRAME
)
223 tty_insert_flip_char(tty
, 0, TTY_FRAME
);
225 if (stat
& ULITE_STATUS_OVERRUN
)
226 tty_insert_flip_char(tty
, 0, TTY_OVERRUN
);
232 * interrupts are disabled on entry
234 static void ubi32_serdes_stop_tx(struct uart_port
*port
)
236 IO_PORT_INT_MASK(port
) = IO_PORT_INT_MASK(port
) & ~IO_PORTX_INT_SERDES_TXBE
;
239 static int ubi32_serdes_transmit(struct uart_port
*port
, int stat
)
241 struct circ_buf
*xmit
= &port
->info
->xmit
;
243 if (!(stat
& IO_PORTX_INT_SERDES_TXBE
))
247 ubi32_serdes_put_char(IO_PORT(port
), port
->x_char
);
253 if (uart_circ_empty(xmit
) || uart_tx_stopped(port
)) {
254 ubi32_serdes_stop_tx(port
);
258 ubi32_serdes_put_char(IO_PORT(port
), xmit
->buf
[xmit
->tail
]);
259 xmit
->tail
= (xmit
->tail
+ 1) & (UART_XMIT_SIZE
-1);
263 if (uart_circ_chars_pending(xmit
) < WAKEUP_CHARS
)
264 uart_write_wakeup(port
);
266 if (uart_circ_empty(xmit
))
267 ubi32_serdes_stop_tx(port
);
273 * port is locked and interrupts are disabled
275 static void ubi32_serdes_start_tx(struct uart_port
*port
)
277 IO_PORT_INT_MASK(port
) = IO_PORT_INT_MASK(port
) | IO_PORTX_INT_SERDES_TXBE
;
278 ubi32_serdes_transmit(port
, IO_PORT_INT_STATUS(port
));
282 * Interrupts are enabled
284 static void ubi32_serdes_stop_rx(struct uart_port
*port
)
286 /* don't forward any more data (like !CREAD) */
287 port
->ignore_status_mask
= IO_PORTX_INT_SERDES_RXBF
;
291 * Set the modem control timer to fire immediately.
293 static void ubi32_serdes_enable_ms(struct uart_port
*port
)
298 static irqreturn_t
ubi32_serdes_isr(int irq
, void *dev_id
)
300 struct uart_port
*port
= dev_id
;
303 spin_lock(&port
->lock
);
306 int stat
= IO_PORT_INT_STATUS(port
);
307 busy
= ubi32_serdes_receive(port
, stat
);
308 busy
|= ubi32_serdes_transmit(port
, stat
);
311 tty_flip_buffer_push(port
->info
->port
.tty
);
313 spin_unlock(&port
->lock
);
319 * Return TIOCSER_TEMT when transmitter is not busy.
321 static unsigned int ubi32_serdes_tx_empty(struct uart_port
*port
)
326 spin_lock_irqsave(&port
->lock
, flags
);
327 ret
= IO_PORT_INT_STATUS(port
);
328 spin_unlock_irqrestore(&port
->lock
, flags
);
330 return ret
& ULITE_STATUS_TXEMPTY
? TIOCSER_TEMT
: 0;
333 static unsigned int ubi32_serdes_get_mctrl(struct uart_port
*port
)
335 return TIOCM_CTS
| TIOCM_DSR
| TIOCM_CAR
;
338 static void ubi32_serdes_set_mctrl(struct uart_port
*port
, unsigned int mctrl
)
344 * Interrupts are always disabled.
346 static void ubi32_serdes_break_ctl(struct uart_port
*port
, int break_state
)
351 static int ubi32_serdes_startup(struct uart_port
*port
)
353 if (request_irq(port
->irq
, ubi32_serdes_isr
, IRQF_DISABLED
,
354 "UBI32_SERDES", port
)) {
355 printk(KERN_NOTICE
"Unable to attach port interrupt\n");
359 IO_PORT_INT_CLR(port
) = IO_PORTX_INT_SERDES_RXBF
;
360 IO_PORT_INT_MASK(port
) = IO_PORTX_INT_SERDES_RXBF
;
364 static void ubi32_serdes_shutdown(struct uart_port
*port
)
366 struct ubi32_serdes_port
*uart
= (struct ubi32_serdes_port
*)port
;
368 IO_PORT_INT_MASK(port
) = 0;
369 free_irq(port
->irq
, uart
);
373 ubi32_serdes_set_termios(struct uart_port
*port
, struct ktermios
*termios
,
374 struct ktermios
*old
)
379 spin_lock_irqsave(&port
->lock
, flags
);
381 port
->read_status_mask
= ULITE_STATUS_RXVALID
| ULITE_STATUS_OVERRUN
382 | ULITE_STATUS_TXFULL
;
384 if (termios
->c_iflag
& INPCK
)
385 port
->read_status_mask
|=
386 ULITE_STATUS_PARITY
| ULITE_STATUS_FRAME
;
388 port
->ignore_status_mask
= 0;
389 if (termios
->c_iflag
& IGNPAR
)
390 port
->ignore_status_mask
|= ULITE_STATUS_PARITY
391 | ULITE_STATUS_FRAME
| ULITE_STATUS_OVERRUN
;
393 /* ignore all characters if CREAD is not set */
394 if ((termios
->c_cflag
& CREAD
) == 0)
395 port
->ignore_status_mask
|=
396 ULITE_STATUS_RXVALID
| ULITE_STATUS_PARITY
397 | ULITE_STATUS_FRAME
| ULITE_STATUS_OVERRUN
;
400 baud
= uart_get_baud_rate(port
, termios
, old
, 0, 460800);
401 uart_update_timeout(port
, termios
->c_cflag
, baud
);
403 IO_PORT(port
)->ctl0
= SERIAL_UBICOM_CTL0
|
404 ((port
->uartclk
/ (16 * baud
)) - 1);
406 spin_unlock_irqrestore(&port
->lock
, flags
);
409 static const char *ubi32_serdes_type(struct uart_port
*port
)
411 return port
->type
== PORT_UBI32_SERDES
? "UBI32_SERDES" : NULL
;
415 * Release the memory region(s) being used by 'port'.
417 static void ubi32_serdes_release_port(struct uart_port
*port
)
422 * Request the memory region(s) being used by 'port'.
424 static int ubi32_serdes_request_port(struct uart_port
*port
)
430 * Configure/autoconfigure the port.
432 static void ubi32_serdes_config_port(struct uart_port
*port
, int flags
)
434 if (flags
& UART_CONFIG_TYPE
&&
435 ubi32_serdes_request_port(port
) == 0)
436 port
->type
= PORT_UBI32_SERDES
;
440 * Verify the new serial_struct (for TIOCSSERIAL).
441 * The only change we allow are to the flags and type, and
442 * even then only between PORT_UBI32_SERDES and PORT_UNKNOWN
445 ubi32_serdes_verify_port(struct uart_port
*port
, struct serial_struct
*ser
)
450 static struct uart_ops ubi32_serdes_pops
= {
451 .tx_empty
= ubi32_serdes_tx_empty
,
452 .set_mctrl
= ubi32_serdes_set_mctrl
,
453 .get_mctrl
= ubi32_serdes_get_mctrl
,
454 .stop_tx
= ubi32_serdes_stop_tx
,
455 .start_tx
= ubi32_serdes_start_tx
,
456 .stop_rx
= ubi32_serdes_stop_rx
,
457 .enable_ms
= ubi32_serdes_enable_ms
,
458 .break_ctl
= ubi32_serdes_break_ctl
,
459 .startup
= ubi32_serdes_startup
,
460 .shutdown
= ubi32_serdes_shutdown
,
461 .set_termios
= ubi32_serdes_set_termios
,
462 .type
= ubi32_serdes_type
,
463 .release_port
= ubi32_serdes_release_port
,
464 .request_port
= ubi32_serdes_request_port
,
465 .config_port
= ubi32_serdes_config_port
,
466 .verify_port
= ubi32_serdes_verify_port
,
469 static void __init
ubi32_serdes_init_ports(void)
473 for (i
= 0; i
< NR_PORTS
; i
++) {
474 ubi32_serdes_ports
[i
].uartclk
= ubi32_serdes_resource
[i
].uart_clock
;
475 ubi32_serdes_ports
[i
].ops
= &ubi32_serdes_pops
;
476 ubi32_serdes_ports
[i
].line
= i
;
477 ubi32_serdes_ports
[i
].iotype
= UPIO_MEM
;
478 ubi32_serdes_ports
[i
].membase
=
479 (void __iomem
*)ubi32_serdes_resource
[i
].uart_base_addr
;
480 ubi32_serdes_ports
[i
].mapbase
=
481 (resource_size_t
)ubi32_serdes_resource
[i
].uart_base_addr
;
482 ubi32_serdes_ports
[i
].irq
=
483 ubi32_serdes_resource
[i
].uart_irq
;
484 ubi32_serdes_ports
[i
].flags
= UPF_BOOT_AUTOCONF
;
486 ubi32_serdes_hw_init(&ubi32_serdes_ports
[i
], 0);
491 #ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
493 * If the port was already initialised (eg, by a boot loader),
494 * try to determine the current setup.
497 ubi32_serdes_console_get_options(struct uart_port
*port
, int *baud
)
503 * We might get called before platform init and with no
504 * kernel command line options, so port might be NULL.
506 *baud
= ubi32_serdes_default_baud_rate
;;
507 if ( IO_PORT(port
) == 0 )
510 real_baud
= port
->uartclk
511 / (16 * ((IO_PORT(port
)->ctl0
& ~SERIAL_UBICOM_CTL0
) + 1));
513 *baud
= ((real_baud
+ round_to
- 1) / round_to
) * round_to
;
515 pr_debug("%s:baud = %d, real_baud = %d\n", __FUNCTION__
, *baud
, real_baud
);
519 #if defined(CONFIG_SERIAL_UBI32_SERDES_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
520 static struct uart_driver ubi32_serdes_reg
;
523 ubi32_serdes_console_setup(struct console
*co
, char *options
)
525 struct uart_port
*port
;
526 #ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
527 int baud
= ubi32_serdes_default_baud_rate
;
534 * Check whether an invalid uart number has been specified, and
535 * if so, search for the first available port that does have
538 if (co
->index
== -1 || co
->index
>= NR_PORTS
)
540 port
= &ubi32_serdes_ports
[co
->index
];
542 #ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
544 uart_parse_options(options
, &baud
, &parity
, &bits
, &flow
);
545 ubi32_serdes_hw_init(port
, baud
);
548 ubi32_serdes_console_get_options(port
, &baud
);
550 return uart_set_options(port
, co
, baud
, parity
, bits
, flow
);
555 #endif /* defined (CONFIG_SERIAL_UBI32_SERDES_CONSOLE) ||
556 defined (CONFIG_EARLY_PRINTK) */
558 #ifdef CONFIG_SERIAL_UBI32_SERDES_CONSOLE
560 ubi32_serdes_console_putchar(struct uart_port
*port
, int ch
)
562 if ( IO_PORT(port
) ) {
563 while (!(IO_PORT_INT_STATUS(port
) & IO_PORTX_INT_SERDES_TXBE
))
565 ubi32_serdes_put_char(IO_PORT(port
), ch
);
570 * Interrupts are disabled on entering
573 ubi32_serdes_console_write(struct console
*co
, const char *s
, unsigned int count
)
575 struct uart_port
*port
= &ubi32_serdes_ports
[co
->index
];
576 unsigned long flags
= 0;
578 spin_lock_irqsave(&port
->lock
, flags
);
579 uart_console_write(port
, s
, count
, ubi32_serdes_console_putchar
);
580 spin_unlock_irqrestore(&port
->lock
, flags
);
584 static struct console ubi32_serdes_console
= {
585 .name
= UBI32_SERDES_NAME
,
586 .write
= ubi32_serdes_console_write
,
587 .device
= uart_console_device
,
588 .setup
= ubi32_serdes_console_setup
,
589 .flags
= CON_PRINTBUFFER
,
591 .data
= &ubi32_serdes_reg
,
594 static int __init
ubi32_serdes_console_init(void)
596 ubi32_serdes_init_ports();
597 register_console(&ubi32_serdes_console
);
600 console_initcall(ubi32_serdes_console_init
);
602 #define UBI32_SERDES_CONSOLE &ubi32_serdes_console
604 #define UBI32_SERDES_CONSOLE NULL
605 #endif /* CONFIG_SERIAL_UBI32_SERDES_CONSOLE */
608 #ifdef CONFIG_EARLY_PRINTK
609 static __init
void ubi32_serdes_early_putc(struct uart_port
*port
, int ch
)
611 unsigned timeout
= 0xffff;
613 while ((!(IO_PORT_INT_STATUS(port
) & IO_PORTX_INT_SERDES_TXBE
)) && --timeout
)
615 ubi32_serdes_put_char(IO_PORT(port
), ch
);
618 static __init
void ubi32_serdes_early_write(struct console
*con
, const char *s
,
621 struct uart_port
*port
= &ubi32_serdes_ports
[con
->index
];
624 for (i
= 0; i
< n
; i
++, s
++) {
626 ubi32_serdes_early_putc(port
, '\r');
627 ubi32_serdes_early_putc(port
, *s
);
631 static struct __init console ubi32_serdes_early_console
= {
633 .write
= ubi32_serdes_early_write
,
634 .device
= uart_console_device
,
635 .flags
= CON_PRINTBUFFER
,
636 .setup
= ubi32_serdes_console_setup
,
638 .data
= &ubi32_serdes_reg
,
642 * XXX Unused in our driver. Need to find out what the termios initialization is good/needed for.
644 struct console __init
*ubi32_serdes_early_init(unsigned int port_index
,
647 struct uart_port
*uart
;
650 if (port_index
== -1 || port_index
>= NR_PORTS
)
652 ubi32_serdes_init_ports();
653 ubi32_serdes_early_console
.index
= port_index
;
654 uart
= &ubi32_serdes_ports
[port_index
];
659 t
.c_line
= port_index
;
660 ubi32_serdes_set_termios(uart
, &t
, &t
);
661 return &ubi32_serdes_early_console
;
664 #endif /* CONFIG_SERIAL_UBI32_SERDES_CONSOLE */
666 static struct uart_driver ubi32_serdes_reg
= {
667 .owner
= THIS_MODULE
,
668 .driver_name
= "ubi32_serdes",
669 .dev_name
= UBI32_SERDES_NAME
,
670 .major
= UBI32_SERDES_MAJOR
,
671 .minor
= UBI32_SERDES_MINOR
,
673 .cons
= UBI32_SERDES_CONSOLE
,
676 static int ubi32_serdes_suspend(struct platform_device
*dev
, pm_message_t state
)
678 struct uart_port
*port
= platform_get_drvdata(dev
);
681 uart_suspend_port(&ubi32_serdes_reg
, port
);
686 static int ubi32_serdes_resume(struct platform_device
*dev
)
688 struct uart_port
*port
= platform_get_drvdata(dev
);
691 uart_resume_port(&ubi32_serdes_reg
, port
);
696 static int ubi32_serdes_probe(struct platform_device
*dev
)
698 struct resource
*res
= dev
->resource
;
701 for (i
= 0; i
< dev
->num_resources
; i
++, res
++) {
702 if (res
->flags
& IORESOURCE_MEM
) {
703 ubi32_serdes_resource
[0].uart_base_addr
= (void *) res
->start
;
705 else if (res
->flags
& IORESOURCE_IRQ
) {
706 ubi32_serdes_resource
[0].uart_irq
= res
->start
;
708 else if (res
->flags
& UBICOM32_SUART_IORESOURCE_CLOCK
) {
709 ubi32_serdes_resource
[0].uart_clock
= res
->start
;
713 ubi32_serdes_init_ports();
718 static int ubi32_serdes_remove(struct platform_device
*pdev
)
720 struct uart_port
*port
= platform_get_drvdata(pdev
);
722 platform_set_drvdata(pdev
, NULL
);
725 uart_remove_one_port(&ubi32_serdes_reg
, port
);
730 static struct platform_driver ubi32_serdes_driver
= {
731 .remove
= ubi32_serdes_remove
,
732 .suspend
= ubi32_serdes_suspend
,
733 .resume
= ubi32_serdes_resume
,
735 .name
= "ubicom32suart",
736 .owner
= THIS_MODULE
,
743 * Called at boot time.
745 * You can specify IO base, IRQ, and clock for the serdes serial port
746 * using kernel command line "serdes=0xiobase,irq,clock". Values
747 * specified will be overwritten by platform device data, if present.
749 static int __init
ubi32_serdes_setup(char *str
)
751 #define N_PARMS (4+1)
755 str
= get_options(str
, ARRAY_SIZE(ints
), ints
);
757 for (i
= 0; i
< N_PARMS
; i
++) {
760 ubi32_serdes_resource
[0].uart_base_addr
= (void *) ints
[i
+1];
763 ubi32_serdes_resource
[0].uart_irq
= ints
[i
+1];
766 ubi32_serdes_resource
[0].uart_clock
= ints
[i
+1];
769 ubi32_serdes_default_baud_rate
= ints
[i
+1];
776 __setup("serdes=", ubi32_serdes_setup
);
779 static int __init
ubi32_serdes_init(void)
783 pr_info("Serial: Ubicom32 serdes uart serial driver\n");
785 ret
= platform_driver_probe(&ubi32_serdes_driver
, ubi32_serdes_probe
);
787 printk(KERN_INFO
"serdes platform_driver_probe() failed: %d\n", ret
);
791 ubi32_serdes_init_ports();
793 ret
= uart_register_driver(&ubi32_serdes_reg
);
795 ret
= uart_add_one_port(&ubi32_serdes_reg
, &ubi32_serdes_ports
[0]);
797 uart_unregister_driver(&ubi32_serdes_reg
);
804 static void __exit
ubi32_serdes_exit(void)
806 platform_driver_unregister(&ubi32_serdes_driver
);
807 uart_unregister_driver(&ubi32_serdes_reg
);
810 module_init(ubi32_serdes_init
);
811 module_exit(ubi32_serdes_exit
);
813 MODULE_AUTHOR("Rainer Keller <rkeller@ubicom.com>");
814 MODULE_DESCRIPTION("Ubicom generic serial port driver");
815 MODULE_LICENSE("GPL");
816 MODULE_ALIAS_CHARDEV_MAJOR(UBI32_SERDES_MAJOR
);
817 MODULE_ALIAS("platform:ubi32_serdes");