static irqreturn_t sci_er_interrupt(int irq, void *ptr) { struct uart_port *port = ptr; /* Handle errors */ if (port->type == PORT_SCI) { if (sci_handle_errors(port)) { /* discard character in rx buffer */ sci_in(port, SCxSR); sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); } } else { #if defined(SCIF_ORER) if((sci_in(port, SCLSR) & SCIF_ORER) != 0) { struct tty_struct *tty = port->info->port.tty; sci_out(port, SCLSR, 0); tty_insert_flip_char(tty, 0, TTY_OVERRUN); tty_flip_buffer_push(tty); pr_debug("scif: overrun error\n"); } #endif sci_rx_interrupt(irq, ptr); } sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); /* Kick the transmission */ sci_tx_interrupt(irq, ptr); return IRQ_HANDLED; }
void handle_error(void) { sci_in(&sh_sci, SCxSR); sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci)); sci_in(&sh_sci, SCLSR); sci_out(&sh_sci, SCLSR, 0x00); }
static int get_char(struct uart_port *port) { unsigned long flags; unsigned short status; int c; spin_lock_irqsave(&port->lock, flags); do { status = sci_in(port, SCxSR); if (status & SCxSR_ERRORS(port)) { /* Clear error flags. */ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); continue; } } while (!(status & SCxSR_RDxF(port))); c = sci_in(port, SCxRDR); sci_in(port, SCxSR); /* Dummy read */ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); spin_unlock_irqrestore(&port->lock, flags); return c; }
static inline void handle_error(struct uart_port *port) { /* Clear error flags */ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); }
/* Clear any errors on the SCI */ static void kgdb_handle_error(struct sci_port *port) { sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); /* Clear error flags */ }