myri10ge: update driver version
[linux-2.6] / drivers / serial / vr41xx_siu.c
1 /*
2  *  Driver for NEC VR4100 series Serial Interface Unit.
3  *
4  *  Copyright (C) 2004-2008  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5  *
6  *  Based on drivers/serial/8250.c, by Russell King.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #if defined(CONFIG_SERIAL_VR41XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
24 #define SUPPORT_SYSRQ
25 #endif
26
27 #include <linux/console.h>
28 #include <linux/errno.h>
29 #include <linux/init.h>
30 #include <linux/interrupt.h>
31 #include <linux/ioport.h>
32 #include <linux/module.h>
33 #include <linux/platform_device.h>
34 #include <linux/serial.h>
35 #include <linux/serial_core.h>
36 #include <linux/serial_reg.h>
37 #include <linux/tty.h>
38 #include <linux/tty_flip.h>
39
40 #include <asm/io.h>
41 #include <asm/vr41xx/siu.h>
42 #include <asm/vr41xx/vr41xx.h>
43
44 #define SIU_BAUD_BASE   1152000
45 #define SIU_MAJOR       204
46 #define SIU_MINOR_BASE  82
47
48 #define RX_MAX_COUNT    256
49 #define TX_MAX_COUNT    15
50
51 #define SIUIRSEL        0x08
52  #define TMICMODE       0x20
53  #define TMICTX         0x10
54  #define IRMSEL         0x0c
55  #define IRMSEL_HP      0x08
56  #define IRMSEL_TEMIC   0x04
57  #define IRMSEL_SHARP   0x00
58  #define IRUSESEL       0x02
59  #define SIRSEL         0x01
60
61 static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = {
62         [0 ... SIU_PORTS_MAX-1] = {
63                 .lock   = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock),
64                 .irq    = -1,
65         },
66 };
67
68 #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
69 static uint8_t lsr_break_flag[SIU_PORTS_MAX];
70 #endif
71
72 #define siu_read(port, offset)          readb((port)->membase + (offset))
73 #define siu_write(port, offset, value)  writeb((value), (port)->membase + (offset))
74
75 void vr41xx_select_siu_interface(siu_interface_t interface)
76 {
77         struct uart_port *port;
78         unsigned long flags;
79         uint8_t irsel;
80
81         port = &siu_uart_ports[0];
82
83         spin_lock_irqsave(&port->lock, flags);
84
85         irsel = siu_read(port, SIUIRSEL);
86         if (interface == SIU_INTERFACE_IRDA)
87                 irsel |= SIRSEL;
88         else
89                 irsel &= ~SIRSEL;
90         siu_write(port, SIUIRSEL, irsel);
91
92         spin_unlock_irqrestore(&port->lock, flags);
93 }
94 EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface);
95
96 void vr41xx_use_irda(irda_use_t use)
97 {
98         struct uart_port *port;
99         unsigned long flags;
100         uint8_t irsel;
101
102         port = &siu_uart_ports[0];
103
104         spin_lock_irqsave(&port->lock, flags);
105
106         irsel = siu_read(port, SIUIRSEL);
107         if (use == FIR_USE_IRDA)
108                 irsel |= IRUSESEL;
109         else
110                 irsel &= ~IRUSESEL;
111         siu_write(port, SIUIRSEL, irsel);
112
113         spin_unlock_irqrestore(&port->lock, flags);
114 }
115 EXPORT_SYMBOL_GPL(vr41xx_use_irda);
116
117 void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed)
118 {
119         struct uart_port *port;
120         unsigned long flags;
121         uint8_t irsel;
122
123         port = &siu_uart_ports[0];
124
125         spin_lock_irqsave(&port->lock, flags);
126
127         irsel = siu_read(port, SIUIRSEL);
128         irsel &= ~(IRMSEL | TMICTX | TMICMODE);
129         switch (module) {
130         case SHARP_IRDA:
131                 irsel |= IRMSEL_SHARP;
132                 break;
133         case TEMIC_IRDA:
134                 irsel |= IRMSEL_TEMIC | TMICMODE;
135                 if (speed == IRDA_TX_4MBPS)
136                         irsel |= TMICTX;
137                 break;
138         case HP_IRDA:
139                 irsel |= IRMSEL_HP;
140                 break;
141         default:
142                 break;
143         }
144         siu_write(port, SIUIRSEL, irsel);
145
146         spin_unlock_irqrestore(&port->lock, flags);
147 }
148 EXPORT_SYMBOL_GPL(vr41xx_select_irda_module);
149
150 static inline void siu_clear_fifo(struct uart_port *port)
151 {
152         siu_write(port, UART_FCR, UART_FCR_ENABLE_FIFO);
153         siu_write(port, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
154                                   UART_FCR_CLEAR_XMIT);
155         siu_write(port, UART_FCR, 0);
156 }
157
158 static inline unsigned long siu_port_size(struct uart_port *port)
159 {
160         switch (port->type) {
161         case PORT_VR41XX_SIU:
162                 return 11UL;
163         case PORT_VR41XX_DSIU:
164                 return 8UL;
165         }
166
167         return 0;
168 }
169
170 static inline unsigned int siu_check_type(struct uart_port *port)
171 {
172         if (port->line == 0)
173                 return PORT_VR41XX_SIU;
174         if (port->line == 1 && port->irq != -1)
175                 return PORT_VR41XX_DSIU;
176
177         return PORT_UNKNOWN;
178 }
179
180 static inline const char *siu_type_name(struct uart_port *port)
181 {
182         switch (port->type) {
183         case PORT_VR41XX_SIU:
184                 return "SIU";
185         case PORT_VR41XX_DSIU:
186                 return "DSIU";
187         }
188
189         return NULL;
190 }
191
192 static unsigned int siu_tx_empty(struct uart_port *port)
193 {
194         uint8_t lsr;
195
196         lsr = siu_read(port, UART_LSR);
197         if (lsr & UART_LSR_TEMT)
198                 return TIOCSER_TEMT;
199
200         return 0;
201 }
202
203 static void siu_set_mctrl(struct uart_port *port, unsigned int mctrl)
204 {
205         uint8_t mcr = 0;
206
207         if (mctrl & TIOCM_DTR)
208                 mcr |= UART_MCR_DTR;
209         if (mctrl & TIOCM_RTS)
210                 mcr |= UART_MCR_RTS;
211         if (mctrl & TIOCM_OUT1)
212                 mcr |= UART_MCR_OUT1;
213         if (mctrl & TIOCM_OUT2)
214                 mcr |= UART_MCR_OUT2;
215         if (mctrl & TIOCM_LOOP)
216                 mcr |= UART_MCR_LOOP;
217
218         siu_write(port, UART_MCR, mcr);
219 }
220
221 static unsigned int siu_get_mctrl(struct uart_port *port)
222 {
223         uint8_t msr;
224         unsigned int mctrl = 0;
225
226         msr = siu_read(port, UART_MSR);
227         if (msr & UART_MSR_DCD)
228                 mctrl |= TIOCM_CAR;
229         if (msr & UART_MSR_RI)
230                 mctrl |= TIOCM_RNG;
231         if (msr & UART_MSR_DSR)
232                 mctrl |= TIOCM_DSR;
233         if (msr & UART_MSR_CTS)
234                 mctrl |= TIOCM_CTS;
235
236         return mctrl;
237 }
238
239 static void siu_stop_tx(struct uart_port *port)
240 {
241         unsigned long flags;
242         uint8_t ier;
243
244         spin_lock_irqsave(&port->lock, flags);
245
246         ier = siu_read(port, UART_IER);
247         ier &= ~UART_IER_THRI;
248         siu_write(port, UART_IER, ier);
249
250         spin_unlock_irqrestore(&port->lock, flags);
251 }
252
253 static void siu_start_tx(struct uart_port *port)
254 {
255         unsigned long flags;
256         uint8_t ier;
257
258         spin_lock_irqsave(&port->lock, flags);
259
260         ier = siu_read(port, UART_IER);
261         ier |= UART_IER_THRI;
262         siu_write(port, UART_IER, ier);
263
264         spin_unlock_irqrestore(&port->lock, flags);
265 }
266
267 static void siu_stop_rx(struct uart_port *port)
268 {
269         unsigned long flags;
270         uint8_t ier;
271
272         spin_lock_irqsave(&port->lock, flags);
273
274         ier = siu_read(port, UART_IER);
275         ier &= ~UART_IER_RLSI;
276         siu_write(port, UART_IER, ier);
277
278         port->read_status_mask &= ~UART_LSR_DR;
279
280         spin_unlock_irqrestore(&port->lock, flags);
281 }
282
283 static void siu_enable_ms(struct uart_port *port)
284 {
285         unsigned long flags;
286         uint8_t ier;
287
288         spin_lock_irqsave(&port->lock, flags);
289
290         ier = siu_read(port, UART_IER);
291         ier |= UART_IER_MSI;
292         siu_write(port, UART_IER, ier);
293
294         spin_unlock_irqrestore(&port->lock, flags);
295 }
296
297 static void siu_break_ctl(struct uart_port *port, int ctl)
298 {
299         unsigned long flags;
300         uint8_t lcr;
301
302         spin_lock_irqsave(&port->lock, flags);
303
304         lcr = siu_read(port, UART_LCR);
305         if (ctl == -1)
306                 lcr |= UART_LCR_SBC;
307         else
308                 lcr &= ~UART_LCR_SBC;
309         siu_write(port, UART_LCR, lcr);
310
311         spin_unlock_irqrestore(&port->lock, flags);
312 }
313
314 static inline void receive_chars(struct uart_port *port, uint8_t *status)
315 {
316         struct tty_struct *tty;
317         uint8_t lsr, ch;
318         char flag;
319         int max_count = RX_MAX_COUNT;
320
321         tty = port->info->tty;
322         lsr = *status;
323
324         do {
325                 ch = siu_read(port, UART_RX);
326                 port->icount.rx++;
327                 flag = TTY_NORMAL;
328
329 #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
330                 lsr |= lsr_break_flag[port->line];
331                 lsr_break_flag[port->line] = 0;
332 #endif
333                 if (unlikely(lsr & (UART_LSR_BI | UART_LSR_FE |
334                                     UART_LSR_PE | UART_LSR_OE))) {
335                         if (lsr & UART_LSR_BI) {
336                                 lsr &= ~(UART_LSR_FE | UART_LSR_PE);
337                                 port->icount.brk++;
338
339                                 if (uart_handle_break(port))
340                                         goto ignore_char;
341                         }
342
343                         if (lsr & UART_LSR_FE)
344                                 port->icount.frame++;
345                         if (lsr & UART_LSR_PE)
346                                 port->icount.parity++;
347                         if (lsr & UART_LSR_OE)
348                                 port->icount.overrun++;
349
350                         lsr &= port->read_status_mask;
351                         if (lsr & UART_LSR_BI)
352                                 flag = TTY_BREAK;
353                         if (lsr & UART_LSR_FE)
354                                 flag = TTY_FRAME;
355                         if (lsr & UART_LSR_PE)
356                                 flag = TTY_PARITY;
357                 }
358
359                 if (uart_handle_sysrq_char(port, ch))
360                         goto ignore_char;
361
362                 uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
363
364         ignore_char:
365                 lsr = siu_read(port, UART_LSR);
366         } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
367
368         tty_flip_buffer_push(tty);
369
370         *status = lsr;
371 }
372
373 static inline void check_modem_status(struct uart_port *port)
374 {
375         uint8_t msr;
376
377         msr = siu_read(port, UART_MSR);
378         if ((msr & UART_MSR_ANY_DELTA) == 0)
379                 return;
380         if (msr & UART_MSR_DDCD)
381                 uart_handle_dcd_change(port, msr & UART_MSR_DCD);
382         if (msr & UART_MSR_TERI)
383                 port->icount.rng++;
384         if (msr & UART_MSR_DDSR)
385                 port->icount.dsr++;
386         if (msr & UART_MSR_DCTS)
387                 uart_handle_cts_change(port, msr & UART_MSR_CTS);
388
389         wake_up_interruptible(&port->info->delta_msr_wait);
390 }
391
392 static inline void transmit_chars(struct uart_port *port)
393 {
394         struct circ_buf *xmit;
395         int max_count = TX_MAX_COUNT;
396
397         xmit = &port->info->xmit;
398
399         if (port->x_char) {
400                 siu_write(port, UART_TX, port->x_char);
401                 port->icount.tx++;
402                 port->x_char = 0;
403                 return;
404         }
405
406         if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
407                 siu_stop_tx(port);
408                 return;
409         }
410
411         do {
412                 siu_write(port, UART_TX, xmit->buf[xmit->tail]);
413                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
414                 port->icount.tx++;
415                 if (uart_circ_empty(xmit))
416                         break;
417         } while (max_count-- > 0);
418
419         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
420                 uart_write_wakeup(port);
421
422         if (uart_circ_empty(xmit))
423                 siu_stop_tx(port);
424 }
425
426 static irqreturn_t siu_interrupt(int irq, void *dev_id)
427 {
428         struct uart_port *port;
429         uint8_t iir, lsr;
430
431         port = (struct uart_port *)dev_id;
432
433         iir = siu_read(port, UART_IIR);
434         if (iir & UART_IIR_NO_INT)
435                 return IRQ_NONE;
436
437         lsr = siu_read(port, UART_LSR);
438         if (lsr & UART_LSR_DR)
439                 receive_chars(port, &lsr);
440
441         check_modem_status(port);
442
443         if (lsr & UART_LSR_THRE)
444                 transmit_chars(port);
445
446         return IRQ_HANDLED;
447 }
448
449 static int siu_startup(struct uart_port *port)
450 {
451         int retval;
452
453         if (port->membase == NULL)
454                 return -ENODEV;
455
456         siu_clear_fifo(port);
457
458         (void)siu_read(port, UART_LSR);
459         (void)siu_read(port, UART_RX);
460         (void)siu_read(port, UART_IIR);
461         (void)siu_read(port, UART_MSR);
462
463         if (siu_read(port, UART_LSR) == 0xff)
464                 return -ENODEV;
465
466         retval = request_irq(port->irq, siu_interrupt, 0, siu_type_name(port), port);
467         if (retval)
468                 return retval;
469
470         if (port->type == PORT_VR41XX_DSIU)
471                 vr41xx_enable_dsiuint(DSIUINT_ALL);
472
473         siu_write(port, UART_LCR, UART_LCR_WLEN8);
474
475         spin_lock_irq(&port->lock);
476         siu_set_mctrl(port, port->mctrl);
477         spin_unlock_irq(&port->lock);
478
479         siu_write(port, UART_IER, UART_IER_RLSI | UART_IER_RDI);
480
481         (void)siu_read(port, UART_LSR);
482         (void)siu_read(port, UART_RX);
483         (void)siu_read(port, UART_IIR);
484         (void)siu_read(port, UART_MSR);
485
486         return 0;
487 }
488
489 static void siu_shutdown(struct uart_port *port)
490 {
491         unsigned long flags;
492         uint8_t lcr;
493
494         siu_write(port, UART_IER, 0);
495
496         spin_lock_irqsave(&port->lock, flags);
497
498         port->mctrl &= ~TIOCM_OUT2;
499         siu_set_mctrl(port, port->mctrl);
500
501         spin_unlock_irqrestore(&port->lock, flags);
502
503         lcr = siu_read(port, UART_LCR);
504         lcr &= ~UART_LCR_SBC;
505         siu_write(port, UART_LCR, lcr);
506
507         siu_clear_fifo(port);
508
509         (void)siu_read(port, UART_RX);
510
511         if (port->type == PORT_VR41XX_DSIU)
512                 vr41xx_disable_dsiuint(DSIUINT_ALL);
513
514         free_irq(port->irq, port);
515 }
516
517 static void siu_set_termios(struct uart_port *port, struct ktermios *new,
518                             struct ktermios *old)
519 {
520         tcflag_t c_cflag, c_iflag;
521         uint8_t lcr, fcr, ier;
522         unsigned int baud, quot;
523         unsigned long flags;
524
525         c_cflag = new->c_cflag;
526         switch (c_cflag & CSIZE) {
527         case CS5:
528                 lcr = UART_LCR_WLEN5;
529                 break;
530         case CS6:
531                 lcr = UART_LCR_WLEN6;
532                 break;
533         case CS7:
534                 lcr = UART_LCR_WLEN7;
535                 break;
536         default:
537                 lcr = UART_LCR_WLEN8;
538                 break;
539         }
540
541         if (c_cflag & CSTOPB)
542                 lcr |= UART_LCR_STOP;
543         if (c_cflag & PARENB)
544                 lcr |= UART_LCR_PARITY;
545         if ((c_cflag & PARODD) != PARODD)
546                 lcr |= UART_LCR_EPAR;
547         if (c_cflag & CMSPAR)
548                 lcr |= UART_LCR_SPAR;
549
550         baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
551         quot = uart_get_divisor(port, baud);
552
553         fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
554
555         spin_lock_irqsave(&port->lock, flags);
556
557         uart_update_timeout(port, c_cflag, baud);
558
559         c_iflag = new->c_iflag;
560
561         port->read_status_mask = UART_LSR_THRE | UART_LSR_OE | UART_LSR_DR;
562         if (c_iflag & INPCK)
563                 port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
564         if (c_iflag & (BRKINT | PARMRK))
565                 port->read_status_mask |= UART_LSR_BI;
566
567         port->ignore_status_mask = 0;
568         if (c_iflag & IGNPAR)
569                 port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE;
570         if (c_iflag & IGNBRK) {
571                 port->ignore_status_mask |= UART_LSR_BI;
572                 if (c_iflag & IGNPAR)
573                         port->ignore_status_mask |= UART_LSR_OE;
574         }
575
576         if ((c_cflag & CREAD) == 0)
577                 port->ignore_status_mask |= UART_LSR_DR;
578
579         ier = siu_read(port, UART_IER);
580         ier &= ~UART_IER_MSI;
581         if (UART_ENABLE_MS(port, c_cflag))
582                 ier |= UART_IER_MSI;
583         siu_write(port, UART_IER, ier);
584
585         siu_write(port, UART_LCR, lcr | UART_LCR_DLAB);
586
587         siu_write(port, UART_DLL, (uint8_t)quot);
588         siu_write(port, UART_DLM, (uint8_t)(quot >> 8));
589
590         siu_write(port, UART_LCR, lcr);
591
592         siu_write(port, UART_FCR, fcr);
593
594         siu_set_mctrl(port, port->mctrl);
595
596         spin_unlock_irqrestore(&port->lock, flags);
597 }
598
599 static void siu_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
600 {
601         switch (state) {
602         case 0:
603                 switch (port->type) {
604                 case PORT_VR41XX_SIU:
605                         vr41xx_supply_clock(SIU_CLOCK);
606                         break;
607                 case PORT_VR41XX_DSIU:
608                         vr41xx_supply_clock(DSIU_CLOCK);
609                         break;
610                 }
611                 break;
612         case 3:
613                 switch (port->type) {
614                 case PORT_VR41XX_SIU:
615                         vr41xx_mask_clock(SIU_CLOCK);
616                         break;
617                 case PORT_VR41XX_DSIU:
618                         vr41xx_mask_clock(DSIU_CLOCK);
619                         break;
620                 }
621                 break;
622         }
623 }
624
625 static const char *siu_type(struct uart_port *port)
626 {
627         return siu_type_name(port);
628 }
629
630 static void siu_release_port(struct uart_port *port)
631 {
632         unsigned long size;
633
634         if (port->flags & UPF_IOREMAP) {
635                 iounmap(port->membase);
636                 port->membase = NULL;
637         }
638
639         size = siu_port_size(port);
640         release_mem_region(port->mapbase, size);
641 }
642
643 static int siu_request_port(struct uart_port *port)
644 {
645         unsigned long size;
646         struct resource *res;
647
648         size = siu_port_size(port);
649         res = request_mem_region(port->mapbase, size, siu_type_name(port));
650         if (res == NULL)
651                 return -EBUSY;
652
653         if (port->flags & UPF_IOREMAP) {
654                 port->membase = ioremap(port->mapbase, size);
655                 if (port->membase == NULL) {
656                         release_resource(res);
657                         return -ENOMEM;
658                 }
659         }
660
661         return 0;
662 }
663
664 static void siu_config_port(struct uart_port *port, int flags)
665 {
666         if (flags & UART_CONFIG_TYPE) {
667                 port->type = siu_check_type(port);
668                 (void)siu_request_port(port);
669         }
670 }
671
672 static int siu_verify_port(struct uart_port *port, struct serial_struct *serial)
673 {
674         if (port->type != PORT_VR41XX_SIU && port->type != PORT_VR41XX_DSIU)
675                 return -EINVAL;
676         if (port->irq != serial->irq)
677                 return -EINVAL;
678         if (port->iotype != serial->io_type)
679                 return -EINVAL;
680         if (port->mapbase != (unsigned long)serial->iomem_base)
681                 return -EINVAL;
682
683         return 0;
684 }
685
686 static struct uart_ops siu_uart_ops = {
687         .tx_empty       = siu_tx_empty,
688         .set_mctrl      = siu_set_mctrl,
689         .get_mctrl      = siu_get_mctrl,
690         .stop_tx        = siu_stop_tx,
691         .start_tx       = siu_start_tx,
692         .stop_rx        = siu_stop_rx,
693         .enable_ms      = siu_enable_ms,
694         .break_ctl      = siu_break_ctl,
695         .startup        = siu_startup,
696         .shutdown       = siu_shutdown,
697         .set_termios    = siu_set_termios,
698         .pm             = siu_pm,
699         .type           = siu_type,
700         .release_port   = siu_release_port,
701         .request_port   = siu_request_port,
702         .config_port    = siu_config_port,
703         .verify_port    = siu_verify_port,
704 };
705
706 static int siu_init_ports(struct platform_device *pdev)
707 {
708         struct uart_port *port;
709         struct resource *res;
710         int *type = pdev->dev.platform_data;
711         int i;
712
713         if (!type)
714                 return 0;
715
716         port = siu_uart_ports;
717         for (i = 0; i < SIU_PORTS_MAX; i++) {
718                 port->type = type[i];
719                 if (port->type == PORT_UNKNOWN)
720                         continue;
721                 port->irq = platform_get_irq(pdev, i);
722                 port->uartclk = SIU_BAUD_BASE * 16;
723                 port->fifosize = 16;
724                 port->regshift = 0;
725                 port->iotype = UPIO_MEM;
726                 port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
727                 port->line = i;
728                 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
729                 port->mapbase = res->start;
730                 port++;
731         }
732
733         return i;
734 }
735
736 #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
737
738 #define BOTH_EMPTY      (UART_LSR_TEMT | UART_LSR_THRE)
739
740 static void wait_for_xmitr(struct uart_port *port)
741 {
742         int timeout = 10000;
743         uint8_t lsr, msr;
744
745         do {
746                 lsr = siu_read(port, UART_LSR);
747                 if (lsr & UART_LSR_BI)
748                         lsr_break_flag[port->line] = UART_LSR_BI;
749
750                 if ((lsr & BOTH_EMPTY) == BOTH_EMPTY)
751                         break;
752         } while (timeout-- > 0);
753
754         if (port->flags & UPF_CONS_FLOW) {
755                 timeout = 1000000;
756
757                 do {
758                         msr = siu_read(port, UART_MSR);
759                         if ((msr & UART_MSR_CTS) != 0)
760                                 break;
761                 } while (timeout-- > 0);
762         }
763 }
764
765 static void siu_console_putchar(struct uart_port *port, int ch)
766 {
767         wait_for_xmitr(port);
768         siu_write(port, UART_TX, ch);
769 }
770
771 static void siu_console_write(struct console *con, const char *s, unsigned count)
772 {
773         struct uart_port *port;
774         uint8_t ier;
775
776         port = &siu_uart_ports[con->index];
777
778         ier = siu_read(port, UART_IER);
779         siu_write(port, UART_IER, 0);
780
781         uart_console_write(port, s, count, siu_console_putchar);
782
783         wait_for_xmitr(port);
784         siu_write(port, UART_IER, ier);
785 }
786
787 static int __init siu_console_setup(struct console *con, char *options)
788 {
789         struct uart_port *port;
790         int baud = 9600;
791         int parity = 'n';
792         int bits = 8;
793         int flow = 'n';
794
795         if (con->index >= SIU_PORTS_MAX)
796                 con->index = 0;
797
798         port = &siu_uart_ports[con->index];
799         if (port->membase == NULL) {
800                 if (port->mapbase == 0)
801                         return -ENODEV;
802                 port->membase = ioremap(port->mapbase, siu_port_size(port));
803         }
804
805         if (port->type == PORT_VR41XX_SIU)
806                 vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
807
808         if (options != NULL)
809                 uart_parse_options(options, &baud, &parity, &bits, &flow);
810
811         return uart_set_options(port, con, baud, parity, bits, flow);
812 }
813
814 static struct uart_driver siu_uart_driver;
815
816 static struct console siu_console = {
817         .name   = "ttyVR",
818         .write  = siu_console_write,
819         .device = uart_console_device,
820         .setup  = siu_console_setup,
821         .flags  = CON_PRINTBUFFER,
822         .index  = -1,
823         .data   = &siu_uart_driver,
824 };
825
826 static int __devinit siu_console_init(void)
827 {
828         struct uart_port *port;
829         int i;
830
831         for (i = 0; i < SIU_PORTS_MAX; i++) {
832                 port = &siu_uart_ports[i];
833                 port->ops = &siu_uart_ops;
834         }
835
836         register_console(&siu_console);
837
838         return 0;
839 }
840
841 console_initcall(siu_console_init);
842
843 void __init vr41xx_siu_early_setup(struct uart_port *port)
844 {
845         if (port->type == PORT_UNKNOWN)
846                 return;
847
848         siu_uart_ports[port->line].line = port->line;
849         siu_uart_ports[port->line].type = port->type;
850         siu_uart_ports[port->line].uartclk = SIU_BAUD_BASE * 16;
851         siu_uart_ports[port->line].mapbase = port->mapbase;
852         siu_uart_ports[port->line].mapbase = port->mapbase;
853         siu_uart_ports[port->line].ops = &siu_uart_ops;
854 }
855
856 #define SERIAL_VR41XX_CONSOLE   &siu_console
857 #else
858 #define SERIAL_VR41XX_CONSOLE   NULL
859 #endif
860
861 static struct uart_driver siu_uart_driver = {
862         .owner          = THIS_MODULE,
863         .driver_name    = "SIU",
864         .dev_name       = "ttyVR",
865         .major          = SIU_MAJOR,
866         .minor          = SIU_MINOR_BASE,
867         .cons           = SERIAL_VR41XX_CONSOLE,
868 };
869
870 static int __devinit siu_probe(struct platform_device *dev)
871 {
872         struct uart_port *port;
873         int num, i, retval;
874
875         num = siu_init_ports(dev);
876         if (num <= 0)
877                 return -ENODEV;
878
879         siu_uart_driver.nr = num;
880         retval = uart_register_driver(&siu_uart_driver);
881         if (retval)
882                 return retval;
883
884         for (i = 0; i < num; i++) {
885                 port = &siu_uart_ports[i];
886                 port->ops = &siu_uart_ops;
887                 port->dev = &dev->dev;
888
889                 retval = uart_add_one_port(&siu_uart_driver, port);
890                 if (retval < 0) {
891                         port->dev = NULL;
892                         break;
893                 }
894         }
895
896         if (i == 0 && retval < 0) {
897                 uart_unregister_driver(&siu_uart_driver);
898                 return retval;
899         }
900
901         return 0;
902 }
903
904 static int __devexit siu_remove(struct platform_device *dev)
905 {
906         struct uart_port *port;
907         int i;
908
909         for (i = 0; i < siu_uart_driver.nr; i++) {
910                 port = &siu_uart_ports[i];
911                 if (port->dev == &dev->dev) {
912                         uart_remove_one_port(&siu_uart_driver, port);
913                         port->dev = NULL;
914                 }
915         }
916
917         uart_unregister_driver(&siu_uart_driver);
918
919         return 0;
920 }
921
922 static int siu_suspend(struct platform_device *dev, pm_message_t state)
923 {
924         struct uart_port *port;
925         int i;
926
927         for (i = 0; i < siu_uart_driver.nr; i++) {
928                 port = &siu_uart_ports[i];
929                 if ((port->type == PORT_VR41XX_SIU ||
930                      port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
931                         uart_suspend_port(&siu_uart_driver, port);
932
933         }
934
935         return 0;
936 }
937
938 static int siu_resume(struct platform_device *dev)
939 {
940         struct uart_port *port;
941         int i;
942
943         for (i = 0; i < siu_uart_driver.nr; i++) {
944                 port = &siu_uart_ports[i];
945                 if ((port->type == PORT_VR41XX_SIU ||
946                      port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
947                         uart_resume_port(&siu_uart_driver, port);
948         }
949
950         return 0;
951 }
952
953 static struct platform_driver siu_device_driver = {
954         .probe          = siu_probe,
955         .remove         = __devexit_p(siu_remove),
956         .suspend        = siu_suspend,
957         .resume         = siu_resume,
958         .driver         = {
959                 .name   = "SIU",
960                 .owner  = THIS_MODULE,
961         },
962 };
963
964 static int __init vr41xx_siu_init(void)
965 {
966         return platform_driver_register(&siu_device_driver);
967 }
968
969 static void __exit vr41xx_siu_exit(void)
970 {
971         platform_driver_unregister(&siu_device_driver);
972 }
973
974 module_init(vr41xx_siu_init);
975 module_exit(vr41xx_siu_exit);
976
977 MODULE_LICENSE("GPL");
978 MODULE_ALIAS("platform:SIU");