sunzilog.c (92a19f9cec9a80ad93c06e115822deb729e2c6ad) sunzilog.c (2e124b4a390ca85325fae75764bef92f0547fa25)
1/* sunzilog.c: Zilog serial driver for Sparc systems.
2 *
3 * Driver for Zilog serial chips found on Sun workstations and
4 * servers. This driver could actually be made more generic.
5 *
6 * This is based on the old drivers/sbus/char/zs.c code. A lot
7 * of code has been simply moved over directly from there but
8 * much has been rewritten. Credits therefore go out to Eddie

--- 309 unchanged lines hidden (view full) ---

318 if (up->serio_open)
319 serio_interrupt(&up->serio, ch, 0);
320#endif
321 break;
322 };
323 }
324}
325
1/* sunzilog.c: Zilog serial driver for Sparc systems.
2 *
3 * Driver for Zilog serial chips found on Sun workstations and
4 * servers. This driver could actually be made more generic.
5 *
6 * This is based on the old drivers/sbus/char/zs.c code. A lot
7 * of code has been simply moved over directly from there but
8 * much has been rewritten. Credits therefore go out to Eddie

--- 309 unchanged lines hidden (view full) ---

318 if (up->serio_open)
319 serio_interrupt(&up->serio, ch, 0);
320#endif
321 break;
322 };
323 }
324}
325
326static struct tty_struct *
326static struct tty_port *
327sunzilog_receive_chars(struct uart_sunzilog_port *up,
328 struct zilog_channel __iomem *channel)
329{
330 struct tty_port *port = NULL;
327sunzilog_receive_chars(struct uart_sunzilog_port *up,
328 struct zilog_channel __iomem *channel)
329{
330 struct tty_port *port = NULL;
331 struct tty_struct *tty;
332 unsigned char ch, r1, flag;
333
331 unsigned char ch, r1, flag;
332
334 tty = NULL;
335 if (up->port.state != NULL) { /* Unopened serial console */
333 if (up->port.state != NULL) /* Unopened serial console */
336 port = &up->port.state->port;
334 port = &up->port.state->port;
337 tty = port->tty; /* mouse => tty is NULL */
338 }
339
340 for (;;) {
341
342 r1 = read_zsreg(channel, R1);
343 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
344 writeb(ERR_RES, &channel->control);
345 ZSDELAY();
346 ZS_WSYNC(channel);

--- 51 unchanged lines hidden (view full) ---

398 if (up->port.ignore_status_mask == 0xff ||
399 (r1 & up->port.ignore_status_mask) == 0) {
400 tty_insert_flip_char(port, ch, flag);
401 }
402 if (r1 & Rx_OVR)
403 tty_insert_flip_char(port, 0, TTY_OVERRUN);
404 }
405
335
336 for (;;) {
337
338 r1 = read_zsreg(channel, R1);
339 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
340 writeb(ERR_RES, &channel->control);
341 ZSDELAY();
342 ZS_WSYNC(channel);

--- 51 unchanged lines hidden (view full) ---

394 if (up->port.ignore_status_mask == 0xff ||
395 (r1 & up->port.ignore_status_mask) == 0) {
396 tty_insert_flip_char(port, ch, flag);
397 }
398 if (r1 & Rx_OVR)
399 tty_insert_flip_char(port, 0, TTY_OVERRUN);
400 }
401
406 return tty;
402 return port;
407}
408
409static void sunzilog_status_handle(struct uart_sunzilog_port *up,
410 struct zilog_channel __iomem *channel)
411{
412 unsigned char status;
413
414 status = readb(&channel->control);

--- 116 unchanged lines hidden (view full) ---

531
532static irqreturn_t sunzilog_interrupt(int irq, void *dev_id)
533{
534 struct uart_sunzilog_port *up = dev_id;
535
536 while (up) {
537 struct zilog_channel __iomem *channel
538 = ZILOG_CHANNEL_FROM_PORT(&up->port);
403}
404
405static void sunzilog_status_handle(struct uart_sunzilog_port *up,
406 struct zilog_channel __iomem *channel)
407{
408 unsigned char status;
409
410 status = readb(&channel->control);

--- 116 unchanged lines hidden (view full) ---

527
528static irqreturn_t sunzilog_interrupt(int irq, void *dev_id)
529{
530 struct uart_sunzilog_port *up = dev_id;
531
532 while (up) {
533 struct zilog_channel __iomem *channel
534 = ZILOG_CHANNEL_FROM_PORT(&up->port);
539 struct tty_struct *tty;
535 struct tty_port *port;
540 unsigned char r3;
541
542 spin_lock(&up->port.lock);
543 r3 = read_zsreg(channel, R3);
544
545 /* Channel A */
536 unsigned char r3;
537
538 spin_lock(&up->port.lock);
539 r3 = read_zsreg(channel, R3);
540
541 /* Channel A */
546 tty = NULL;
542 port = NULL;
547 if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
548 writeb(RES_H_IUS, &channel->control);
549 ZSDELAY();
550 ZS_WSYNC(channel);
551
552 if (r3 & CHARxIP)
543 if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
544 writeb(RES_H_IUS, &channel->control);
545 ZSDELAY();
546 ZS_WSYNC(channel);
547
548 if (r3 & CHARxIP)
553 tty = sunzilog_receive_chars(up, channel);
549 port = sunzilog_receive_chars(up, channel);
554 if (r3 & CHAEXT)
555 sunzilog_status_handle(up, channel);
556 if (r3 & CHATxIP)
557 sunzilog_transmit_chars(up, channel);
558 }
559 spin_unlock(&up->port.lock);
560
550 if (r3 & CHAEXT)
551 sunzilog_status_handle(up, channel);
552 if (r3 & CHATxIP)
553 sunzilog_transmit_chars(up, channel);
554 }
555 spin_unlock(&up->port.lock);
556
561 if (tty)
562 tty_flip_buffer_push(tty);
557 if (port)
558 tty_flip_buffer_push(port);
563
564 /* Channel B */
565 up = up->next;
566 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
567
568 spin_lock(&up->port.lock);
559
560 /* Channel B */
561 up = up->next;
562 channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
563
564 spin_lock(&up->port.lock);
569 tty = NULL;
565 port = NULL;
570 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
571 writeb(RES_H_IUS, &channel->control);
572 ZSDELAY();
573 ZS_WSYNC(channel);
574
575 if (r3 & CHBRxIP)
566 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
567 writeb(RES_H_IUS, &channel->control);
568 ZSDELAY();
569 ZS_WSYNC(channel);
570
571 if (r3 & CHBRxIP)
576 tty = sunzilog_receive_chars(up, channel);
572 port = sunzilog_receive_chars(up, channel);
577 if (r3 & CHBEXT)
578 sunzilog_status_handle(up, channel);
579 if (r3 & CHBTxIP)
580 sunzilog_transmit_chars(up, channel);
581 }
582 spin_unlock(&up->port.lock);
583
573 if (r3 & CHBEXT)
574 sunzilog_status_handle(up, channel);
575 if (r3 & CHBTxIP)
576 sunzilog_transmit_chars(up, channel);
577 }
578 spin_unlock(&up->port.lock);
579
584 if (tty)
585 tty_flip_buffer_push(tty);
580 if (port)
581 tty_flip_buffer_push(port);
586
587 up = up->next;
588 }
589
590 return IRQ_HANDLED;
591}
592
593/* A convenient way to quickly get R0 status. The caller must _not_ hold the

--- 1060 unchanged lines hidden ---
582
583 up = up->next;
584 }
585
586 return IRQ_HANDLED;
587}
588
589/* A convenient way to quickly get R0 status. The caller must _not_ hold the

--- 1060 unchanged lines hidden ---