diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/Kconfig | 2 | ||||
-rw-r--r-- | drivers/tty/serial/amba-pl010.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/amba-pl011.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/pmac_zilog.c | 423 | ||||
-rw-r--r-- | drivers/tty/serial/pmac_zilog.h | 19 | ||||
-rw-r--r-- | drivers/tty/serial/ucc_uart.c | 3 | ||||
-rw-r--r-- | drivers/tty/sysrq.c | 2 | ||||
-rw-r--r-- | drivers/tty/tty_io.c | 2 |
8 files changed, 151 insertions, 304 deletions
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index d1e4f203ae61..113fccf82517 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -834,7 +834,7 @@ config BFIN_UART3_CTSRTS | |||
834 | 834 | ||
835 | config SERIAL_IMX | 835 | config SERIAL_IMX |
836 | bool "IMX serial port support" | 836 | bool "IMX serial port support" |
837 | depends on ARM && (ARCH_IMX || ARCH_MXC) | 837 | depends on ARCH_MXC |
838 | select SERIAL_CORE | 838 | select SERIAL_CORE |
839 | select RATIONAL | 839 | select RATIONAL |
840 | help | 840 | help |
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index efdf92c3a352..0d91a540bf11 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c | |||
@@ -795,6 +795,8 @@ static struct amba_id pl010_ids[] = { | |||
795 | { 0, 0 }, | 795 | { 0, 0 }, |
796 | }; | 796 | }; |
797 | 797 | ||
798 | MODULE_DEVICE_TABLE(amba, pl010_ids); | ||
799 | |||
798 | static struct amba_driver pl010_driver = { | 800 | static struct amba_driver pl010_driver = { |
799 | .drv = { | 801 | .drv = { |
800 | .name = "uart-pl010", | 802 | .name = "uart-pl010", |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 00233af1acc4..6958594f2fc0 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -1994,6 +1994,8 @@ static struct amba_id pl011_ids[] = { | |||
1994 | { 0, 0 }, | 1994 | { 0, 0 }, |
1995 | }; | 1995 | }; |
1996 | 1996 | ||
1997 | MODULE_DEVICE_TABLE(amba, pl011_ids); | ||
1998 | |||
1997 | static struct amba_driver pl011_driver = { | 1999 | static struct amba_driver pl011_driver = { |
1998 | .drv = { | 2000 | .drv = { |
1999 | .name = "uart-pl011", | 2001 | .name = "uart-pl011", |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 5acd24a27d08..e9c2dfe471a2 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -99,6 +99,9 @@ MODULE_LICENSE("GPL"); | |||
99 | #define PMACZILOG_NAME "ttyPZ" | 99 | #define PMACZILOG_NAME "ttyPZ" |
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | #define pmz_debug(fmt, arg...) pr_debug("ttyPZ%d: " fmt, uap->port.line, ## arg) | ||
103 | #define pmz_error(fmt, arg...) pr_err("ttyPZ%d: " fmt, uap->port.line, ## arg) | ||
104 | #define pmz_info(fmt, arg...) pr_info("ttyPZ%d: " fmt, uap->port.line, ## arg) | ||
102 | 105 | ||
103 | /* | 106 | /* |
104 | * For the sake of early serial console, we can do a pre-probe | 107 | * For the sake of early serial console, we can do a pre-probe |
@@ -106,7 +109,6 @@ MODULE_LICENSE("GPL"); | |||
106 | */ | 109 | */ |
107 | static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS]; | 110 | static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS]; |
108 | static int pmz_ports_count; | 111 | static int pmz_ports_count; |
109 | static DEFINE_MUTEX(pmz_irq_mutex); | ||
110 | 112 | ||
111 | static struct uart_driver pmz_uart_reg = { | 113 | static struct uart_driver pmz_uart_reg = { |
112 | .owner = THIS_MODULE, | 114 | .owner = THIS_MODULE, |
@@ -126,9 +128,6 @@ static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs) | |||
126 | { | 128 | { |
127 | int i; | 129 | int i; |
128 | 130 | ||
129 | if (ZS_IS_ASLEEP(uap)) | ||
130 | return; | ||
131 | |||
132 | /* Let pending transmits finish. */ | 131 | /* Let pending transmits finish. */ |
133 | for (i = 0; i < 1000; i++) { | 132 | for (i = 0; i < 1000; i++) { |
134 | unsigned char stat = read_zsreg(uap, R1); | 133 | unsigned char stat = read_zsreg(uap, R1); |
@@ -216,32 +215,24 @@ static void pmz_maybe_update_regs(struct uart_pmac_port *uap) | |||
216 | } | 215 | } |
217 | } | 216 | } |
218 | 217 | ||
218 | static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable) | ||
219 | { | ||
220 | if (enable) { | ||
221 | uap->curregs[1] |= INT_ALL_Rx | TxINT_ENAB; | ||
222 | if (!ZS_IS_EXTCLK(uap)) | ||
223 | uap->curregs[1] |= EXT_INT_ENAB; | ||
224 | } else { | ||
225 | uap->curregs[1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); | ||
226 | } | ||
227 | write_zsreg(uap, R1, uap->curregs[1]); | ||
228 | } | ||
229 | |||
219 | static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | 230 | static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) |
220 | { | 231 | { |
221 | struct tty_struct *tty = NULL; | 232 | struct tty_struct *tty = NULL; |
222 | unsigned char ch, r1, drop, error, flag; | 233 | unsigned char ch, r1, drop, error, flag; |
223 | int loops = 0; | 234 | int loops = 0; |
224 | 235 | ||
225 | /* The interrupt can be enabled when the port isn't open, typically | ||
226 | * that happens when using one port is open and the other closed (stale | ||
227 | * interrupt) or when one port is used as a console. | ||
228 | */ | ||
229 | if (!ZS_IS_OPEN(uap)) { | ||
230 | pmz_debug("pmz: draining input\n"); | ||
231 | /* Port is closed, drain input data */ | ||
232 | for (;;) { | ||
233 | if ((++loops) > 1000) | ||
234 | goto flood; | ||
235 | (void)read_zsreg(uap, R1); | ||
236 | write_zsreg(uap, R0, ERR_RES); | ||
237 | (void)read_zsdata(uap); | ||
238 | ch = read_zsreg(uap, R0); | ||
239 | if (!(ch & Rx_CH_AV)) | ||
240 | break; | ||
241 | } | ||
242 | return NULL; | ||
243 | } | ||
244 | |||
245 | /* Sanity check, make sure the old bug is no longer happening */ | 236 | /* Sanity check, make sure the old bug is no longer happening */ |
246 | if (uap->port.state == NULL || uap->port.state->port.tty == NULL) { | 237 | if (uap->port.state == NULL || uap->port.state->port.tty == NULL) { |
247 | WARN_ON(1); | 238 | WARN_ON(1); |
@@ -339,9 +330,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
339 | 330 | ||
340 | return tty; | 331 | return tty; |
341 | flood: | 332 | flood: |
342 | uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); | 333 | pmz_interrupt_control(uap, 0); |
343 | write_zsreg(uap, R1, uap->curregs[R1]); | ||
344 | zssync(uap); | ||
345 | pmz_error("pmz: rx irq flood !\n"); | 334 | pmz_error("pmz: rx irq flood !\n"); |
346 | return tty; | 335 | return tty; |
347 | } | 336 | } |
@@ -383,8 +372,6 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap) | |||
383 | { | 372 | { |
384 | struct circ_buf *xmit; | 373 | struct circ_buf *xmit; |
385 | 374 | ||
386 | if (ZS_IS_ASLEEP(uap)) | ||
387 | return; | ||
388 | if (ZS_IS_CONS(uap)) { | 375 | if (ZS_IS_CONS(uap)) { |
389 | unsigned char status = read_zsreg(uap, R0); | 376 | unsigned char status = read_zsreg(uap, R0); |
390 | 377 | ||
@@ -481,6 +468,10 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
481 | /* Channel A */ | 468 | /* Channel A */ |
482 | tty = NULL; | 469 | tty = NULL; |
483 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
471 | if (!ZS_IS_OPEN(uap_a)) { | ||
472 | pmz_debug("ChanA interrupt while open !\n"); | ||
473 | goto skip_a; | ||
474 | } | ||
484 | write_zsreg(uap_a, R0, RES_H_IUS); | 475 | write_zsreg(uap_a, R0, RES_H_IUS); |
485 | zssync(uap_a); | 476 | zssync(uap_a); |
486 | if (r3 & CHAEXT) | 477 | if (r3 & CHAEXT) |
@@ -491,16 +482,21 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
491 | pmz_transmit_chars(uap_a); | 482 | pmz_transmit_chars(uap_a); |
492 | rc = IRQ_HANDLED; | 483 | rc = IRQ_HANDLED; |
493 | } | 484 | } |
485 | skip_a: | ||
494 | spin_unlock(&uap_a->port.lock); | 486 | spin_unlock(&uap_a->port.lock); |
495 | if (tty != NULL) | 487 | if (tty != NULL) |
496 | tty_flip_buffer_push(tty); | 488 | tty_flip_buffer_push(tty); |
497 | 489 | ||
498 | if (uap_b->node == NULL) | 490 | if (!uap_b) |
499 | goto out; | 491 | goto out; |
500 | 492 | ||
501 | spin_lock(&uap_b->port.lock); | 493 | spin_lock(&uap_b->port.lock); |
502 | tty = NULL; | 494 | tty = NULL; |
503 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
496 | if (!ZS_IS_OPEN(uap_a)) { | ||
497 | pmz_debug("ChanB interrupt while open !\n"); | ||
498 | goto skip_b; | ||
499 | } | ||
504 | write_zsreg(uap_b, R0, RES_H_IUS); | 500 | write_zsreg(uap_b, R0, RES_H_IUS); |
505 | zssync(uap_b); | 501 | zssync(uap_b); |
506 | if (r3 & CHBEXT) | 502 | if (r3 & CHBEXT) |
@@ -511,14 +507,12 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
511 | pmz_transmit_chars(uap_b); | 507 | pmz_transmit_chars(uap_b); |
512 | rc = IRQ_HANDLED; | 508 | rc = IRQ_HANDLED; |
513 | } | 509 | } |
510 | skip_b: | ||
514 | spin_unlock(&uap_b->port.lock); | 511 | spin_unlock(&uap_b->port.lock); |
515 | if (tty != NULL) | 512 | if (tty != NULL) |
516 | tty_flip_buffer_push(tty); | 513 | tty_flip_buffer_push(tty); |
517 | 514 | ||
518 | out: | 515 | out: |
519 | #ifdef DEBUG_HARD | ||
520 | pmz_debug("irq done.\n"); | ||
521 | #endif | ||
522 | return rc; | 516 | return rc; |
523 | } | 517 | } |
524 | 518 | ||
@@ -543,12 +537,8 @@ static inline u8 pmz_peek_status(struct uart_pmac_port *uap) | |||
543 | */ | 537 | */ |
544 | static unsigned int pmz_tx_empty(struct uart_port *port) | 538 | static unsigned int pmz_tx_empty(struct uart_port *port) |
545 | { | 539 | { |
546 | struct uart_pmac_port *uap = to_pmz(port); | ||
547 | unsigned char status; | 540 | unsigned char status; |
548 | 541 | ||
549 | if (ZS_IS_ASLEEP(uap) || uap->node == NULL) | ||
550 | return TIOCSER_TEMT; | ||
551 | |||
552 | status = pmz_peek_status(to_pmz(port)); | 542 | status = pmz_peek_status(to_pmz(port)); |
553 | if (status & Tx_BUF_EMP) | 543 | if (status & Tx_BUF_EMP) |
554 | return TIOCSER_TEMT; | 544 | return TIOCSER_TEMT; |
@@ -570,8 +560,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
570 | if (ZS_IS_IRDA(uap)) | 560 | if (ZS_IS_IRDA(uap)) |
571 | return; | 561 | return; |
572 | /* We get called during boot with a port not up yet */ | 562 | /* We get called during boot with a port not up yet */ |
573 | if (ZS_IS_ASLEEP(uap) || | 563 | if (!(ZS_IS_OPEN(uap) || ZS_IS_CONS(uap))) |
574 | !(ZS_IS_OPEN(uap) || ZS_IS_CONS(uap))) | ||
575 | return; | 564 | return; |
576 | 565 | ||
577 | set_bits = clear_bits = 0; | 566 | set_bits = clear_bits = 0; |
@@ -590,8 +579,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
590 | /* NOTE: Not subject to 'transmitter active' rule. */ | 579 | /* NOTE: Not subject to 'transmitter active' rule. */ |
591 | uap->curregs[R5] |= set_bits; | 580 | uap->curregs[R5] |= set_bits; |
592 | uap->curregs[R5] &= ~clear_bits; | 581 | uap->curregs[R5] &= ~clear_bits; |
593 | if (ZS_IS_ASLEEP(uap)) | 582 | |
594 | return; | ||
595 | write_zsreg(uap, R5, uap->curregs[R5]); | 583 | write_zsreg(uap, R5, uap->curregs[R5]); |
596 | pmz_debug("pmz_set_mctrl: set bits: %x, clear bits: %x -> %x\n", | 584 | pmz_debug("pmz_set_mctrl: set bits: %x, clear bits: %x -> %x\n", |
597 | set_bits, clear_bits, uap->curregs[R5]); | 585 | set_bits, clear_bits, uap->curregs[R5]); |
@@ -609,9 +597,6 @@ static unsigned int pmz_get_mctrl(struct uart_port *port) | |||
609 | unsigned char status; | 597 | unsigned char status; |
610 | unsigned int ret; | 598 | unsigned int ret; |
611 | 599 | ||
612 | if (ZS_IS_ASLEEP(uap) || uap->node == NULL) | ||
613 | return 0; | ||
614 | |||
615 | status = read_zsreg(uap, R0); | 600 | status = read_zsreg(uap, R0); |
616 | 601 | ||
617 | ret = 0; | 602 | ret = 0; |
@@ -649,9 +634,6 @@ static void pmz_start_tx(struct uart_port *port) | |||
649 | uap->flags |= PMACZILOG_FLAG_TX_ACTIVE; | 634 | uap->flags |= PMACZILOG_FLAG_TX_ACTIVE; |
650 | uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED; | 635 | uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED; |
651 | 636 | ||
652 | if (ZS_IS_ASLEEP(uap) || uap->node == NULL) | ||
653 | return; | ||
654 | |||
655 | status = read_zsreg(uap, R0); | 637 | status = read_zsreg(uap, R0); |
656 | 638 | ||
657 | /* TX busy? Just wait for the TX done interrupt. */ | 639 | /* TX busy? Just wait for the TX done interrupt. */ |
@@ -690,9 +672,6 @@ static void pmz_stop_rx(struct uart_port *port) | |||
690 | { | 672 | { |
691 | struct uart_pmac_port *uap = to_pmz(port); | 673 | struct uart_pmac_port *uap = to_pmz(port); |
692 | 674 | ||
693 | if (ZS_IS_ASLEEP(uap) || uap->node == NULL) | ||
694 | return; | ||
695 | |||
696 | pmz_debug("pmz: stop_rx()()\n"); | 675 | pmz_debug("pmz: stop_rx()()\n"); |
697 | 676 | ||
698 | /* Disable all RX interrupts. */ | 677 | /* Disable all RX interrupts. */ |
@@ -711,14 +690,12 @@ static void pmz_enable_ms(struct uart_port *port) | |||
711 | struct uart_pmac_port *uap = to_pmz(port); | 690 | struct uart_pmac_port *uap = to_pmz(port); |
712 | unsigned char new_reg; | 691 | unsigned char new_reg; |
713 | 692 | ||
714 | if (ZS_IS_IRDA(uap) || uap->node == NULL) | 693 | if (ZS_IS_IRDA(uap)) |
715 | return; | 694 | return; |
716 | new_reg = uap->curregs[R15] | (DCDIE | SYNCIE | CTSIE); | 695 | new_reg = uap->curregs[R15] | (DCDIE | SYNCIE | CTSIE); |
717 | if (new_reg != uap->curregs[R15]) { | 696 | if (new_reg != uap->curregs[R15]) { |
718 | uap->curregs[R15] = new_reg; | 697 | uap->curregs[R15] = new_reg; |
719 | 698 | ||
720 | if (ZS_IS_ASLEEP(uap)) | ||
721 | return; | ||
722 | /* NOTE: Not subject to 'transmitter active' rule. */ | 699 | /* NOTE: Not subject to 'transmitter active' rule. */ |
723 | write_zsreg(uap, R15, uap->curregs[R15]); | 700 | write_zsreg(uap, R15, uap->curregs[R15]); |
724 | } | 701 | } |
@@ -734,8 +711,6 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) | |||
734 | unsigned char set_bits, clear_bits, new_reg; | 711 | unsigned char set_bits, clear_bits, new_reg; |
735 | unsigned long flags; | 712 | unsigned long flags; |
736 | 713 | ||
737 | if (uap->node == NULL) | ||
738 | return; | ||
739 | set_bits = clear_bits = 0; | 714 | set_bits = clear_bits = 0; |
740 | 715 | ||
741 | if (break_state) | 716 | if (break_state) |
@@ -748,12 +723,6 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) | |||
748 | new_reg = (uap->curregs[R5] | set_bits) & ~clear_bits; | 723 | new_reg = (uap->curregs[R5] | set_bits) & ~clear_bits; |
749 | if (new_reg != uap->curregs[R5]) { | 724 | if (new_reg != uap->curregs[R5]) { |
750 | uap->curregs[R5] = new_reg; | 725 | uap->curregs[R5] = new_reg; |
751 | |||
752 | /* NOTE: Not subject to 'transmitter active' rule. */ | ||
753 | if (ZS_IS_ASLEEP(uap)) { | ||
754 | spin_unlock_irqrestore(&port->lock, flags); | ||
755 | return; | ||
756 | } | ||
757 | write_zsreg(uap, R5, uap->curregs[R5]); | 726 | write_zsreg(uap, R5, uap->curregs[R5]); |
758 | } | 727 | } |
759 | 728 | ||
@@ -927,14 +896,21 @@ static int __pmz_startup(struct uart_pmac_port *uap) | |||
927 | 896 | ||
928 | static void pmz_irda_reset(struct uart_pmac_port *uap) | 897 | static void pmz_irda_reset(struct uart_pmac_port *uap) |
929 | { | 898 | { |
899 | unsigned long flags; | ||
900 | |||
901 | spin_lock_irqsave(&uap->port.lock, flags); | ||
930 | uap->curregs[R5] |= DTR; | 902 | uap->curregs[R5] |= DTR; |
931 | write_zsreg(uap, R5, uap->curregs[R5]); | 903 | write_zsreg(uap, R5, uap->curregs[R5]); |
932 | zssync(uap); | 904 | zssync(uap); |
933 | mdelay(110); | 905 | spin_unlock_irqrestore(&uap->port.lock, flags); |
906 | msleep(110); | ||
907 | |||
908 | spin_lock_irqsave(&uap->port.lock, flags); | ||
934 | uap->curregs[R5] &= ~DTR; | 909 | uap->curregs[R5] &= ~DTR; |
935 | write_zsreg(uap, R5, uap->curregs[R5]); | 910 | write_zsreg(uap, R5, uap->curregs[R5]); |
936 | zssync(uap); | 911 | zssync(uap); |
937 | mdelay(10); | 912 | spin_unlock_irqrestore(&uap->port.lock, flags); |
913 | msleep(10); | ||
938 | } | 914 | } |
939 | 915 | ||
940 | /* | 916 | /* |
@@ -949,13 +925,6 @@ static int pmz_startup(struct uart_port *port) | |||
949 | 925 | ||
950 | pmz_debug("pmz: startup()\n"); | 926 | pmz_debug("pmz: startup()\n"); |
951 | 927 | ||
952 | if (ZS_IS_ASLEEP(uap)) | ||
953 | return -EAGAIN; | ||
954 | if (uap->node == NULL) | ||
955 | return -ENODEV; | ||
956 | |||
957 | mutex_lock(&pmz_irq_mutex); | ||
958 | |||
959 | uap->flags |= PMACZILOG_FLAG_IS_OPEN; | 928 | uap->flags |= PMACZILOG_FLAG_IS_OPEN; |
960 | 929 | ||
961 | /* A console is never powered down. Else, power up and | 930 | /* A console is never powered down. Else, power up and |
@@ -966,18 +935,14 @@ static int pmz_startup(struct uart_port *port) | |||
966 | pwr_delay = __pmz_startup(uap); | 935 | pwr_delay = __pmz_startup(uap); |
967 | spin_unlock_irqrestore(&port->lock, flags); | 936 | spin_unlock_irqrestore(&port->lock, flags); |
968 | } | 937 | } |
969 | 938 | sprintf(uap->irq_name, PMACZILOG_NAME"%d", uap->port.line); | |
970 | pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON; | ||
971 | if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, | 939 | if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, |
972 | "SCC", uap)) { | 940 | uap->irq_name, uap)) { |
973 | pmz_error("Unable to register zs interrupt handler.\n"); | 941 | pmz_error("Unable to register zs interrupt handler.\n"); |
974 | pmz_set_scc_power(uap, 0); | 942 | pmz_set_scc_power(uap, 0); |
975 | mutex_unlock(&pmz_irq_mutex); | ||
976 | return -ENXIO; | 943 | return -ENXIO; |
977 | } | 944 | } |
978 | 945 | ||
979 | mutex_unlock(&pmz_irq_mutex); | ||
980 | |||
981 | /* Right now, we deal with delay by blocking here, I'll be | 946 | /* Right now, we deal with delay by blocking here, I'll be |
982 | * smarter later on | 947 | * smarter later on |
983 | */ | 948 | */ |
@@ -990,12 +955,9 @@ static int pmz_startup(struct uart_port *port) | |||
990 | if (ZS_IS_IRDA(uap)) | 955 | if (ZS_IS_IRDA(uap)) |
991 | pmz_irda_reset(uap); | 956 | pmz_irda_reset(uap); |
992 | 957 | ||
993 | /* Enable interrupts emission from the chip */ | 958 | /* Enable interrupt requests for the channel */ |
994 | spin_lock_irqsave(&port->lock, flags); | 959 | spin_lock_irqsave(&port->lock, flags); |
995 | uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB; | 960 | pmz_interrupt_control(uap, 1); |
996 | if (!ZS_IS_EXTCLK(uap)) | ||
997 | uap->curregs[R1] |= EXT_INT_ENAB; | ||
998 | write_zsreg(uap, R1, uap->curregs[R1]); | ||
999 | spin_unlock_irqrestore(&port->lock, flags); | 961 | spin_unlock_irqrestore(&port->lock, flags); |
1000 | 962 | ||
1001 | pmz_debug("pmz: startup() done.\n"); | 963 | pmz_debug("pmz: startup() done.\n"); |
@@ -1010,49 +972,35 @@ static void pmz_shutdown(struct uart_port *port) | |||
1010 | 972 | ||
1011 | pmz_debug("pmz: shutdown()\n"); | 973 | pmz_debug("pmz: shutdown()\n"); |
1012 | 974 | ||
1013 | if (uap->node == NULL) | ||
1014 | return; | ||
1015 | |||
1016 | mutex_lock(&pmz_irq_mutex); | ||
1017 | |||
1018 | /* Release interrupt handler */ | ||
1019 | free_irq(uap->port.irq, uap); | ||
1020 | |||
1021 | spin_lock_irqsave(&port->lock, flags); | 975 | spin_lock_irqsave(&port->lock, flags); |
1022 | 976 | ||
1023 | uap->flags &= ~PMACZILOG_FLAG_IS_OPEN; | 977 | /* Disable interrupt requests for the channel */ |
978 | pmz_interrupt_control(uap, 0); | ||
1024 | 979 | ||
1025 | if (!ZS_IS_OPEN(uap->mate)) | 980 | if (!ZS_IS_CONS(uap)) { |
1026 | pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON; | 981 | /* Disable receiver and transmitter */ |
982 | uap->curregs[R3] &= ~RxENABLE; | ||
983 | uap->curregs[R5] &= ~TxENABLE; | ||
1027 | 984 | ||
1028 | /* Disable interrupts */ | 985 | /* Disable break assertion */ |
1029 | if (!ZS_IS_ASLEEP(uap)) { | 986 | uap->curregs[R5] &= ~SND_BRK; |
1030 | uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); | 987 | pmz_maybe_update_regs(uap); |
1031 | write_zsreg(uap, R1, uap->curregs[R1]); | ||
1032 | zssync(uap); | ||
1033 | } | 988 | } |
1034 | 989 | ||
1035 | if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) { | 990 | spin_unlock_irqrestore(&port->lock, flags); |
1036 | spin_unlock_irqrestore(&port->lock, flags); | 991 | |
1037 | mutex_unlock(&pmz_irq_mutex); | 992 | /* Release interrupt handler */ |
1038 | return; | 993 | free_irq(uap->port.irq, uap); |
1039 | } | ||
1040 | 994 | ||
1041 | /* Disable receiver and transmitter. */ | 995 | spin_lock_irqsave(&port->lock, flags); |
1042 | uap->curregs[R3] &= ~RxENABLE; | ||
1043 | uap->curregs[R5] &= ~TxENABLE; | ||
1044 | 996 | ||
1045 | /* Disable all interrupts and BRK assertion. */ | 997 | uap->flags &= ~PMACZILOG_FLAG_IS_OPEN; |
1046 | uap->curregs[R5] &= ~SND_BRK; | ||
1047 | pmz_maybe_update_regs(uap); | ||
1048 | 998 | ||
1049 | /* Shut the chip down */ | 999 | if (!ZS_IS_CONS(uap)) |
1050 | pmz_set_scc_power(uap, 0); | 1000 | pmz_set_scc_power(uap, 0); /* Shut the chip down */ |
1051 | 1001 | ||
1052 | spin_unlock_irqrestore(&port->lock, flags); | 1002 | spin_unlock_irqrestore(&port->lock, flags); |
1053 | 1003 | ||
1054 | mutex_unlock(&pmz_irq_mutex); | ||
1055 | |||
1056 | pmz_debug("pmz: shutdown() done.\n"); | 1004 | pmz_debug("pmz: shutdown() done.\n"); |
1057 | } | 1005 | } |
1058 | 1006 | ||
@@ -1300,9 +1248,6 @@ static void __pmz_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1300 | 1248 | ||
1301 | pmz_debug("pmz: set_termios()\n"); | 1249 | pmz_debug("pmz: set_termios()\n"); |
1302 | 1250 | ||
1303 | if (ZS_IS_ASLEEP(uap)) | ||
1304 | return; | ||
1305 | |||
1306 | memcpy(&uap->termios_cache, termios, sizeof(struct ktermios)); | 1251 | memcpy(&uap->termios_cache, termios, sizeof(struct ktermios)); |
1307 | 1252 | ||
1308 | /* XXX Check which revs of machines actually allow 1 and 4Mb speeds | 1253 | /* XXX Check which revs of machines actually allow 1 and 4Mb speeds |
@@ -1352,19 +1297,15 @@ static void pmz_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1352 | spin_lock_irqsave(&port->lock, flags); | 1297 | spin_lock_irqsave(&port->lock, flags); |
1353 | 1298 | ||
1354 | /* Disable IRQs on the port */ | 1299 | /* Disable IRQs on the port */ |
1355 | uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); | 1300 | pmz_interrupt_control(uap, 0); |
1356 | write_zsreg(uap, R1, uap->curregs[R1]); | ||
1357 | 1301 | ||
1358 | /* Setup new port configuration */ | 1302 | /* Setup new port configuration */ |
1359 | __pmz_set_termios(port, termios, old); | 1303 | __pmz_set_termios(port, termios, old); |
1360 | 1304 | ||
1361 | /* Re-enable IRQs on the port */ | 1305 | /* Re-enable IRQs on the port */ |
1362 | if (ZS_IS_OPEN(uap)) { | 1306 | if (ZS_IS_OPEN(uap)) |
1363 | uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB; | 1307 | pmz_interrupt_control(uap, 1); |
1364 | if (!ZS_IS_EXTCLK(uap)) | 1308 | |
1365 | uap->curregs[R1] |= EXT_INT_ENAB; | ||
1366 | write_zsreg(uap, R1, uap->curregs[R1]); | ||
1367 | } | ||
1368 | spin_unlock_irqrestore(&port->lock, flags); | 1309 | spin_unlock_irqrestore(&port->lock, flags); |
1369 | } | 1310 | } |
1370 | 1311 | ||
@@ -1604,25 +1545,34 @@ static void pmz_dispose_port(struct uart_pmac_port *uap) | |||
1604 | */ | 1545 | */ |
1605 | static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) | 1546 | static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) |
1606 | { | 1547 | { |
1548 | struct uart_pmac_port *uap; | ||
1607 | int i; | 1549 | int i; |
1608 | 1550 | ||
1609 | /* Iterate the pmz_ports array to find a matching entry | 1551 | /* Iterate the pmz_ports array to find a matching entry |
1610 | */ | 1552 | */ |
1611 | for (i = 0; i < MAX_ZS_PORTS; i++) | 1553 | for (i = 0; i < MAX_ZS_PORTS; i++) |
1612 | if (pmz_ports[i].node == mdev->ofdev.dev.of_node) { | 1554 | if (pmz_ports[i].node == mdev->ofdev.dev.of_node) |
1613 | struct uart_pmac_port *uap = &pmz_ports[i]; | 1555 | break; |
1614 | 1556 | if (i >= MAX_ZS_PORTS) | |
1615 | uap->dev = mdev; | 1557 | return -ENODEV; |
1616 | dev_set_drvdata(&mdev->ofdev.dev, uap); | 1558 | |
1617 | if (macio_request_resources(uap->dev, "pmac_zilog")) | 1559 | |
1618 | printk(KERN_WARNING "%s: Failed to request resource" | 1560 | uap = &pmz_ports[i]; |
1619 | ", port still active\n", | 1561 | uap->dev = mdev; |
1620 | uap->node->name); | 1562 | uap->port.dev = &mdev->ofdev.dev; |
1621 | else | 1563 | dev_set_drvdata(&mdev->ofdev.dev, uap); |
1622 | uap->flags |= PMACZILOG_FLAG_RSRC_REQUESTED; | 1564 | |
1623 | return 0; | 1565 | /* We still activate the port even when failing to request resources |
1624 | } | 1566 | * to work around bugs in ancient Apple device-trees |
1625 | return -ENODEV; | 1567 | */ |
1568 | if (macio_request_resources(uap->dev, "pmac_zilog")) | ||
1569 | printk(KERN_WARNING "%s: Failed to request resource" | ||
1570 | ", port still active\n", | ||
1571 | uap->node->name); | ||
1572 | else | ||
1573 | uap->flags |= PMACZILOG_FLAG_RSRC_REQUESTED; | ||
1574 | |||
1575 | return uart_add_one_port(&pmz_uart_reg, &uap->port); | ||
1626 | } | 1576 | } |
1627 | 1577 | ||
1628 | /* | 1578 | /* |
@@ -1636,12 +1586,15 @@ static int pmz_detach(struct macio_dev *mdev) | |||
1636 | if (!uap) | 1586 | if (!uap) |
1637 | return -ENODEV; | 1587 | return -ENODEV; |
1638 | 1588 | ||
1589 | uart_remove_one_port(&pmz_uart_reg, &uap->port); | ||
1590 | |||
1639 | if (uap->flags & PMACZILOG_FLAG_RSRC_REQUESTED) { | 1591 | if (uap->flags & PMACZILOG_FLAG_RSRC_REQUESTED) { |
1640 | macio_release_resources(uap->dev); | 1592 | macio_release_resources(uap->dev); |
1641 | uap->flags &= ~PMACZILOG_FLAG_RSRC_REQUESTED; | 1593 | uap->flags &= ~PMACZILOG_FLAG_RSRC_REQUESTED; |
1642 | } | 1594 | } |
1643 | dev_set_drvdata(&mdev->ofdev.dev, NULL); | 1595 | dev_set_drvdata(&mdev->ofdev.dev, NULL); |
1644 | uap->dev = NULL; | 1596 | uap->dev = NULL; |
1597 | uap->port.dev = NULL; | ||
1645 | 1598 | ||
1646 | return 0; | 1599 | return 0; |
1647 | } | 1600 | } |
@@ -1650,59 +1603,13 @@ static int pmz_detach(struct macio_dev *mdev) | |||
1650 | static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) | 1603 | static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) |
1651 | { | 1604 | { |
1652 | struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev); | 1605 | struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev); |
1653 | struct uart_state *state; | ||
1654 | unsigned long flags; | ||
1655 | 1606 | ||
1656 | if (uap == NULL) { | 1607 | if (uap == NULL) { |
1657 | printk("HRM... pmz_suspend with NULL uap\n"); | 1608 | printk("HRM... pmz_suspend with NULL uap\n"); |
1658 | return 0; | 1609 | return 0; |
1659 | } | 1610 | } |
1660 | 1611 | ||
1661 | if (pm_state.event == mdev->ofdev.dev.power.power_state.event) | 1612 | uart_suspend_port(&pmz_uart_reg, &uap->port); |
1662 | return 0; | ||
1663 | |||
1664 | pmz_debug("suspend, switching to state %d\n", pm_state.event); | ||
1665 | |||
1666 | state = pmz_uart_reg.state + uap->port.line; | ||
1667 | |||
1668 | mutex_lock(&pmz_irq_mutex); | ||
1669 | mutex_lock(&state->port.mutex); | ||
1670 | |||
1671 | spin_lock_irqsave(&uap->port.lock, flags); | ||
1672 | |||
1673 | if (ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)) { | ||
1674 | /* Disable receiver and transmitter. */ | ||
1675 | uap->curregs[R3] &= ~RxENABLE; | ||
1676 | uap->curregs[R5] &= ~TxENABLE; | ||
1677 | |||
1678 | /* Disable all interrupts and BRK assertion. */ | ||
1679 | uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); | ||
1680 | uap->curregs[R5] &= ~SND_BRK; | ||
1681 | pmz_load_zsregs(uap, uap->curregs); | ||
1682 | uap->flags |= PMACZILOG_FLAG_IS_ASLEEP; | ||
1683 | mb(); | ||
1684 | } | ||
1685 | |||
1686 | spin_unlock_irqrestore(&uap->port.lock, flags); | ||
1687 | |||
1688 | if (ZS_IS_OPEN(uap) || ZS_IS_OPEN(uap->mate)) | ||
1689 | if (ZS_IS_ASLEEP(uap->mate) && ZS_IS_IRQ_ON(pmz_get_port_A(uap))) { | ||
1690 | pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON; | ||
1691 | disable_irq(uap->port.irq); | ||
1692 | } | ||
1693 | |||
1694 | if (ZS_IS_CONS(uap)) | ||
1695 | uap->port.cons->flags &= ~CON_ENABLED; | ||
1696 | |||
1697 | /* Shut the chip down */ | ||
1698 | pmz_set_scc_power(uap, 0); | ||
1699 | |||
1700 | mutex_unlock(&state->port.mutex); | ||
1701 | mutex_unlock(&pmz_irq_mutex); | ||
1702 | |||
1703 | pmz_debug("suspend, switching complete\n"); | ||
1704 | |||
1705 | mdev->ofdev.dev.power.power_state = pm_state; | ||
1706 | 1613 | ||
1707 | return 0; | 1614 | return 0; |
1708 | } | 1615 | } |
@@ -1711,76 +1618,20 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) | |||
1711 | static int pmz_resume(struct macio_dev *mdev) | 1618 | static int pmz_resume(struct macio_dev *mdev) |
1712 | { | 1619 | { |
1713 | struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev); | 1620 | struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev); |
1714 | struct uart_state *state; | ||
1715 | unsigned long flags; | ||
1716 | int pwr_delay = 0; | ||
1717 | 1621 | ||
1718 | if (uap == NULL) | 1622 | if (uap == NULL) |
1719 | return 0; | 1623 | return 0; |
1720 | 1624 | ||
1721 | if (mdev->ofdev.dev.power.power_state.event == PM_EVENT_ON) | 1625 | uart_resume_port(&pmz_uart_reg, &uap->port); |
1722 | return 0; | ||
1723 | |||
1724 | pmz_debug("resume, switching to state 0\n"); | ||
1725 | |||
1726 | state = pmz_uart_reg.state + uap->port.line; | ||
1727 | |||
1728 | mutex_lock(&pmz_irq_mutex); | ||
1729 | mutex_lock(&state->port.mutex); | ||
1730 | |||
1731 | spin_lock_irqsave(&uap->port.lock, flags); | ||
1732 | if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) { | ||
1733 | spin_unlock_irqrestore(&uap->port.lock, flags); | ||
1734 | goto bail; | ||
1735 | } | ||
1736 | pwr_delay = __pmz_startup(uap); | ||
1737 | |||
1738 | /* Take care of config that may have changed while asleep */ | ||
1739 | __pmz_set_termios(&uap->port, &uap->termios_cache, NULL); | ||
1740 | |||
1741 | if (ZS_IS_OPEN(uap)) { | ||
1742 | /* Enable interrupts */ | ||
1743 | uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB; | ||
1744 | if (!ZS_IS_EXTCLK(uap)) | ||
1745 | uap->curregs[R1] |= EXT_INT_ENAB; | ||
1746 | write_zsreg(uap, R1, uap->curregs[R1]); | ||
1747 | } | ||
1748 | |||
1749 | spin_unlock_irqrestore(&uap->port.lock, flags); | ||
1750 | |||
1751 | if (ZS_IS_CONS(uap)) | ||
1752 | uap->port.cons->flags |= CON_ENABLED; | ||
1753 | |||
1754 | /* Re-enable IRQ on the controller */ | ||
1755 | if (ZS_IS_OPEN(uap) && !ZS_IS_IRQ_ON(pmz_get_port_A(uap))) { | ||
1756 | pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON; | ||
1757 | enable_irq(uap->port.irq); | ||
1758 | } | ||
1759 | |||
1760 | bail: | ||
1761 | mutex_unlock(&state->port.mutex); | ||
1762 | mutex_unlock(&pmz_irq_mutex); | ||
1763 | |||
1764 | /* Right now, we deal with delay by blocking here, I'll be | ||
1765 | * smarter later on | ||
1766 | */ | ||
1767 | if (pwr_delay != 0) { | ||
1768 | pmz_debug("pmz: delaying %d ms\n", pwr_delay); | ||
1769 | msleep(pwr_delay); | ||
1770 | } | ||
1771 | |||
1772 | pmz_debug("resume, switching complete\n"); | ||
1773 | |||
1774 | mdev->ofdev.dev.power.power_state.event = PM_EVENT_ON; | ||
1775 | 1626 | ||
1776 | return 0; | 1627 | return 0; |
1777 | } | 1628 | } |
1778 | 1629 | ||
1779 | /* | 1630 | /* |
1780 | * Probe all ports in the system and build the ports array, we register | 1631 | * Probe all ports in the system and build the ports array, we register |
1781 | * with the serial layer at this point, the macio-type probing is only | 1632 | * with the serial layer later, so we get a proper struct device which |
1782 | * used later to "attach" to the sysfs tree so we get power management | 1633 | * allows the tty to attach properly. This is later than it used to be |
1783 | * events | 1634 | * but the tty layer really wants it that way. |
1784 | */ | 1635 | */ |
1785 | static int __init pmz_probe(void) | 1636 | static int __init pmz_probe(void) |
1786 | { | 1637 | { |
@@ -1816,8 +1667,10 @@ static int __init pmz_probe(void) | |||
1816 | /* | 1667 | /* |
1817 | * Fill basic fields in the port structures | 1668 | * Fill basic fields in the port structures |
1818 | */ | 1669 | */ |
1819 | pmz_ports[count].mate = &pmz_ports[count+1]; | 1670 | if (node_b != NULL) { |
1820 | pmz_ports[count+1].mate = &pmz_ports[count]; | 1671 | pmz_ports[count].mate = &pmz_ports[count+1]; |
1672 | pmz_ports[count+1].mate = &pmz_ports[count]; | ||
1673 | } | ||
1821 | pmz_ports[count].flags = PMACZILOG_FLAG_IS_CHANNEL_A; | 1674 | pmz_ports[count].flags = PMACZILOG_FLAG_IS_CHANNEL_A; |
1822 | pmz_ports[count].node = node_a; | 1675 | pmz_ports[count].node = node_a; |
1823 | pmz_ports[count+1].node = node_b; | 1676 | pmz_ports[count+1].node = node_b; |
@@ -1855,8 +1708,8 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) | |||
1855 | struct resource *r_ports; | 1708 | struct resource *r_ports; |
1856 | int irq; | 1709 | int irq; |
1857 | 1710 | ||
1858 | r_ports = platform_get_resource(uap->node, IORESOURCE_MEM, 0); | 1711 | r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0); |
1859 | irq = platform_get_irq(uap->node, 0); | 1712 | irq = platform_get_irq(uap->pdev, 0); |
1860 | if (!r_ports || !irq) | 1713 | if (!r_ports || !irq) |
1861 | return -ENODEV; | 1714 | return -ENODEV; |
1862 | 1715 | ||
@@ -1885,19 +1738,19 @@ static int __init pmz_probe(void) | |||
1885 | 1738 | ||
1886 | pmz_ports_count = 0; | 1739 | pmz_ports_count = 0; |
1887 | 1740 | ||
1888 | pmz_ports[0].mate = &pmz_ports[1]; | ||
1889 | pmz_ports[0].port.line = 0; | 1741 | pmz_ports[0].port.line = 0; |
1890 | pmz_ports[0].flags = PMACZILOG_FLAG_IS_CHANNEL_A; | 1742 | pmz_ports[0].flags = PMACZILOG_FLAG_IS_CHANNEL_A; |
1891 | pmz_ports[0].node = &scc_a_pdev; | 1743 | pmz_ports[0].pdev = &scc_a_pdev; |
1892 | err = pmz_init_port(&pmz_ports[0]); | 1744 | err = pmz_init_port(&pmz_ports[0]); |
1893 | if (err) | 1745 | if (err) |
1894 | return err; | 1746 | return err; |
1895 | pmz_ports_count++; | 1747 | pmz_ports_count++; |
1896 | 1748 | ||
1749 | pmz_ports[0].mate = &pmz_ports[1]; | ||
1897 | pmz_ports[1].mate = &pmz_ports[0]; | 1750 | pmz_ports[1].mate = &pmz_ports[0]; |
1898 | pmz_ports[1].port.line = 1; | 1751 | pmz_ports[1].port.line = 1; |
1899 | pmz_ports[1].flags = 0; | 1752 | pmz_ports[1].flags = 0; |
1900 | pmz_ports[1].node = &scc_b_pdev; | 1753 | pmz_ports[1].pdev = &scc_b_pdev; |
1901 | err = pmz_init_port(&pmz_ports[1]); | 1754 | err = pmz_init_port(&pmz_ports[1]); |
1902 | if (err) | 1755 | if (err) |
1903 | return err; | 1756 | return err; |
@@ -1913,16 +1766,35 @@ static void pmz_dispose_port(struct uart_pmac_port *uap) | |||
1913 | 1766 | ||
1914 | static int __init pmz_attach(struct platform_device *pdev) | 1767 | static int __init pmz_attach(struct platform_device *pdev) |
1915 | { | 1768 | { |
1769 | struct uart_pmac_port *uap; | ||
1916 | int i; | 1770 | int i; |
1917 | 1771 | ||
1772 | /* Iterate the pmz_ports array to find a matching entry */ | ||
1918 | for (i = 0; i < pmz_ports_count; i++) | 1773 | for (i = 0; i < pmz_ports_count; i++) |
1919 | if (pmz_ports[i].node == pdev) | 1774 | if (pmz_ports[i].pdev == pdev) |
1920 | return 0; | 1775 | break; |
1921 | return -ENODEV; | 1776 | if (i >= pmz_ports_count) |
1777 | return -ENODEV; | ||
1778 | |||
1779 | uap = &pmz_ports[i]; | ||
1780 | uap->port.dev = &pdev->dev; | ||
1781 | platform_set_drvdata(pdev, uap); | ||
1782 | |||
1783 | return uart_add_one_port(&pmz_uart_reg, &uap->port); | ||
1922 | } | 1784 | } |
1923 | 1785 | ||
1924 | static int __exit pmz_detach(struct platform_device *pdev) | 1786 | static int __exit pmz_detach(struct platform_device *pdev) |
1925 | { | 1787 | { |
1788 | struct uart_pmac_port *uap = platform_get_drvdata(pdev); | ||
1789 | |||
1790 | if (!uap) | ||
1791 | return -ENODEV; | ||
1792 | |||
1793 | uart_remove_one_port(&pmz_uart_reg, &uap->port); | ||
1794 | |||
1795 | platform_set_drvdata(pdev, NULL); | ||
1796 | uap->port.dev = NULL; | ||
1797 | |||
1926 | return 0; | 1798 | return 0; |
1927 | } | 1799 | } |
1928 | 1800 | ||
@@ -1954,38 +1826,13 @@ static struct console pmz_console = { | |||
1954 | */ | 1826 | */ |
1955 | static int __init pmz_register(void) | 1827 | static int __init pmz_register(void) |
1956 | { | 1828 | { |
1957 | int i, rc; | ||
1958 | |||
1959 | pmz_uart_reg.nr = pmz_ports_count; | 1829 | pmz_uart_reg.nr = pmz_ports_count; |
1960 | pmz_uart_reg.cons = PMACZILOG_CONSOLE; | 1830 | pmz_uart_reg.cons = PMACZILOG_CONSOLE; |
1961 | 1831 | ||
1962 | /* | 1832 | /* |
1963 | * Register this driver with the serial core | 1833 | * Register this driver with the serial core |
1964 | */ | 1834 | */ |
1965 | rc = uart_register_driver(&pmz_uart_reg); | 1835 | return uart_register_driver(&pmz_uart_reg); |
1966 | if (rc) | ||
1967 | return rc; | ||
1968 | |||
1969 | /* | ||
1970 | * Register each port with the serial core | ||
1971 | */ | ||
1972 | for (i = 0; i < pmz_ports_count; i++) { | ||
1973 | struct uart_pmac_port *uport = &pmz_ports[i]; | ||
1974 | /* NULL node may happen on wallstreet */ | ||
1975 | if (uport->node != NULL) | ||
1976 | rc = uart_add_one_port(&pmz_uart_reg, &uport->port); | ||
1977 | if (rc) | ||
1978 | goto err_out; | ||
1979 | } | ||
1980 | |||
1981 | return 0; | ||
1982 | err_out: | ||
1983 | while (i-- > 0) { | ||
1984 | struct uart_pmac_port *uport = &pmz_ports[i]; | ||
1985 | uart_remove_one_port(&pmz_uart_reg, &uport->port); | ||
1986 | } | ||
1987 | uart_unregister_driver(&pmz_uart_reg); | ||
1988 | return rc; | ||
1989 | } | 1836 | } |
1990 | 1837 | ||
1991 | #ifdef CONFIG_PPC_PMAC | 1838 | #ifdef CONFIG_PPC_PMAC |
@@ -2084,10 +1931,13 @@ static void __exit exit_pmz(void) | |||
2084 | 1931 | ||
2085 | for (i = 0; i < pmz_ports_count; i++) { | 1932 | for (i = 0; i < pmz_ports_count; i++) { |
2086 | struct uart_pmac_port *uport = &pmz_ports[i]; | 1933 | struct uart_pmac_port *uport = &pmz_ports[i]; |
2087 | if (uport->node != NULL) { | 1934 | #ifdef CONFIG_PPC_PMAC |
2088 | uart_remove_one_port(&pmz_uart_reg, &uport->port); | 1935 | if (uport->node != NULL) |
2089 | pmz_dispose_port(uport); | 1936 | pmz_dispose_port(uport); |
2090 | } | 1937 | #else |
1938 | if (uport->pdev != NULL) | ||
1939 | pmz_dispose_port(uport); | ||
1940 | #endif | ||
2091 | } | 1941 | } |
2092 | /* Unregister UART driver */ | 1942 | /* Unregister UART driver */ |
2093 | uart_unregister_driver(&pmz_uart_reg); | 1943 | uart_unregister_driver(&pmz_uart_reg); |
@@ -2114,8 +1964,6 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c | |||
2114 | struct uart_pmac_port *uap = &pmz_ports[con->index]; | 1964 | struct uart_pmac_port *uap = &pmz_ports[con->index]; |
2115 | unsigned long flags; | 1965 | unsigned long flags; |
2116 | 1966 | ||
2117 | if (ZS_IS_ASLEEP(uap)) | ||
2118 | return; | ||
2119 | spin_lock_irqsave(&uap->port.lock, flags); | 1967 | spin_lock_irqsave(&uap->port.lock, flags); |
2120 | 1968 | ||
2121 | /* Turn of interrupts and enable the transmitter. */ | 1969 | /* Turn of interrupts and enable the transmitter. */ |
@@ -2160,8 +2008,13 @@ static int __init pmz_console_setup(struct console *co, char *options) | |||
2160 | if (co->index >= pmz_ports_count) | 2008 | if (co->index >= pmz_ports_count) |
2161 | co->index = 0; | 2009 | co->index = 0; |
2162 | uap = &pmz_ports[co->index]; | 2010 | uap = &pmz_ports[co->index]; |
2011 | #ifdef CONFIG_PPC_PMAC | ||
2163 | if (uap->node == NULL) | 2012 | if (uap->node == NULL) |
2164 | return -ENODEV; | 2013 | return -ENODEV; |
2014 | #else | ||
2015 | if (uap->pdev == NULL) | ||
2016 | return -ENODEV; | ||
2017 | #endif | ||
2165 | port = &uap->port; | 2018 | port = &uap->port; |
2166 | 2019 | ||
2167 | /* | 2020 | /* |
diff --git a/drivers/tty/serial/pmac_zilog.h b/drivers/tty/serial/pmac_zilog.h index cbc34fbb1b20..3483242ee3e0 100644 --- a/drivers/tty/serial/pmac_zilog.h +++ b/drivers/tty/serial/pmac_zilog.h | |||
@@ -1,16 +1,6 @@ | |||
1 | #ifndef __PMAC_ZILOG_H__ | 1 | #ifndef __PMAC_ZILOG_H__ |
2 | #define __PMAC_ZILOG_H__ | 2 | #define __PMAC_ZILOG_H__ |
3 | 3 | ||
4 | #ifdef CONFIG_PPC_PMAC | ||
5 | #define pmz_debug(fmt, arg...) dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg) | ||
6 | #define pmz_error(fmt, arg...) dev_err(&uap->dev->ofdev.dev, fmt, ## arg) | ||
7 | #define pmz_info(fmt, arg...) dev_info(&uap->dev->ofdev.dev, fmt, ## arg) | ||
8 | #else | ||
9 | #define pmz_debug(fmt, arg...) dev_dbg(&uap->node->dev, fmt, ## arg) | ||
10 | #define pmz_error(fmt, arg...) dev_err(&uap->node->dev, fmt, ## arg) | ||
11 | #define pmz_info(fmt, arg...) dev_info(&uap->node->dev, fmt, ## arg) | ||
12 | #endif | ||
13 | |||
14 | /* | 4 | /* |
15 | * At most 2 ESCCs with 2 ports each | 5 | * At most 2 ESCCs with 2 ports each |
16 | */ | 6 | */ |
@@ -35,7 +25,7 @@ struct uart_pmac_port { | |||
35 | */ | 25 | */ |
36 | struct device_node *node; | 26 | struct device_node *node; |
37 | #else | 27 | #else |
38 | struct platform_device *node; | 28 | struct platform_device *pdev; |
39 | #endif | 29 | #endif |
40 | 30 | ||
41 | /* Port type as obtained from device tree (IRDA, modem, ...) */ | 31 | /* Port type as obtained from device tree (IRDA, modem, ...) */ |
@@ -50,14 +40,11 @@ struct uart_pmac_port { | |||
50 | #define PMACZILOG_FLAG_REGS_HELD 0x00000010 | 40 | #define PMACZILOG_FLAG_REGS_HELD 0x00000010 |
51 | #define PMACZILOG_FLAG_TX_STOPPED 0x00000020 | 41 | #define PMACZILOG_FLAG_TX_STOPPED 0x00000020 |
52 | #define PMACZILOG_FLAG_TX_ACTIVE 0x00000040 | 42 | #define PMACZILOG_FLAG_TX_ACTIVE 0x00000040 |
53 | #define PMACZILOG_FLAG_ENABLED 0x00000080 | ||
54 | #define PMACZILOG_FLAG_IS_IRDA 0x00000100 | 43 | #define PMACZILOG_FLAG_IS_IRDA 0x00000100 |
55 | #define PMACZILOG_FLAG_IS_INTMODEM 0x00000200 | 44 | #define PMACZILOG_FLAG_IS_INTMODEM 0x00000200 |
56 | #define PMACZILOG_FLAG_HAS_DMA 0x00000400 | 45 | #define PMACZILOG_FLAG_HAS_DMA 0x00000400 |
57 | #define PMACZILOG_FLAG_RSRC_REQUESTED 0x00000800 | 46 | #define PMACZILOG_FLAG_RSRC_REQUESTED 0x00000800 |
58 | #define PMACZILOG_FLAG_IS_ASLEEP 0x00001000 | ||
59 | #define PMACZILOG_FLAG_IS_OPEN 0x00002000 | 47 | #define PMACZILOG_FLAG_IS_OPEN 0x00002000 |
60 | #define PMACZILOG_FLAG_IS_IRQ_ON 0x00004000 | ||
61 | #define PMACZILOG_FLAG_IS_EXTCLK 0x00008000 | 48 | #define PMACZILOG_FLAG_IS_EXTCLK 0x00008000 |
62 | #define PMACZILOG_FLAG_BREAK 0x00010000 | 49 | #define PMACZILOG_FLAG_BREAK 0x00010000 |
63 | 50 | ||
@@ -74,6 +61,8 @@ struct uart_pmac_port { | |||
74 | volatile struct dbdma_regs __iomem *rx_dma_regs; | 61 | volatile struct dbdma_regs __iomem *rx_dma_regs; |
75 | #endif | 62 | #endif |
76 | 63 | ||
64 | unsigned char irq_name[8]; | ||
65 | |||
77 | struct ktermios termios_cache; | 66 | struct ktermios termios_cache; |
78 | }; | 67 | }; |
79 | 68 | ||
@@ -388,9 +377,7 @@ static inline void zssync(struct uart_pmac_port *port) | |||
388 | #define ZS_IS_IRDA(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRDA) | 377 | #define ZS_IS_IRDA(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRDA) |
389 | #define ZS_IS_INTMODEM(UP) ((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM) | 378 | #define ZS_IS_INTMODEM(UP) ((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM) |
390 | #define ZS_HAS_DMA(UP) ((UP)->flags & PMACZILOG_FLAG_HAS_DMA) | 379 | #define ZS_HAS_DMA(UP) ((UP)->flags & PMACZILOG_FLAG_HAS_DMA) |
391 | #define ZS_IS_ASLEEP(UP) ((UP)->flags & PMACZILOG_FLAG_IS_ASLEEP) | ||
392 | #define ZS_IS_OPEN(UP) ((UP)->flags & PMACZILOG_FLAG_IS_OPEN) | 380 | #define ZS_IS_OPEN(UP) ((UP)->flags & PMACZILOG_FLAG_IS_OPEN) |
393 | #define ZS_IS_IRQ_ON(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRQ_ON) | ||
394 | #define ZS_IS_EXTCLK(UP) ((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK) | 381 | #define ZS_IS_EXTCLK(UP) ((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK) |
395 | 382 | ||
396 | #endif /* __PMAC_ZILOG_H__ */ | 383 | #endif /* __PMAC_ZILOG_H__ */ |
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index cea8918b8233..2ebe606a2db1 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c | |||
@@ -963,6 +963,9 @@ static void qe_uart_set_termios(struct uart_port *port, | |||
963 | /* Do we really need a spinlock here? */ | 963 | /* Do we really need a spinlock here? */ |
964 | spin_lock_irqsave(&port->lock, flags); | 964 | spin_lock_irqsave(&port->lock, flags); |
965 | 965 | ||
966 | /* Update the per-port timeout. */ | ||
967 | uart_update_timeout(port, termios->c_cflag, baud); | ||
968 | |||
966 | out_be16(&uccp->upsmr, upsmr); | 969 | out_be16(&uccp->upsmr, upsmr); |
967 | if (soft_uart) { | 970 | if (soft_uart) { |
968 | out_be16(&uccup->supsmr, supsmr); | 971 | out_be16(&uccup->supsmr, supsmr); |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 43db715f1502..7867b7c4538e 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/suspend.h> | 33 | #include <linux/suspend.h> |
34 | #include <linux/writeback.h> | 34 | #include <linux/writeback.h> |
35 | #include <linux/buffer_head.h> /* for fsync_bdev() */ | ||
36 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
37 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
38 | #include <linux/vt_kern.h> | 37 | #include <linux/vt_kern.h> |
@@ -41,6 +40,7 @@ | |||
41 | #include <linux/oom.h> | 40 | #include <linux/oom.h> |
42 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
43 | #include <linux/input.h> | 42 | #include <linux/input.h> |
43 | #include <linux/uaccess.h> | ||
44 | 44 | ||
45 | #include <asm/ptrace.h> | 45 | #include <asm/ptrace.h> |
46 | #include <asm/irq_regs.h> | 46 | #include <asm/irq_regs.h> |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 57c374399f59..e41b9bbc107d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -3318,7 +3318,7 @@ void __init console_init(void) | |||
3318 | } | 3318 | } |
3319 | } | 3319 | } |
3320 | 3320 | ||
3321 | static char *tty_devnode(struct device *dev, mode_t *mode) | 3321 | static char *tty_devnode(struct device *dev, umode_t *mode) |
3322 | { | 3322 | { |
3323 | if (!mode) | 3323 | if (!mode) |
3324 | return NULL; | 3324 | return NULL; |