--- linux-2.6.8-rc3-plain/drivers/serial/pmac_zilog.c 2004-08-05 14:48:36.000000000 +0200 +++ linux-2.6.8-rc3-hw1/drivers/serial/pmac_zilog.c 2004-08-06 14:37:17.003886152 +0200 @@ -29,6 +29,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * 2004-08-06 Harald Welte + * - Enable BREAK interrupt + * - Add support for sysreq + * * TODO: - Add DMA support * - Defer port shutdown to a few seconds after close * - maybe put something right into uap->clk_divisor @@ -53,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +69,10 @@ #include #include +#if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + #include #include @@ -259,8 +268,10 @@ } ch &= uap->parity_mask; - if (ch == 0 && uap->prev_status & BRK_ABRT) + if (ch == 0 && uap->flags & PMACZILOG_FLAG_BREAK) { + uap->flags &= ~PMACZILOG_FLAG_BREAK; r1 |= BRK_ABRT; + } /* A real serial line, record the character and status. */ if (drop) @@ -273,6 +284,7 @@ if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) { error = 1; if (r1 & BRK_ABRT) { + printk(KERN_DEBUG "pmz:got break !\n"); pmz_debug("pmz: got break !\n"); r1 &= ~(PAR_ERR | CRC_ERR); uap->port.icount.brk++; @@ -364,6 +376,9 @@ wake_up_interruptible(&uap->port.info->delta_msr_wait); } + if (status & BRK_ABRT) + uap->flags |= PMACZILOG_FLAG_BREAK; + uap->prev_status = status; } @@ -872,8 +887,8 @@ uap->curregs[R13] = 0; uap->curregs[R14] = BRENAB; - /* Clear handshaking */ - uap->curregs[R15] = 0; + /* Clear handshaking, enable BREAK interrupts */ + uap->curregs[R15] = BRKIE; /* Master interrupt enable */ uap->curregs[R9] |= NV | MIE; @@ -1919,10 +1934,11 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int count) { struct uart_pmac_port *uap = &pmz_ports[con->index]; - unsigned long flags; int i; - spin_lock_irqsave(&uap->port.lock, flags); + /* Don't do any locking here, since we might get called from within + * sysreq() handling and already hold a lock. Ideally we would need + * something like the 'steal lock' code in sn_sal_console_write -HW */ /* Turn of interrupts and enable the transmitter. */ write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB); @@ -1943,8 +1959,6 @@ /* Restore the values in the registers. */ write_zsreg(uap, R1, uap->curregs[1]); /* Don't disable the transmitter. */ - - spin_unlock_irqrestore(&uap->port.lock, flags); } /*