aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/pmac_zilog.c102
1 files changed, 52 insertions, 50 deletions
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 5acd24a27d08..51941f02e936 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -216,6 +216,18 @@ static void pmz_maybe_update_regs(struct uart_pmac_port *uap)
216 } 216 }
217} 217}
218 218
219static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
220{
221 if (enable) {
222 uap->curregs[1] |= INT_ALL_Rx | TxINT_ENAB;
223 if (!ZS_IS_EXTCLK(uap))
224 uap->curregs[1] |= EXT_INT_ENAB;
225 } else {
226 uap->curregs[1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
227 }
228 write_zsreg(uap, R1, uap->curregs[1]);
229}
230
219static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) 231static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
220{ 232{
221 struct tty_struct *tty = NULL; 233 struct tty_struct *tty = NULL;
@@ -339,9 +351,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
339 351
340 return tty; 352 return tty;
341 flood: 353 flood:
342 uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); 354 pmz_interrupt_control(uap, 0);
343 write_zsreg(uap, R1, uap->curregs[R1]);
344 zssync(uap);
345 pmz_error("pmz: rx irq flood !\n"); 355 pmz_error("pmz: rx irq flood !\n");
346 return tty; 356 return tty;
347} 357}
@@ -990,12 +1000,9 @@ static int pmz_startup(struct uart_port *port)
990 if (ZS_IS_IRDA(uap)) 1000 if (ZS_IS_IRDA(uap))
991 pmz_irda_reset(uap); 1001 pmz_irda_reset(uap);
992 1002
993 /* Enable interrupts emission from the chip */ 1003 /* Enable interrupt requests for the channel */
994 spin_lock_irqsave(&port->lock, flags); 1004 spin_lock_irqsave(&port->lock, flags);
995 uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB; 1005 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); 1006 spin_unlock_irqrestore(&port->lock, flags);
1000 1007
1001 pmz_debug("pmz: startup() done.\n"); 1008 pmz_debug("pmz: startup() done.\n");
@@ -1015,6 +1022,25 @@ static void pmz_shutdown(struct uart_port *port)
1015 1022
1016 mutex_lock(&pmz_irq_mutex); 1023 mutex_lock(&pmz_irq_mutex);
1017 1024
1025 spin_lock_irqsave(&port->lock, flags);
1026
1027 if (!ZS_IS_ASLEEP(uap)) {
1028 /* Disable interrupt requests for the channel */
1029 pmz_interrupt_control(uap, 0);
1030
1031 if (!ZS_IS_CONS(uap)) {
1032 /* Disable receiver and transmitter */
1033 uap->curregs[R3] &= ~RxENABLE;
1034 uap->curregs[R5] &= ~TxENABLE;
1035
1036 /* Disable break assertion */
1037 uap->curregs[R5] &= ~SND_BRK;
1038 pmz_maybe_update_regs(uap);
1039 }
1040 }
1041
1042 spin_unlock_irqrestore(&port->lock, flags);
1043
1018 /* Release interrupt handler */ 1044 /* Release interrupt handler */
1019 free_irq(uap->port.irq, uap); 1045 free_irq(uap->port.irq, uap);
1020 1046
@@ -1025,29 +1051,8 @@ static void pmz_shutdown(struct uart_port *port)
1025 if (!ZS_IS_OPEN(uap->mate)) 1051 if (!ZS_IS_OPEN(uap->mate))
1026 pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON; 1052 pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON;
1027 1053
1028 /* Disable interrupts */ 1054 if (!ZS_IS_ASLEEP(uap) && !ZS_IS_CONS(uap))
1029 if (!ZS_IS_ASLEEP(uap)) { 1055 pmz_set_scc_power(uap, 0); /* Shut the chip down */
1030 uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
1031 write_zsreg(uap, R1, uap->curregs[R1]);
1032 zssync(uap);
1033 }
1034
1035 if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) {
1036 spin_unlock_irqrestore(&port->lock, flags);
1037 mutex_unlock(&pmz_irq_mutex);
1038 return;
1039 }
1040
1041 /* Disable receiver and transmitter. */
1042 uap->curregs[R3] &= ~RxENABLE;
1043 uap->curregs[R5] &= ~TxENABLE;
1044
1045 /* Disable all interrupts and BRK assertion. */
1046 uap->curregs[R5] &= ~SND_BRK;
1047 pmz_maybe_update_regs(uap);
1048
1049 /* Shut the chip down */
1050 pmz_set_scc_power(uap, 0);
1051 1056
1052 spin_unlock_irqrestore(&port->lock, flags); 1057 spin_unlock_irqrestore(&port->lock, flags);
1053 1058
@@ -1352,19 +1357,15 @@ static void pmz_set_termios(struct uart_port *port, struct ktermios *termios,
1352 spin_lock_irqsave(&port->lock, flags); 1357 spin_lock_irqsave(&port->lock, flags);
1353 1358
1354 /* Disable IRQs on the port */ 1359 /* Disable IRQs on the port */
1355 uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); 1360 pmz_interrupt_control(uap, 0);
1356 write_zsreg(uap, R1, uap->curregs[R1]);
1357 1361
1358 /* Setup new port configuration */ 1362 /* Setup new port configuration */
1359 __pmz_set_termios(port, termios, old); 1363 __pmz_set_termios(port, termios, old);
1360 1364
1361 /* Re-enable IRQs on the port */ 1365 /* Re-enable IRQs on the port */
1362 if (ZS_IS_OPEN(uap)) { 1366 if (ZS_IS_OPEN(uap))
1363 uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB; 1367 pmz_interrupt_control(uap, 1);
1364 if (!ZS_IS_EXTCLK(uap)) 1368
1365 uap->curregs[R1] |= EXT_INT_ENAB;
1366 write_zsreg(uap, R1, uap->curregs[R1]);
1367 }
1368 spin_unlock_irqrestore(&port->lock, flags); 1369 spin_unlock_irqrestore(&port->lock, flags);
1369} 1370}
1370 1371
@@ -1671,14 +1672,17 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
1671 spin_lock_irqsave(&uap->port.lock, flags); 1672 spin_lock_irqsave(&uap->port.lock, flags);
1672 1673
1673 if (ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)) { 1674 if (ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)) {
1674 /* Disable receiver and transmitter. */ 1675 /* Disable interrupt requests for the channel */
1676 pmz_interrupt_control(uap, 0);
1677
1678 /* Disable receiver and transmitter */
1675 uap->curregs[R3] &= ~RxENABLE; 1679 uap->curregs[R3] &= ~RxENABLE;
1676 uap->curregs[R5] &= ~TxENABLE; 1680 uap->curregs[R5] &= ~TxENABLE;
1677 1681
1678 /* Disable all interrupts and BRK assertion. */ 1682 /* Disable break assertion */
1679 uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
1680 uap->curregs[R5] &= ~SND_BRK; 1683 uap->curregs[R5] &= ~SND_BRK;
1681 pmz_load_zsregs(uap, uap->curregs); 1684 pmz_load_zsregs(uap, uap->curregs);
1685
1682 uap->flags |= PMACZILOG_FLAG_IS_ASLEEP; 1686 uap->flags |= PMACZILOG_FLAG_IS_ASLEEP;
1683 mb(); 1687 mb();
1684 } 1688 }
@@ -1738,14 +1742,6 @@ static int pmz_resume(struct macio_dev *mdev)
1738 /* Take care of config that may have changed while asleep */ 1742 /* Take care of config that may have changed while asleep */
1739 __pmz_set_termios(&uap->port, &uap->termios_cache, NULL); 1743 __pmz_set_termios(&uap->port, &uap->termios_cache, NULL);
1740 1744
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); 1745 spin_unlock_irqrestore(&uap->port.lock, flags);
1750 1746
1751 if (ZS_IS_CONS(uap)) 1747 if (ZS_IS_CONS(uap))
@@ -1757,6 +1753,12 @@ static int pmz_resume(struct macio_dev *mdev)
1757 enable_irq(uap->port.irq); 1753 enable_irq(uap->port.irq);
1758 } 1754 }
1759 1755
1756 if (ZS_IS_OPEN(uap)) {
1757 spin_lock_irqsave(&uap->port.lock, flags);
1758 pmz_interrupt_control(uap, 1);
1759 spin_unlock_irqrestore(&uap->port.lock, flags);
1760 }
1761
1760 bail: 1762 bail:
1761 mutex_unlock(&state->port.mutex); 1763 mutex_unlock(&state->port.mutex);
1762 mutex_unlock(&pmz_irq_mutex); 1764 mutex_unlock(&pmz_irq_mutex);