Merge branch 'next-s3c-pm' of git://aeryn.fluff.org.uk/bjdooks/linux into devel
[linux-2.6] / drivers / serial / serial_lh7a40x.c
1 /* drivers/serial/serial_lh7a40x.c
2  *
3  *  Copyright (C) 2004 Coastal Environmental Systems
4  *
5  *  This program is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU General Public License
7  *  version 2 as published by the Free Software Foundation.
8  *
9  */
10
11 /* Driver for Sharp LH7A40X embedded serial ports
12  *
13  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
14  *  Based on drivers/serial/amba.c, by Deep Blue Solutions Ltd.
15  *
16  *  ---
17  *
18  * This driver supports the embedded UARTs of the Sharp LH7A40X series
19  * CPUs.  While similar to the 16550 and other UART chips, there is
20  * nothing close to register compatibility.  Moreover, some of the
21  * modem control lines are not available, either in the chip or they
22  * are lacking in the board-level implementation.
23  *
24  * - Use of SIRDIS
25  *   For simplicity, we disable the IR functions of any UART whenever
26  *   we enable it.
27  *
28  */
29
30
31 #if defined(CONFIG_SERIAL_LH7A40X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
32 #define SUPPORT_SYSRQ
33 #endif
34
35 #include <linux/module.h>
36 #include <linux/ioport.h>
37 #include <linux/init.h>
38 #include <linux/console.h>
39 #include <linux/sysrq.h>
40 #include <linux/tty.h>
41 #include <linux/tty_flip.h>
42 #include <linux/serial_core.h>
43 #include <linux/serial.h>
44 #include <linux/io.h>
45
46 #include <asm/irq.h>
47 #include <mach/hardware.h>
48
49 #define DEV_MAJOR       204
50 #define DEV_MINOR       16
51 #define DEV_NR          3
52
53 #define ISR_LOOP_LIMIT  256
54
55 #define UR(p,o) _UR ((p)->membase, o)
56 #define _UR(b,o) (*((volatile unsigned int*)(((unsigned char*) b) + (o))))
57 #define BIT_CLR(p,o,m)  UR(p,o) = UR(p,o) & (~(unsigned int)m)
58 #define BIT_SET(p,o,m)  UR(p,o) = UR(p,o) | ( (unsigned int)m)
59
60 #define UART_REG_SIZE   32
61
62 #define UART_R_DATA     (0x00)
63 #define UART_R_FCON     (0x04)
64 #define UART_R_BRCON    (0x08)
65 #define UART_R_CON      (0x0c)
66 #define UART_R_STATUS   (0x10)
67 #define UART_R_RAWISR   (0x14)
68 #define UART_R_INTEN    (0x18)
69 #define UART_R_ISR      (0x1c)
70
71 #define UARTEN          (0x01)          /* UART enable */
72 #define SIRDIS          (0x02)          /* Serial IR disable (UART1 only) */
73
74 #define RxEmpty         (0x10)
75 #define TxEmpty         (0x80)
76 #define TxFull          (0x20)
77 #define nRxRdy          RxEmpty
78 #define nTxRdy          TxFull
79 #define TxBusy          (0x08)
80
81 #define RxBreak         (0x0800)
82 #define RxOverrunError  (0x0400)
83 #define RxParityError   (0x0200)
84 #define RxFramingError  (0x0100)
85 #define RxError     (RxBreak | RxOverrunError | RxParityError | RxFramingError)
86
87 #define DCD             (0x04)
88 #define DSR             (0x02)
89 #define CTS             (0x01)
90
91 #define RxInt           (0x01)
92 #define TxInt           (0x02)
93 #define ModemInt        (0x04)
94 #define RxTimeoutInt    (0x08)
95
96 #define MSEOI           (0x10)
97
98 #define WLEN_8          (0x60)
99 #define WLEN_7          (0x40)
100 #define WLEN_6          (0x20)
101 #define WLEN_5          (0x00)
102 #define WLEN            (0x60)  /* Mask for all word-length bits */
103 #define STP2            (0x08)
104 #define PEN             (0x02)  /* Parity Enable */
105 #define EPS             (0x04)  /* Even Parity Set */
106 #define FEN             (0x10)  /* FIFO Enable */
107 #define BRK             (0x01)  /* Send Break */
108
109
110 struct uart_port_lh7a40x {
111         struct uart_port port;
112         unsigned int statusPrev; /* Most recently read modem status */
113 };
114
115 static void lh7a40xuart_stop_tx (struct uart_port* port)
116 {
117         BIT_CLR (port, UART_R_INTEN, TxInt);
118 }
119
120 static void lh7a40xuart_start_tx (struct uart_port* port)
121 {
122         BIT_SET (port, UART_R_INTEN, TxInt);
123
124         /* *** FIXME: do I need to check for startup of the
125                       transmitter?  The old driver did, but AMBA
126                       doesn't . */
127 }
128
129 static void lh7a40xuart_stop_rx (struct uart_port* port)
130 {
131         BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt);
132 }
133
134 static void lh7a40xuart_enable_ms (struct uart_port* port)
135 {
136         BIT_SET (port, UART_R_INTEN, ModemInt);
137 }
138
139 static void lh7a40xuart_rx_chars (struct uart_port* port)
140 {
141         struct tty_struct* tty = port->info->port.tty;
142         int cbRxMax = 256;      /* (Gross) limit on receive */
143         unsigned int data;      /* Received data and status */
144         unsigned int flag;
145
146         while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) {
147                 data = UR (port, UART_R_DATA);
148                 flag = TTY_NORMAL;
149                 ++port->icount.rx;
150
151                 if (unlikely(data & RxError)) {
152                         if (data & RxBreak) {
153                                 data &= ~(RxFramingError | RxParityError);
154                                 ++port->icount.brk;
155                                 if (uart_handle_break (port))
156                                         continue;
157                         }
158                         else if (data & RxParityError)
159                                 ++port->icount.parity;
160                         else if (data & RxFramingError)
161                                 ++port->icount.frame;
162                         if (data & RxOverrunError)
163                                 ++port->icount.overrun;
164
165                                 /* Mask by termios, leave Rx'd byte */
166                         data &= port->read_status_mask | 0xff;
167
168                         if (data & RxBreak)
169                                 flag = TTY_BREAK;
170                         else if (data & RxParityError)
171                                 flag = TTY_PARITY;
172                         else if (data & RxFramingError)
173                                 flag = TTY_FRAME;
174                 }
175
176                 if (uart_handle_sysrq_char (port, (unsigned char) data))
177                         continue;
178
179                 uart_insert_char(port, data, RxOverrunError, data, flag);
180         }
181         tty_flip_buffer_push (tty);
182         return;
183 }
184
185 static void lh7a40xuart_tx_chars (struct uart_port* port)
186 {
187         struct circ_buf* xmit = &port->info->xmit;
188         int cbTxMax = port->fifosize;
189
190         if (port->x_char) {
191                 UR (port, UART_R_DATA) = port->x_char;
192                 ++port->icount.tx;
193                 port->x_char = 0;
194                 return;
195         }
196         if (uart_circ_empty (xmit) || uart_tx_stopped (port)) {
197                 lh7a40xuart_stop_tx (port);
198                 return;
199         }
200
201         /* Unlike the AMBA UART, the lh7a40x UART does not guarantee
202            that at least half of the FIFO is empty.  Instead, we check
203            status for every character.  Using the AMBA method causes
204            the transmitter to drop characters. */
205
206         do {
207                 UR (port, UART_R_DATA) = xmit->buf[xmit->tail];
208                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
209                 ++port->icount.tx;
210                 if (uart_circ_empty(xmit))
211                         break;
212         } while (!(UR (port, UART_R_STATUS) & nTxRdy)
213                  && cbTxMax--);
214
215         if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
216                 uart_write_wakeup (port);
217
218         if (uart_circ_empty (xmit))
219                 lh7a40xuart_stop_tx (port);
220 }
221
222 static void lh7a40xuart_modem_status (struct uart_port* port)
223 {
224         unsigned int status = UR (port, UART_R_STATUS);
225         unsigned int delta
226                 = status ^ ((struct uart_port_lh7a40x*) port)->statusPrev;
227
228         BIT_SET (port, UART_R_RAWISR, MSEOI); /* Clear modem status intr */
229
230         if (!delta)             /* Only happens if we missed 2 transitions */
231                 return;
232
233         ((struct uart_port_lh7a40x*) port)->statusPrev = status;
234
235         if (delta & DCD)
236                 uart_handle_dcd_change (port, status & DCD);
237
238         if (delta & DSR)
239                 ++port->icount.dsr;
240
241         if (delta & CTS)
242                 uart_handle_cts_change (port, status & CTS);
243
244         wake_up_interruptible (&port->info->delta_msr_wait);
245 }
246
247 static irqreturn_t lh7a40xuart_int (int irq, void* dev_id)
248 {
249         struct uart_port* port = dev_id;
250         unsigned int cLoopLimit = ISR_LOOP_LIMIT;
251         unsigned int isr = UR (port, UART_R_ISR);
252
253
254         do {
255                 if (isr & (RxInt | RxTimeoutInt))
256                         lh7a40xuart_rx_chars(port);
257                 if (isr & ModemInt)
258                         lh7a40xuart_modem_status (port);
259                 if (isr & TxInt)
260                         lh7a40xuart_tx_chars (port);
261
262                 if (--cLoopLimit == 0)
263                         break;
264
265                 isr = UR (port, UART_R_ISR);
266         } while (isr & (RxInt | TxInt | RxTimeoutInt));
267
268         return IRQ_HANDLED;
269 }
270
271 static unsigned int lh7a40xuart_tx_empty (struct uart_port* port)
272 {
273         return (UR (port, UART_R_STATUS) & TxEmpty) ? TIOCSER_TEMT : 0;
274 }
275
276 static unsigned int lh7a40xuart_get_mctrl (struct uart_port* port)
277 {
278         unsigned int result = 0;
279         unsigned int status = UR (port, UART_R_STATUS);
280
281         if (status & DCD)
282                 result |= TIOCM_CAR;
283         if (status & DSR)
284                 result |= TIOCM_DSR;
285         if (status & CTS)
286                 result |= TIOCM_CTS;
287
288         return result;
289 }
290
291 static void lh7a40xuart_set_mctrl (struct uart_port* port, unsigned int mctrl)
292 {
293         /* None of the ports supports DTR. UART1 supports RTS through GPIO. */
294         /* Note, kernel appears to be setting DTR and RTS on console. */
295
296         /* *** FIXME: this deserves more work.  There's some work in
297                tracing all of the IO pins. */
298 #if 0
299         if( port->mapbase == UART1_PHYS) {
300                 gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS);
301
302                 if (mctrl & TIOCM_RTS)
303                         gpio->pbdr &= ~GPIOB_UART1_RTS;
304                 else
305                         gpio->pbdr |= GPIOB_UART1_RTS;
306         }
307 #endif
308 }
309
310 static void lh7a40xuart_break_ctl (struct uart_port* port, int break_state)
311 {
312         unsigned long flags;
313
314         spin_lock_irqsave(&port->lock, flags);
315         if (break_state == -1)
316                 BIT_SET (port, UART_R_FCON, BRK); /* Assert break */
317         else
318                 BIT_CLR (port, UART_R_FCON, BRK); /* Deassert break */
319         spin_unlock_irqrestore(&port->lock, flags);
320 }
321
322 static int lh7a40xuart_startup (struct uart_port* port)
323 {
324         int retval;
325
326         retval = request_irq (port->irq, lh7a40xuart_int, 0,
327                               "serial_lh7a40x", port);
328         if (retval)
329                 return retval;
330
331                                 /* Initial modem control-line settings */
332         ((struct uart_port_lh7a40x*) port)->statusPrev
333                 = UR (port, UART_R_STATUS);
334
335         /* There is presently no configuration option to enable IR.
336            Thus, we always disable it. */
337
338         BIT_SET (port, UART_R_CON, UARTEN | SIRDIS);
339         BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt);
340
341         return 0;
342 }
343
344 static void lh7a40xuart_shutdown (struct uart_port* port)
345 {
346         free_irq (port->irq, port);
347         BIT_CLR (port, UART_R_FCON, BRK | FEN);
348         BIT_CLR (port, UART_R_CON, UARTEN);
349 }
350
351 static void lh7a40xuart_set_termios (struct uart_port* port,
352                                      struct ktermios* termios,
353                                      struct ktermios* old)
354 {
355         unsigned int con;
356         unsigned int inten;
357         unsigned int fcon;
358         unsigned long flags;
359         unsigned int baud;
360         unsigned int quot;
361
362         baud = uart_get_baud_rate (port, termios, old, 8, port->uartclk/16);
363         quot = uart_get_divisor (port, baud); /* -1 performed elsewhere */
364
365         switch (termios->c_cflag & CSIZE) {
366         case CS5:
367                 fcon = WLEN_5;
368                 break;
369         case CS6:
370                 fcon = WLEN_6;
371                 break;
372         case CS7:
373                 fcon = WLEN_7;
374                 break;
375         case CS8:
376         default:
377                 fcon = WLEN_8;
378                 break;
379         }
380         if (termios->c_cflag & CSTOPB)
381                 fcon |= STP2;
382         if (termios->c_cflag & PARENB) {
383                 fcon |= PEN;
384                 if (!(termios->c_cflag & PARODD))
385                         fcon |= EPS;
386         }
387         if (port->fifosize > 1)
388                 fcon |= FEN;
389
390         spin_lock_irqsave (&port->lock, flags);
391
392         uart_update_timeout (port, termios->c_cflag, baud);
393
394         port->read_status_mask = RxOverrunError;
395         if (termios->c_iflag & INPCK)
396                 port->read_status_mask |= RxFramingError | RxParityError;
397         if (termios->c_iflag & (BRKINT | PARMRK))
398                 port->read_status_mask |= RxBreak;
399
400                 /* Figure mask for status we ignore */
401         port->ignore_status_mask = 0;
402         if (termios->c_iflag & IGNPAR)
403                 port->ignore_status_mask |= RxFramingError | RxParityError;
404         if (termios->c_iflag & IGNBRK) {
405                 port->ignore_status_mask |= RxBreak;
406                 /* Ignore overrun when ignorning parity */
407                 /* *** FIXME: is this in the right place? */
408                 if (termios->c_iflag & IGNPAR)
409                         port->ignore_status_mask |= RxOverrunError;
410         }
411
412                 /* Ignore all receive errors when receive disabled */
413         if ((termios->c_cflag & CREAD) == 0)
414                 port->ignore_status_mask |= RxError;
415
416         con   = UR (port, UART_R_CON);
417         inten = (UR (port, UART_R_INTEN) & ~ModemInt);
418
419         if (UART_ENABLE_MS (port, termios->c_cflag))
420                 inten |= ModemInt;
421
422         BIT_CLR (port, UART_R_CON, UARTEN);     /* Disable UART */
423         UR (port, UART_R_INTEN) = 0;            /* Disable interrupts */
424         UR (port, UART_R_BRCON) = quot - 1;     /* Set baud rate divisor */
425         UR (port, UART_R_FCON)  = fcon;         /* Set FIFO and frame ctrl */
426         UR (port, UART_R_INTEN) = inten;        /* Enable interrupts */
427         UR (port, UART_R_CON)   = con;          /* Restore UART mode */
428
429         spin_unlock_irqrestore(&port->lock, flags);
430 }
431
432 static const char* lh7a40xuart_type (struct uart_port* port)
433 {
434         return port->type == PORT_LH7A40X ? "LH7A40X" : NULL;
435 }
436
437 static void lh7a40xuart_release_port (struct uart_port* port)
438 {
439         release_mem_region (port->mapbase, UART_REG_SIZE);
440 }
441
442 static int lh7a40xuart_request_port (struct uart_port* port)
443 {
444         return request_mem_region (port->mapbase, UART_REG_SIZE,
445                                    "serial_lh7a40x") != NULL
446                 ? 0 : -EBUSY;
447 }
448
449 static void lh7a40xuart_config_port (struct uart_port* port, int flags)
450 {
451         if (flags & UART_CONFIG_TYPE) {
452                 port->type = PORT_LH7A40X;
453                 lh7a40xuart_request_port (port);
454         }
455 }
456
457 static int lh7a40xuart_verify_port (struct uart_port* port,
458                                     struct serial_struct* ser)
459 {
460         int ret = 0;
461
462         if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X)
463                 ret = -EINVAL;
464         if (ser->irq < 0 || ser->irq >= nr_irqs)
465                 ret = -EINVAL;
466         if (ser->baud_base < 9600) /* *** FIXME: is this true? */
467                 ret = -EINVAL;
468         return ret;
469 }
470
471 static struct uart_ops lh7a40x_uart_ops = {
472         .tx_empty       = lh7a40xuart_tx_empty,
473         .set_mctrl      = lh7a40xuart_set_mctrl,
474         .get_mctrl      = lh7a40xuart_get_mctrl,
475         .stop_tx        = lh7a40xuart_stop_tx,
476         .start_tx       = lh7a40xuart_start_tx,
477         .stop_rx        = lh7a40xuart_stop_rx,
478         .enable_ms      = lh7a40xuart_enable_ms,
479         .break_ctl      = lh7a40xuart_break_ctl,
480         .startup        = lh7a40xuart_startup,
481         .shutdown       = lh7a40xuart_shutdown,
482         .set_termios    = lh7a40xuart_set_termios,
483         .type           = lh7a40xuart_type,
484         .release_port   = lh7a40xuart_release_port,
485         .request_port   = lh7a40xuart_request_port,
486         .config_port    = lh7a40xuart_config_port,
487         .verify_port    = lh7a40xuart_verify_port,
488 };
489
490 static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
491         {
492                 .port = {
493                         .membase        = (void*) io_p2v (UART1_PHYS),
494                         .mapbase        = UART1_PHYS,
495                         .iotype         = UPIO_MEM,
496                         .irq            = IRQ_UART1INTR,
497                         .uartclk        = 14745600/2,
498                         .fifosize       = 16,
499                         .ops            = &lh7a40x_uart_ops,
500                         .flags          = UPF_BOOT_AUTOCONF,
501                         .line           = 0,
502                 },
503         },
504         {
505                 .port = {
506                         .membase        = (void*) io_p2v (UART2_PHYS),
507                         .mapbase        = UART2_PHYS,
508                         .iotype         = UPIO_MEM,
509                         .irq            = IRQ_UART2INTR,
510                         .uartclk        = 14745600/2,
511                         .fifosize       = 16,
512                         .ops            = &lh7a40x_uart_ops,
513                         .flags          = UPF_BOOT_AUTOCONF,
514                         .line           = 1,
515                 },
516         },
517         {
518                 .port = {
519                         .membase        = (void*) io_p2v (UART3_PHYS),
520                         .mapbase        = UART3_PHYS,
521                         .iotype         = UPIO_MEM,
522                         .irq            = IRQ_UART3INTR,
523                         .uartclk        = 14745600/2,
524                         .fifosize       = 16,
525                         .ops            = &lh7a40x_uart_ops,
526                         .flags          = UPF_BOOT_AUTOCONF,
527                         .line           = 2,
528                 },
529         },
530 };
531
532 #ifndef CONFIG_SERIAL_LH7A40X_CONSOLE
533 # define LH7A40X_CONSOLE NULL
534 #else
535 # define LH7A40X_CONSOLE &lh7a40x_console
536
537 static void lh7a40xuart_console_putchar(struct uart_port *port, int ch)
538 {
539         while (UR(port, UART_R_STATUS) & nTxRdy)
540                 ;
541         UR(port, UART_R_DATA) = ch;
542 }
543
544 static void lh7a40xuart_console_write (struct console* co,
545                                        const char* s,
546                                        unsigned int count)
547 {
548         struct uart_port* port = &lh7a40x_ports[co->index].port;
549         unsigned int con = UR (port, UART_R_CON);
550         unsigned int inten = UR (port, UART_R_INTEN);
551
552
553         UR (port, UART_R_INTEN) = 0;            /* Disable all interrupts */
554         BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */
555
556         uart_console_write(port, s, count, lh7a40xuart_console_putchar);
557
558                                 /* Wait until all characters are sent */
559         while (UR (port, UART_R_STATUS) & TxBusy)
560                 ;
561
562                                 /* Restore control and interrupt mask */
563         UR (port, UART_R_CON) = con;
564         UR (port, UART_R_INTEN) = inten;
565 }
566
567 static void __init lh7a40xuart_console_get_options (struct uart_port* port,
568                                                     int* baud,
569                                                     int* parity,
570                                                     int* bits)
571 {
572         if (UR (port, UART_R_CON) & UARTEN) {
573                 unsigned int fcon = UR (port, UART_R_FCON);
574                 unsigned int quot = UR (port, UART_R_BRCON) + 1;
575
576                 switch (fcon & (PEN | EPS)) {
577                 default:        *parity = 'n'; break;
578                 case PEN:       *parity = 'o'; break;
579                 case PEN | EPS: *parity = 'e'; break;
580                 }
581
582                 switch (fcon & WLEN) {
583                 default:
584                 case WLEN_8: *bits = 8; break;
585                 case WLEN_7: *bits = 7; break;
586                 case WLEN_6: *bits = 6; break;
587                 case WLEN_5: *bits = 5; break;
588                 }
589
590                 *baud = port->uartclk/(16*quot);
591         }
592 }
593
594 static int __init lh7a40xuart_console_setup (struct console* co, char* options)
595 {
596         struct uart_port* port;
597         int baud = 38400;
598         int bits = 8;
599         int parity = 'n';
600         int flow = 'n';
601
602         if (co->index >= DEV_NR) /* Bounds check on device number */
603                 co->index = 0;
604         port = &lh7a40x_ports[co->index].port;
605
606         if (options)
607                 uart_parse_options (options, &baud, &parity, &bits, &flow);
608         else
609                 lh7a40xuart_console_get_options (port, &baud, &parity, &bits);
610
611         return uart_set_options (port, co, baud, parity, bits, flow);
612 }
613
614 static struct uart_driver lh7a40x_reg;
615 static struct console lh7a40x_console = {
616         .name           = "ttyAM",
617         .write          = lh7a40xuart_console_write,
618         .device         = uart_console_device,
619         .setup          = lh7a40xuart_console_setup,
620         .flags          = CON_PRINTBUFFER,
621         .index          = -1,
622         .data           = &lh7a40x_reg,
623 };
624
625 static int __init lh7a40xuart_console_init(void)
626 {
627         register_console (&lh7a40x_console);
628         return 0;
629 }
630
631 console_initcall (lh7a40xuart_console_init);
632
633 #endif
634
635 static struct uart_driver lh7a40x_reg = {
636         .owner                  = THIS_MODULE,
637         .driver_name            = "ttyAM",
638         .dev_name               = "ttyAM",
639         .major                  = DEV_MAJOR,
640         .minor                  = DEV_MINOR,
641         .nr                     = DEV_NR,
642         .cons                   = LH7A40X_CONSOLE,
643 };
644
645 static int __init lh7a40xuart_init(void)
646 {
647         int ret;
648
649         printk (KERN_INFO "serial: LH7A40X serial driver\n");
650
651         ret = uart_register_driver (&lh7a40x_reg);
652
653         if (ret == 0) {
654                 int i;
655
656                 for (i = 0; i < DEV_NR; i++) {
657                         /* UART3, when used, requires GPIO pin reallocation */
658                         if (lh7a40x_ports[i].port.mapbase == UART3_PHYS)
659                                 GPIO_PINMUX |= 1<<3;
660                         uart_add_one_port (&lh7a40x_reg,
661                                            &lh7a40x_ports[i].port);
662                 }
663         }
664         return ret;
665 }
666
667 static void __exit lh7a40xuart_exit(void)
668 {
669         int i;
670
671         for (i = 0; i < DEV_NR; i++)
672                 uart_remove_one_port (&lh7a40x_reg, &lh7a40x_ports[i].port);
673
674         uart_unregister_driver (&lh7a40x_reg);
675 }
676
677 module_init (lh7a40xuart_init);
678 module_exit (lh7a40xuart_exit);
679
680 MODULE_AUTHOR ("Marc Singer");
681 MODULE_DESCRIPTION ("Sharp LH7A40X serial port driver");
682 MODULE_LICENSE ("GPL");