udelay(1);
}
-static void receive_chars(struct uart_sunsab_port *up,
- union sab82532_irq_status *stat,
- struct pt_regs *regs)
+static struct tty_struct *
+receive_chars(struct uart_sunsab_port *up,
+ union sab82532_irq_status *stat,
+ struct pt_regs *regs)
{
struct tty_struct *tty = NULL;
unsigned char buf[32];
if (stat->sreg.isr0 & SAB82532_ISR0_TIME) {
sunsab_cec_wait(up);
writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr);
- return;
+ return tty;
}
if (stat->sreg.isr0 & SAB82532_ISR0_RFO)
if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
tty->flip.work.func((void *)tty);
if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- return; // if TTY_DONT_FLIP is set
+ return tty; // if TTY_DONT_FLIP is set
}
*tty->flip.char_buf_ptr = ch;
}
}
- if (tty)
- tty_flip_buffer_push(tty);
-
if (saw_console_brk)
sun_do_break();
+
+ return tty;
}
static void sunsab_stop_tx(struct uart_port *, unsigned int);
static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct uart_sunsab_port *up = dev_id;
+ struct tty_struct *tty;
union sab82532_irq_status status;
unsigned long flags;
if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA1)
status.sreg.isr1 = readb(&up->regs->r.isr1);
+ tty = NULL;
if (status.stat) {
if (status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
SAB82532_ISR0_RFO | SAB82532_ISR0_RPF))
- receive_chars(up, &status, regs);
+ tty = receive_chars(up, &status, regs);
if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
(status.sreg.isr1 & SAB82532_ISR1_CSC))
check_status(up, &status);
spin_unlock(&up->port.lock);
+ if (tty)
+ tty_flip_buffer_push(tty);
+
up++;
spin_lock(&up->port.lock);
if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB1)
status.sreg.isr1 = readb(&up->regs->r.isr1);
+ tty = NULL;
if (status.stat) {
if (status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
SAB82532_ISR0_RFO | SAB82532_ISR0_RPF))
- receive_chars(up, &status, regs);
+ tty = receive_chars(up, &status, regs);
if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
(status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC)))
check_status(up, &status);
spin_unlock_irqrestore(&up->port.lock, flags);
+ if (tty)
+ tty_flip_buffer_push(tty);
+
return IRQ_HANDLED;
}