0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/module.h>
0017 #include <linux/kernel.h>
0018 #include <linux/errno.h>
0019 #include <linux/delay.h>
0020 #include <linux/tty.h>
0021 #include <linux/tty_flip.h>
0022 #include <linux/major.h>
0023 #include <linux/string.h>
0024 #include <linux/ptrace.h>
0025 #include <linux/ioport.h>
0026 #include <linux/slab.h>
0027 #include <linux/circ_buf.h>
0028 #include <linux/serial.h>
0029 #include <linux/sysrq.h>
0030 #include <linux/console.h>
0031 #include <linux/spinlock.h>
0032 #include <linux/init.h>
0033
0034 #include <linux/io.h>
0035 #include <asm/irq.h>
0036 #include <asm/sgialib.h>
0037 #include <asm/sgi/ioc.h>
0038 #include <asm/sgi/hpc3.h>
0039 #include <asm/sgi/ip22.h>
0040
0041 #include <linux/serial_core.h>
0042
0043 #include "ip22zilog.h"
0044
0045
0046
0047
0048
0049 #define ZSDELAY() udelay(5)
0050 #define ZSDELAY_LONG() udelay(20)
0051 #define ZS_WSYNC(channel) do { } while (0)
0052
0053 #define NUM_IP22ZILOG 1
0054 #define NUM_CHANNELS (NUM_IP22ZILOG * 2)
0055
0056 #define ZS_CLOCK 3672000
0057 #define ZS_CLOCK_DIVISOR 16
0058
0059
0060
0061
0062 struct uart_ip22zilog_port {
0063 struct uart_port port;
0064
0065
0066 struct uart_ip22zilog_port *next;
0067
0068
0069 unsigned char curregs[NUM_ZSREGS];
0070
0071 unsigned int flags;
0072 #define IP22ZILOG_FLAG_IS_CONS 0x00000004
0073 #define IP22ZILOG_FLAG_IS_KGDB 0x00000008
0074 #define IP22ZILOG_FLAG_MODEM_STATUS 0x00000010
0075 #define IP22ZILOG_FLAG_IS_CHANNEL_A 0x00000020
0076 #define IP22ZILOG_FLAG_REGS_HELD 0x00000040
0077 #define IP22ZILOG_FLAG_TX_STOPPED 0x00000080
0078 #define IP22ZILOG_FLAG_TX_ACTIVE 0x00000100
0079 #define IP22ZILOG_FLAG_RESET_DONE 0x00000200
0080
0081 unsigned int tty_break;
0082
0083 unsigned char parity_mask;
0084 unsigned char prev_status;
0085 };
0086
0087 #define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel *)((PORT)->membase))
0088 #define UART_ZILOG(PORT) ((struct uart_ip22zilog_port *)(PORT))
0089 #define IP22ZILOG_GET_CURR_REG(PORT, REGNUM) \
0090 (UART_ZILOG(PORT)->curregs[REGNUM])
0091 #define IP22ZILOG_SET_CURR_REG(PORT, REGNUM, REGVAL) \
0092 ((UART_ZILOG(PORT)->curregs[REGNUM]) = (REGVAL))
0093 #define ZS_IS_CONS(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_CONS)
0094 #define ZS_IS_KGDB(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_KGDB)
0095 #define ZS_WANTS_MODEM_STATUS(UP) ((UP)->flags & IP22ZILOG_FLAG_MODEM_STATUS)
0096 #define ZS_IS_CHANNEL_A(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_CHANNEL_A)
0097 #define ZS_REGS_HELD(UP) ((UP)->flags & IP22ZILOG_FLAG_REGS_HELD)
0098 #define ZS_TX_STOPPED(UP) ((UP)->flags & IP22ZILOG_FLAG_TX_STOPPED)
0099 #define ZS_TX_ACTIVE(UP) ((UP)->flags & IP22ZILOG_FLAG_TX_ACTIVE)
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 static unsigned char read_zsreg(struct zilog_channel *channel,
0110 unsigned char reg)
0111 {
0112 unsigned char retval;
0113
0114 writeb(reg, &channel->control);
0115 ZSDELAY();
0116 retval = readb(&channel->control);
0117 ZSDELAY();
0118
0119 return retval;
0120 }
0121
0122 static void write_zsreg(struct zilog_channel *channel,
0123 unsigned char reg, unsigned char value)
0124 {
0125 writeb(reg, &channel->control);
0126 ZSDELAY();
0127 writeb(value, &channel->control);
0128 ZSDELAY();
0129 }
0130
0131 static void ip22zilog_clear_fifo(struct zilog_channel *channel)
0132 {
0133 int i;
0134
0135 for (i = 0; i < 32; i++) {
0136 unsigned char regval;
0137
0138 regval = readb(&channel->control);
0139 ZSDELAY();
0140 if (regval & Rx_CH_AV)
0141 break;
0142
0143 regval = read_zsreg(channel, R1);
0144 readb(&channel->data);
0145 ZSDELAY();
0146
0147 if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) {
0148 writeb(ERR_RES, &channel->control);
0149 ZSDELAY();
0150 ZS_WSYNC(channel);
0151 }
0152 }
0153 }
0154
0155
0156
0157
0158 static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs)
0159 {
0160 int i;
0161
0162
0163 for (i = 0; i < 1000; i++) {
0164 unsigned char stat = read_zsreg(channel, R1);
0165 if (stat & ALL_SNT)
0166 break;
0167 udelay(100);
0168 }
0169
0170 writeb(ERR_RES, &channel->control);
0171 ZSDELAY();
0172 ZS_WSYNC(channel);
0173
0174 ip22zilog_clear_fifo(channel);
0175
0176
0177 write_zsreg(channel, R1,
0178 regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
0179
0180
0181 write_zsreg(channel, R4, regs[R4]);
0182
0183
0184 write_zsreg(channel, R10, regs[R10]);
0185
0186
0187 write_zsreg(channel, R3, regs[R3] & ~RxENAB);
0188 write_zsreg(channel, R5, regs[R5] & ~TxENAB);
0189
0190
0191 write_zsreg(channel, R6, regs[R6]);
0192 write_zsreg(channel, R7, regs[R7]);
0193
0194
0195
0196
0197
0198
0199
0200 write_zsreg(channel, R14, regs[R14] & ~BRENAB);
0201
0202
0203 write_zsreg(channel, R11, regs[R11]);
0204
0205
0206 write_zsreg(channel, R12, regs[R12]);
0207 write_zsreg(channel, R13, regs[R13]);
0208
0209
0210 write_zsreg(channel, R14, regs[R14]);
0211
0212
0213 write_zsreg(channel, R15, regs[R15]);
0214
0215
0216 write_zsreg(channel, R0, RES_EXT_INT);
0217 write_zsreg(channel, R0, RES_EXT_INT);
0218
0219
0220 write_zsreg(channel, R3, regs[R3]);
0221 write_zsreg(channel, R5, regs[R5]);
0222
0223
0224 write_zsreg(channel, R1, regs[R1]);
0225 }
0226
0227
0228
0229
0230
0231
0232
0233 static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up,
0234 struct zilog_channel *channel)
0235 {
0236 if (!ZS_REGS_HELD(up)) {
0237 if (ZS_TX_ACTIVE(up)) {
0238 up->flags |= IP22ZILOG_FLAG_REGS_HELD;
0239 } else {
0240 __load_zsregs(channel, up->curregs);
0241 }
0242 }
0243 }
0244
0245 #define Rx_BRK 0x0100
0246 #define Rx_SYS 0x0200
0247
0248 static bool ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
0249 struct zilog_channel *channel)
0250 {
0251 unsigned char ch, flag;
0252 unsigned int r1;
0253 bool push = up->port.state != NULL;
0254
0255 for (;;) {
0256 ch = readb(&channel->control);
0257 ZSDELAY();
0258 if (!(ch & Rx_CH_AV))
0259 break;
0260
0261 r1 = read_zsreg(channel, R1);
0262 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
0263 writeb(ERR_RES, &channel->control);
0264 ZSDELAY();
0265 ZS_WSYNC(channel);
0266 }
0267
0268 ch = readb(&channel->data);
0269 ZSDELAY();
0270
0271 ch &= up->parity_mask;
0272
0273
0274 if (!ch)
0275 r1 |= up->tty_break;
0276
0277
0278 flag = TTY_NORMAL;
0279 up->port.icount.rx++;
0280 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | Rx_SYS | Rx_BRK)) {
0281 up->tty_break = 0;
0282
0283 if (r1 & (Rx_SYS | Rx_BRK)) {
0284 up->port.icount.brk++;
0285 if (r1 & Rx_SYS)
0286 continue;
0287 r1 &= ~(PAR_ERR | CRC_ERR);
0288 }
0289 else if (r1 & PAR_ERR)
0290 up->port.icount.parity++;
0291 else if (r1 & CRC_ERR)
0292 up->port.icount.frame++;
0293 if (r1 & Rx_OVR)
0294 up->port.icount.overrun++;
0295 r1 &= up->port.read_status_mask;
0296 if (r1 & Rx_BRK)
0297 flag = TTY_BREAK;
0298 else if (r1 & PAR_ERR)
0299 flag = TTY_PARITY;
0300 else if (r1 & CRC_ERR)
0301 flag = TTY_FRAME;
0302 }
0303
0304 if (uart_handle_sysrq_char(&up->port, ch))
0305 continue;
0306
0307 if (push)
0308 uart_insert_char(&up->port, r1, Rx_OVR, ch, flag);
0309 }
0310 return push;
0311 }
0312
0313 static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
0314 struct zilog_channel *channel)
0315 {
0316 unsigned char status;
0317
0318 status = readb(&channel->control);
0319 ZSDELAY();
0320
0321 writeb(RES_EXT_INT, &channel->control);
0322 ZSDELAY();
0323 ZS_WSYNC(channel);
0324
0325 if (up->curregs[R15] & BRKIE) {
0326 if ((status & BRK_ABRT) && !(up->prev_status & BRK_ABRT)) {
0327 if (uart_handle_break(&up->port))
0328 up->tty_break = Rx_SYS;
0329 else
0330 up->tty_break = Rx_BRK;
0331 }
0332 }
0333
0334 if (ZS_WANTS_MODEM_STATUS(up)) {
0335 if (status & SYNC)
0336 up->port.icount.dsr++;
0337
0338
0339
0340
0341
0342 if ((status ^ up->prev_status) ^ DCD)
0343 uart_handle_dcd_change(&up->port,
0344 (status & DCD));
0345 if ((status ^ up->prev_status) ^ CTS)
0346 uart_handle_cts_change(&up->port,
0347 (status & CTS));
0348
0349 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
0350 }
0351
0352 up->prev_status = status;
0353 }
0354
0355 static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
0356 struct zilog_channel *channel)
0357 {
0358 struct circ_buf *xmit;
0359
0360 if (ZS_IS_CONS(up)) {
0361 unsigned char status = readb(&channel->control);
0362 ZSDELAY();
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372 if (!(status & Tx_BUF_EMP))
0373 return;
0374 }
0375
0376 up->flags &= ~IP22ZILOG_FLAG_TX_ACTIVE;
0377
0378 if (ZS_REGS_HELD(up)) {
0379 __load_zsregs(channel, up->curregs);
0380 up->flags &= ~IP22ZILOG_FLAG_REGS_HELD;
0381 }
0382
0383 if (ZS_TX_STOPPED(up)) {
0384 up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
0385 goto ack_tx_int;
0386 }
0387
0388 if (up->port.x_char) {
0389 up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
0390 writeb(up->port.x_char, &channel->data);
0391 ZSDELAY();
0392 ZS_WSYNC(channel);
0393
0394 up->port.icount.tx++;
0395 up->port.x_char = 0;
0396 return;
0397 }
0398
0399 if (up->port.state == NULL)
0400 goto ack_tx_int;
0401 xmit = &up->port.state->xmit;
0402 if (uart_circ_empty(xmit))
0403 goto ack_tx_int;
0404 if (uart_tx_stopped(&up->port))
0405 goto ack_tx_int;
0406
0407 up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
0408 writeb(xmit->buf[xmit->tail], &channel->data);
0409 ZSDELAY();
0410 ZS_WSYNC(channel);
0411
0412 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0413 up->port.icount.tx++;
0414
0415 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0416 uart_write_wakeup(&up->port);
0417
0418 return;
0419
0420 ack_tx_int:
0421 writeb(RES_Tx_P, &channel->control);
0422 ZSDELAY();
0423 ZS_WSYNC(channel);
0424 }
0425
0426 static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id)
0427 {
0428 struct uart_ip22zilog_port *up = dev_id;
0429
0430 while (up) {
0431 struct zilog_channel *channel
0432 = ZILOG_CHANNEL_FROM_PORT(&up->port);
0433 unsigned char r3;
0434 bool push = false;
0435
0436 spin_lock(&up->port.lock);
0437 r3 = read_zsreg(channel, R3);
0438
0439
0440 if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
0441 writeb(RES_H_IUS, &channel->control);
0442 ZSDELAY();
0443 ZS_WSYNC(channel);
0444
0445 if (r3 & CHARxIP)
0446 push = ip22zilog_receive_chars(up, channel);
0447 if (r3 & CHAEXT)
0448 ip22zilog_status_handle(up, channel);
0449 if (r3 & CHATxIP)
0450 ip22zilog_transmit_chars(up, channel);
0451 }
0452 spin_unlock(&up->port.lock);
0453
0454 if (push)
0455 tty_flip_buffer_push(&up->port.state->port);
0456
0457
0458 up = up->next;
0459 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
0460 push = false;
0461
0462 spin_lock(&up->port.lock);
0463 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
0464 writeb(RES_H_IUS, &channel->control);
0465 ZSDELAY();
0466 ZS_WSYNC(channel);
0467
0468 if (r3 & CHBRxIP)
0469 push = ip22zilog_receive_chars(up, channel);
0470 if (r3 & CHBEXT)
0471 ip22zilog_status_handle(up, channel);
0472 if (r3 & CHBTxIP)
0473 ip22zilog_transmit_chars(up, channel);
0474 }
0475 spin_unlock(&up->port.lock);
0476
0477 if (push)
0478 tty_flip_buffer_push(&up->port.state->port);
0479
0480 up = up->next;
0481 }
0482
0483 return IRQ_HANDLED;
0484 }
0485
0486
0487
0488
0489 static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
0490 {
0491 struct zilog_channel *channel;
0492 unsigned char status;
0493
0494 channel = ZILOG_CHANNEL_FROM_PORT(port);
0495 status = readb(&channel->control);
0496 ZSDELAY();
0497
0498 return status;
0499 }
0500
0501
0502 static unsigned int ip22zilog_tx_empty(struct uart_port *port)
0503 {
0504 unsigned long flags;
0505 unsigned char status;
0506 unsigned int ret;
0507
0508 spin_lock_irqsave(&port->lock, flags);
0509
0510 status = ip22zilog_read_channel_status(port);
0511
0512 spin_unlock_irqrestore(&port->lock, flags);
0513
0514 if (status & Tx_BUF_EMP)
0515 ret = TIOCSER_TEMT;
0516 else
0517 ret = 0;
0518
0519 return ret;
0520 }
0521
0522
0523 static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
0524 {
0525 unsigned char status;
0526 unsigned int ret;
0527
0528 status = ip22zilog_read_channel_status(port);
0529
0530 ret = 0;
0531 if (status & DCD)
0532 ret |= TIOCM_CAR;
0533 if (status & SYNC)
0534 ret |= TIOCM_DSR;
0535 if (status & CTS)
0536 ret |= TIOCM_CTS;
0537
0538 return ret;
0539 }
0540
0541
0542 static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
0543 {
0544 struct uart_ip22zilog_port *up =
0545 container_of(port, struct uart_ip22zilog_port, port);
0546 struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0547 unsigned char set_bits, clear_bits;
0548
0549 set_bits = clear_bits = 0;
0550
0551 if (mctrl & TIOCM_RTS)
0552 set_bits |= RTS;
0553 else
0554 clear_bits |= RTS;
0555 if (mctrl & TIOCM_DTR)
0556 set_bits |= DTR;
0557 else
0558 clear_bits |= DTR;
0559
0560
0561 up->curregs[R5] |= set_bits;
0562 up->curregs[R5] &= ~clear_bits;
0563 write_zsreg(channel, R5, up->curregs[R5]);
0564 }
0565
0566
0567 static void ip22zilog_stop_tx(struct uart_port *port)
0568 {
0569 struct uart_ip22zilog_port *up =
0570 container_of(port, struct uart_ip22zilog_port, port);
0571
0572 up->flags |= IP22ZILOG_FLAG_TX_STOPPED;
0573 }
0574
0575
0576 static void ip22zilog_start_tx(struct uart_port *port)
0577 {
0578 struct uart_ip22zilog_port *up =
0579 container_of(port, struct uart_ip22zilog_port, port);
0580 struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0581 unsigned char status;
0582
0583 up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
0584 up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
0585
0586 status = readb(&channel->control);
0587 ZSDELAY();
0588
0589
0590 if (!(status & Tx_BUF_EMP))
0591 return;
0592
0593
0594
0595
0596 if (port->x_char) {
0597 writeb(port->x_char, &channel->data);
0598 ZSDELAY();
0599 ZS_WSYNC(channel);
0600
0601 port->icount.tx++;
0602 port->x_char = 0;
0603 } else {
0604 struct circ_buf *xmit = &port->state->xmit;
0605
0606 if (uart_circ_empty(xmit))
0607 return;
0608 writeb(xmit->buf[xmit->tail], &channel->data);
0609 ZSDELAY();
0610 ZS_WSYNC(channel);
0611
0612 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0613 port->icount.tx++;
0614
0615 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0616 uart_write_wakeup(&up->port);
0617 }
0618 }
0619
0620
0621 static void ip22zilog_stop_rx(struct uart_port *port)
0622 {
0623 struct uart_ip22zilog_port *up = UART_ZILOG(port);
0624 struct zilog_channel *channel;
0625
0626 if (ZS_IS_CONS(up))
0627 return;
0628
0629 channel = ZILOG_CHANNEL_FROM_PORT(port);
0630
0631
0632 up->curregs[R1] &= ~RxINT_MASK;
0633 ip22zilog_maybe_update_regs(up, channel);
0634 }
0635
0636
0637 static void ip22zilog_enable_ms(struct uart_port *port)
0638 {
0639 struct uart_ip22zilog_port *up =
0640 container_of(port, struct uart_ip22zilog_port, port);
0641 struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0642 unsigned char new_reg;
0643
0644 new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
0645 if (new_reg != up->curregs[R15]) {
0646 up->curregs[R15] = new_reg;
0647
0648
0649 write_zsreg(channel, R15, up->curregs[R15]);
0650 }
0651 }
0652
0653
0654 static void ip22zilog_break_ctl(struct uart_port *port, int break_state)
0655 {
0656 struct uart_ip22zilog_port *up =
0657 container_of(port, struct uart_ip22zilog_port, port);
0658 struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0659 unsigned char set_bits, clear_bits, new_reg;
0660 unsigned long flags;
0661
0662 set_bits = clear_bits = 0;
0663
0664 if (break_state)
0665 set_bits |= SND_BRK;
0666 else
0667 clear_bits |= SND_BRK;
0668
0669 spin_lock_irqsave(&port->lock, flags);
0670
0671 new_reg = (up->curregs[R5] | set_bits) & ~clear_bits;
0672 if (new_reg != up->curregs[R5]) {
0673 up->curregs[R5] = new_reg;
0674
0675
0676 write_zsreg(channel, R5, up->curregs[R5]);
0677 }
0678
0679 spin_unlock_irqrestore(&port->lock, flags);
0680 }
0681
0682 static void __ip22zilog_reset(struct uart_ip22zilog_port *up)
0683 {
0684 struct zilog_channel *channel;
0685 int i;
0686
0687 if (up->flags & IP22ZILOG_FLAG_RESET_DONE)
0688 return;
0689
0690
0691 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
0692 for (i = 0; i < 1000; i++) {
0693 unsigned char stat = read_zsreg(channel, R1);
0694 if (stat & ALL_SNT)
0695 break;
0696 udelay(100);
0697 }
0698
0699 if (!ZS_IS_CHANNEL_A(up)) {
0700 up++;
0701 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
0702 }
0703 write_zsreg(channel, R9, FHWRES);
0704 ZSDELAY_LONG();
0705 (void) read_zsreg(channel, R0);
0706
0707 up->flags |= IP22ZILOG_FLAG_RESET_DONE;
0708 up->next->flags |= IP22ZILOG_FLAG_RESET_DONE;
0709 }
0710
0711 static void __ip22zilog_startup(struct uart_ip22zilog_port *up)
0712 {
0713 struct zilog_channel *channel;
0714
0715 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
0716
0717 __ip22zilog_reset(up);
0718
0719 __load_zsregs(channel, up->curregs);
0720
0721 write_zsreg(channel, R9, up->curregs[R9]);
0722 up->prev_status = readb(&channel->control);
0723
0724
0725 up->curregs[R3] |= RxENAB;
0726 up->curregs[R5] |= TxENAB;
0727
0728 up->curregs[R1] |= EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
0729 ip22zilog_maybe_update_regs(up, channel);
0730 }
0731
0732 static int ip22zilog_startup(struct uart_port *port)
0733 {
0734 struct uart_ip22zilog_port *up = UART_ZILOG(port);
0735 unsigned long flags;
0736
0737 if (ZS_IS_CONS(up))
0738 return 0;
0739
0740 spin_lock_irqsave(&port->lock, flags);
0741 __ip22zilog_startup(up);
0742 spin_unlock_irqrestore(&port->lock, flags);
0743 return 0;
0744 }
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771 static void ip22zilog_shutdown(struct uart_port *port)
0772 {
0773 struct uart_ip22zilog_port *up = UART_ZILOG(port);
0774 struct zilog_channel *channel;
0775 unsigned long flags;
0776
0777 if (ZS_IS_CONS(up))
0778 return;
0779
0780 spin_lock_irqsave(&port->lock, flags);
0781
0782 channel = ZILOG_CHANNEL_FROM_PORT(port);
0783
0784
0785 up->curregs[R3] &= ~RxENAB;
0786 up->curregs[R5] &= ~TxENAB;
0787
0788
0789 up->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
0790 up->curregs[R5] &= ~SND_BRK;
0791 ip22zilog_maybe_update_regs(up, channel);
0792
0793 spin_unlock_irqrestore(&port->lock, flags);
0794 }
0795
0796
0797
0798
0799 static void
0800 ip22zilog_convert_to_zs(struct uart_ip22zilog_port *up, unsigned int cflag,
0801 unsigned int iflag, int brg)
0802 {
0803
0804 up->curregs[R10] = NRZ;
0805 up->curregs[R11] = TCBR | RCBR;
0806
0807
0808 up->curregs[R4] &= ~XCLK_MASK;
0809 up->curregs[R4] |= X16CLK;
0810 up->curregs[R12] = brg & 0xff;
0811 up->curregs[R13] = (brg >> 8) & 0xff;
0812 up->curregs[R14] = BRENAB;
0813
0814
0815 up->curregs[3] &= ~RxN_MASK;
0816 up->curregs[5] &= ~TxN_MASK;
0817 switch (cflag & CSIZE) {
0818 case CS5:
0819 up->curregs[3] |= Rx5;
0820 up->curregs[5] |= Tx5;
0821 up->parity_mask = 0x1f;
0822 break;
0823 case CS6:
0824 up->curregs[3] |= Rx6;
0825 up->curregs[5] |= Tx6;
0826 up->parity_mask = 0x3f;
0827 break;
0828 case CS7:
0829 up->curregs[3] |= Rx7;
0830 up->curregs[5] |= Tx7;
0831 up->parity_mask = 0x7f;
0832 break;
0833 case CS8:
0834 default:
0835 up->curregs[3] |= Rx8;
0836 up->curregs[5] |= Tx8;
0837 up->parity_mask = 0xff;
0838 break;
0839 }
0840 up->curregs[4] &= ~0x0c;
0841 if (cflag & CSTOPB)
0842 up->curregs[4] |= SB2;
0843 else
0844 up->curregs[4] |= SB1;
0845 if (cflag & PARENB)
0846 up->curregs[4] |= PAR_ENAB;
0847 else
0848 up->curregs[4] &= ~PAR_ENAB;
0849 if (!(cflag & PARODD))
0850 up->curregs[4] |= PAR_EVEN;
0851 else
0852 up->curregs[4] &= ~PAR_EVEN;
0853
0854 up->port.read_status_mask = Rx_OVR;
0855 if (iflag & INPCK)
0856 up->port.read_status_mask |= CRC_ERR | PAR_ERR;
0857 if (iflag & (IGNBRK | BRKINT | PARMRK))
0858 up->port.read_status_mask |= BRK_ABRT;
0859
0860 up->port.ignore_status_mask = 0;
0861 if (iflag & IGNPAR)
0862 up->port.ignore_status_mask |= CRC_ERR | PAR_ERR;
0863 if (iflag & IGNBRK) {
0864 up->port.ignore_status_mask |= BRK_ABRT;
0865 if (iflag & IGNPAR)
0866 up->port.ignore_status_mask |= Rx_OVR;
0867 }
0868
0869 if ((cflag & CREAD) == 0)
0870 up->port.ignore_status_mask = 0xff;
0871 }
0872
0873
0874 static void
0875 ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios,
0876 struct ktermios *old)
0877 {
0878 struct uart_ip22zilog_port *up =
0879 container_of(port, struct uart_ip22zilog_port, port);
0880 unsigned long flags;
0881 int baud, brg;
0882
0883 baud = uart_get_baud_rate(port, termios, old, 1200, 76800);
0884
0885 spin_lock_irqsave(&up->port.lock, flags);
0886
0887 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
0888
0889 ip22zilog_convert_to_zs(up, termios->c_cflag, termios->c_iflag, brg);
0890
0891 if (UART_ENABLE_MS(&up->port, termios->c_cflag))
0892 up->flags |= IP22ZILOG_FLAG_MODEM_STATUS;
0893 else
0894 up->flags &= ~IP22ZILOG_FLAG_MODEM_STATUS;
0895
0896 ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
0897 uart_update_timeout(port, termios->c_cflag, baud);
0898
0899 spin_unlock_irqrestore(&up->port.lock, flags);
0900 }
0901
0902 static const char *ip22zilog_type(struct uart_port *port)
0903 {
0904 return "IP22-Zilog";
0905 }
0906
0907
0908
0909
0910 static void ip22zilog_release_port(struct uart_port *port)
0911 {
0912 }
0913
0914 static int ip22zilog_request_port(struct uart_port *port)
0915 {
0916 return 0;
0917 }
0918
0919
0920 static void ip22zilog_config_port(struct uart_port *port, int flags)
0921 {
0922 }
0923
0924
0925 static int ip22zilog_verify_port(struct uart_port *port, struct serial_struct *ser)
0926 {
0927 return -EINVAL;
0928 }
0929
0930 static const struct uart_ops ip22zilog_pops = {
0931 .tx_empty = ip22zilog_tx_empty,
0932 .set_mctrl = ip22zilog_set_mctrl,
0933 .get_mctrl = ip22zilog_get_mctrl,
0934 .stop_tx = ip22zilog_stop_tx,
0935 .start_tx = ip22zilog_start_tx,
0936 .stop_rx = ip22zilog_stop_rx,
0937 .enable_ms = ip22zilog_enable_ms,
0938 .break_ctl = ip22zilog_break_ctl,
0939 .startup = ip22zilog_startup,
0940 .shutdown = ip22zilog_shutdown,
0941 .set_termios = ip22zilog_set_termios,
0942 .type = ip22zilog_type,
0943 .release_port = ip22zilog_release_port,
0944 .request_port = ip22zilog_request_port,
0945 .config_port = ip22zilog_config_port,
0946 .verify_port = ip22zilog_verify_port,
0947 };
0948
0949 static struct uart_ip22zilog_port *ip22zilog_port_table;
0950 static struct zilog_layout **ip22zilog_chip_regs;
0951
0952 static struct uart_ip22zilog_port *ip22zilog_irq_chain;
0953 static int zilog_irq = -1;
0954
0955 static void * __init alloc_one_table(unsigned long size)
0956 {
0957 return kzalloc(size, GFP_KERNEL);
0958 }
0959
0960 static void __init ip22zilog_alloc_tables(void)
0961 {
0962 ip22zilog_port_table = (struct uart_ip22zilog_port *)
0963 alloc_one_table(NUM_CHANNELS * sizeof(struct uart_ip22zilog_port));
0964 ip22zilog_chip_regs = (struct zilog_layout **)
0965 alloc_one_table(NUM_IP22ZILOG * sizeof(struct zilog_layout *));
0966
0967 if (ip22zilog_port_table == NULL || ip22zilog_chip_regs == NULL) {
0968 panic("IP22-Zilog: Cannot allocate IP22-Zilog tables.");
0969 }
0970 }
0971
0972
0973 static struct zilog_layout * __init get_zs(int chip)
0974 {
0975 unsigned long base;
0976
0977 if (chip < 0 || chip >= NUM_IP22ZILOG) {
0978 panic("IP22-Zilog: Illegal chip number %d in get_zs.", chip);
0979 }
0980
0981
0982 base = (unsigned long) &sgioc->uart;
0983
0984 zilog_irq = SGI_SERIAL_IRQ;
0985 request_mem_region(base, 8, "IP22-Zilog");
0986
0987 return (struct zilog_layout *) base;
0988 }
0989
0990 #define ZS_PUT_CHAR_MAX_DELAY 2000
0991
0992 #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
0993 static void ip22zilog_put_char(struct uart_port *port, unsigned char ch)
0994 {
0995 struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0996 int loops = ZS_PUT_CHAR_MAX_DELAY;
0997
0998
0999
1000
1001 do {
1002 unsigned char val = readb(&channel->control);
1003 if (val & Tx_BUF_EMP) {
1004 ZSDELAY();
1005 break;
1006 }
1007 udelay(5);
1008 } while (--loops);
1009
1010 writeb(ch, &channel->data);
1011 ZSDELAY();
1012 ZS_WSYNC(channel);
1013 }
1014
1015 static void
1016 ip22zilog_console_write(struct console *con, const char *s, unsigned int count)
1017 {
1018 struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
1019 unsigned long flags;
1020
1021 spin_lock_irqsave(&up->port.lock, flags);
1022 uart_console_write(&up->port, s, count, ip22zilog_put_char);
1023 udelay(2);
1024 spin_unlock_irqrestore(&up->port.lock, flags);
1025 }
1026
1027 static int __init ip22zilog_console_setup(struct console *con, char *options)
1028 {
1029 struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
1030 unsigned long flags;
1031 int baud = 9600, bits = 8;
1032 int parity = 'n';
1033 int flow = 'n';
1034
1035 up->flags |= IP22ZILOG_FLAG_IS_CONS;
1036
1037 printk(KERN_INFO "Console: ttyS%d (IP22-Zilog)\n", con->index);
1038
1039 spin_lock_irqsave(&up->port.lock, flags);
1040
1041 up->curregs[R15] |= BRKIE;
1042
1043 __ip22zilog_startup(up);
1044
1045 spin_unlock_irqrestore(&up->port.lock, flags);
1046
1047 if (options)
1048 uart_parse_options(options, &baud, &parity, &bits, &flow);
1049 return uart_set_options(&up->port, con, baud, parity, bits, flow);
1050 }
1051
1052 static struct uart_driver ip22zilog_reg;
1053
1054 static struct console ip22zilog_console = {
1055 .name = "ttyS",
1056 .write = ip22zilog_console_write,
1057 .device = uart_console_device,
1058 .setup = ip22zilog_console_setup,
1059 .flags = CON_PRINTBUFFER,
1060 .index = -1,
1061 .data = &ip22zilog_reg,
1062 };
1063 #endif
1064
1065 static struct uart_driver ip22zilog_reg = {
1066 .owner = THIS_MODULE,
1067 .driver_name = "serial",
1068 .dev_name = "ttyS",
1069 .major = TTY_MAJOR,
1070 .minor = 64,
1071 .nr = NUM_CHANNELS,
1072 #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
1073 .cons = &ip22zilog_console,
1074 #endif
1075 };
1076
1077 static void __init ip22zilog_prepare(void)
1078 {
1079 unsigned char sysrq_on = IS_ENABLED(CONFIG_SERIAL_IP22_ZILOG_CONSOLE);
1080 struct uart_ip22zilog_port *up;
1081 struct zilog_layout *rp;
1082 int channel, chip;
1083
1084
1085
1086
1087 for (channel = 0; channel < NUM_CHANNELS; channel++)
1088 spin_lock_init(&ip22zilog_port_table[channel].port.lock);
1089
1090 ip22zilog_irq_chain = &ip22zilog_port_table[NUM_CHANNELS - 1];
1091 up = &ip22zilog_port_table[0];
1092 for (channel = NUM_CHANNELS - 1 ; channel > 0; channel--)
1093 up[channel].next = &up[channel - 1];
1094 up[channel].next = NULL;
1095
1096 for (chip = 0; chip < NUM_IP22ZILOG; chip++) {
1097 if (!ip22zilog_chip_regs[chip]) {
1098 ip22zilog_chip_regs[chip] = rp = get_zs(chip);
1099
1100 up[(chip * 2) + 0].port.membase = (char *) &rp->channelB;
1101 up[(chip * 2) + 1].port.membase = (char *) &rp->channelA;
1102
1103
1104 up[(chip * 2) + 0].port.mapbase =
1105 (unsigned long) ioremap((unsigned long) &rp->channelB, 8);
1106 up[(chip * 2) + 1].port.mapbase =
1107 (unsigned long) ioremap((unsigned long) &rp->channelA, 8);
1108 }
1109
1110
1111 up[(chip * 2) + 0].port.iotype = UPIO_MEM;
1112 up[(chip * 2) + 0].port.irq = zilog_irq;
1113 up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
1114 up[(chip * 2) + 0].port.fifosize = 1;
1115 up[(chip * 2) + 0].port.has_sysrq = sysrq_on;
1116 up[(chip * 2) + 0].port.ops = &ip22zilog_pops;
1117 up[(chip * 2) + 0].port.type = PORT_IP22ZILOG;
1118 up[(chip * 2) + 0].port.flags = 0;
1119 up[(chip * 2) + 0].port.line = (chip * 2) + 0;
1120 up[(chip * 2) + 0].flags = 0;
1121
1122
1123 up[(chip * 2) + 1].port.iotype = UPIO_MEM;
1124 up[(chip * 2) + 1].port.irq = zilog_irq;
1125 up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
1126 up[(chip * 2) + 1].port.fifosize = 1;
1127 up[(chip * 2) + 1].port.has_sysrq = sysrq_on;
1128 up[(chip * 2) + 1].port.ops = &ip22zilog_pops;
1129 up[(chip * 2) + 1].port.type = PORT_IP22ZILOG;
1130 up[(chip * 2) + 1].port.line = (chip * 2) + 1;
1131 up[(chip * 2) + 1].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
1132 }
1133
1134 for (channel = 0; channel < NUM_CHANNELS; channel++) {
1135 struct uart_ip22zilog_port *up = &ip22zilog_port_table[channel];
1136 int brg;
1137
1138
1139 up->parity_mask = 0xff;
1140 up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
1141 up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
1142 up->curregs[R3] = RxENAB | Rx8;
1143 up->curregs[R5] = TxENAB | Tx8;
1144 up->curregs[R9] = NV | MIE;
1145 up->curregs[R10] = NRZ;
1146 up->curregs[R11] = TCBR | RCBR;
1147 brg = BPS_TO_BRG(9600, ZS_CLOCK / ZS_CLOCK_DIVISOR);
1148 up->curregs[R12] = (brg & 0xff);
1149 up->curregs[R13] = (brg >> 8) & 0xff;
1150 up->curregs[R14] = BRENAB;
1151 }
1152 }
1153
1154 static int __init ip22zilog_ports_init(void)
1155 {
1156 int ret;
1157
1158 printk(KERN_INFO "Serial: IP22 Zilog driver (%d chips).\n", NUM_IP22ZILOG);
1159
1160 ip22zilog_prepare();
1161
1162 if (request_irq(zilog_irq, ip22zilog_interrupt, 0,
1163 "IP22-Zilog", ip22zilog_irq_chain)) {
1164 panic("IP22-Zilog: Unable to register zs interrupt handler.\n");
1165 }
1166
1167 ret = uart_register_driver(&ip22zilog_reg);
1168 if (ret == 0) {
1169 int i;
1170
1171 for (i = 0; i < NUM_CHANNELS; i++) {
1172 struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];
1173
1174 uart_add_one_port(&ip22zilog_reg, &up->port);
1175 }
1176 }
1177
1178 return ret;
1179 }
1180
1181 static int __init ip22zilog_init(void)
1182 {
1183
1184 ip22zilog_alloc_tables();
1185 ip22zilog_ports_init();
1186
1187 return 0;
1188 }
1189
1190 static void __exit ip22zilog_exit(void)
1191 {
1192 int i;
1193 struct uart_ip22zilog_port *up;
1194
1195 for (i = 0; i < NUM_CHANNELS; i++) {
1196 up = &ip22zilog_port_table[i];
1197
1198 uart_remove_one_port(&ip22zilog_reg, &up->port);
1199 }
1200
1201
1202 up = &ip22zilog_port_table[0];
1203 for (i = 0; i < NUM_IP22ZILOG; i++) {
1204 if (up[(i * 2) + 0].port.mapbase) {
1205 iounmap((void*)up[(i * 2) + 0].port.mapbase);
1206 up[(i * 2) + 0].port.mapbase = 0;
1207 }
1208 if (up[(i * 2) + 1].port.mapbase) {
1209 iounmap((void*)up[(i * 2) + 1].port.mapbase);
1210 up[(i * 2) + 1].port.mapbase = 0;
1211 }
1212 }
1213
1214 uart_unregister_driver(&ip22zilog_reg);
1215 }
1216
1217 module_init(ip22zilog_init);
1218 module_exit(ip22zilog_exit);
1219
1220
1221 MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
1222 MODULE_DESCRIPTION("SGI Zilog serial port driver");
1223 MODULE_LICENSE("GPL");