Index: sysgo/elinos/linux/drivers/char/serial.c diff -c sysgo/elinos/linux/drivers/char/serial.c:1.2 sysgo/elinos/linux/drivers/char/serial.c:1.3 *** sysgo/elinos/linux/drivers/char/serial.c:1.2 Wed May 17 14:07:00 2000 --- sysgo/elinos/linux/drivers/char/serial.c Wed Jun 7 15:19:53 2000 *************** *** 607,612 **** --- 607,613 ---- int status; struct async_struct * info; int pass_counter = 0; + int iir; struct async_struct *end_mark = 0; #ifdef CONFIG_SERIAL_MULTIPORT int first_multi = 0; *************** *** 627,635 **** first_multi = inb(multi->port_monitor); #endif do { if (!info->tty || ! (serial_in(info, UART_IIR) & UART_IIR_NO_INT)) { if (!end_mark) end_mark = info; goto next; --- 628,637 ---- first_multi = inb(multi->port_monitor); #endif + iir = serial_in(info, UART_IIR); do { if (!info->tty || ! ((iir = serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) { if (!end_mark) end_mark = info; goto next; *************** *** 645,650 **** --- 647,663 ---- if (status & UART_LSR_DR) receive_chars(info, &status); check_modem_status(info); + #ifdef CONFIG_AMD_ELAN + /* + ** There is a bug (misfeature?) in the UART on the AMD Elan + ** SC4x0 and SC520 embedded processor series; the THRE bit of + ** the line status register seems to be delayed one bit + ** clock after the interrupt is generated, so kludge this + ** if the IIR indicates a Transmit Holding Register Interrupt + */ + if ((iir & UART_IIR_ID) == UART_IIR_THRI) + status |= UART_LSR_THRE; + #endif if (status & UART_LSR_THRE) transmit_chars(info, 0); *************** *** 679,685 **** */ static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) { ! int status; int pass_counter = 0; struct async_struct * info; #ifdef CONFIG_SERIAL_MULTIPORT --- 692,698 ---- */ static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) { ! int status, iir; int pass_counter = 0; struct async_struct * info; #ifdef CONFIG_SERIAL_MULTIPORT *************** *** 701,706 **** --- 714,720 ---- first_multi = inb(multi->port_monitor); #endif + iir = serial_in(info, UART_IIR); do { status = serial_inp(info, UART_LSR); #ifdef SERIAL_DEBUG_INTR *************** *** 709,714 **** --- 723,739 ---- if (status & UART_LSR_DR) receive_chars(info, &status); check_modem_status(info); + #ifdef CONFIG_AMD_ELAN + /* + ** There is a bug (misfeature?) in the UART on the AMD Elan + ** SC4x0 and SC520 embedded processor series; the THRE bit of + ** the line status register seems to be delayed one bit + ** clock after the interrupt is generated, so kludge this + ** if the IIR indicates a Transmit Holding Register Interrupt + */ + if ((iir & UART_IIR_ID) == UART_IIR_THRI) + status |= UART_LSR_THRE; + #endif if (status & UART_LSR_THRE) transmit_chars(info, 0); if (pass_counter++ > RS_ISR_PASS_LIMIT) { *************** *** 717,723 **** #endif break; } ! } while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT)); info->last_active = jiffies; #ifdef CONFIG_SERIAL_MULTIPORT if (multi->port_monitor) --- 742,748 ---- #endif break; } ! } while (!((iir = serial_in(info, UART_IIR)) & UART_IIR_NO_INT)); info->last_active = jiffies; #ifdef CONFIG_SERIAL_MULTIPORT if (multi->port_monitor)