int serial_getc_check(void) { unsigned short status; status = sci_in(&sh_sci, SCxSR); if (status & SCIF_ERRORS) handle_error(); if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci)) handle_error(); return status & (SCIF_DR | SCxSR_RDxF(&sh_sci)); }
static inline int sci_handle_errors(struct uart_port *port) { int copied = 0; unsigned short status = sci_in(port, SCxSR); struct tty_struct *tty = port->info->port.tty; if (status & SCxSR_ORER(port)) { /* overrun error */ if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) copied++; pr_debug("sci: overrun error\n"); } if (status & SCxSR_FER(port)) { if (sci_rxd_in(port) == 0) { /* Notify of BREAK */ struct sci_port *sci_port = (struct sci_port *)port; if (!sci_port->break_flag) { sci_port->break_flag = 1; sci_schedule_break_timer(sci_port); /* Do sysrq handling. */ if (uart_handle_break(port)) return 0; pr_debug("sci: BREAK detected\n"); if (tty_insert_flip_char(tty, 0, TTY_BREAK)) copied++; } } else { /* frame error */ if (tty_insert_flip_char(tty, 0, TTY_FRAME)) copied++; pr_debug("sci: frame error\n"); } } if (status & SCxSR_PER(port)) { /* parity error */ if (tty_insert_flip_char(tty, 0, TTY_PARITY)) copied++; pr_debug("sci: parity error\n"); } if (copied) tty_flip_buffer_push(tty); return copied; }
static int sh_serial_getc(void) { unsigned short status; char ch; while (!serial_getc_check()) ; ch = sci_in(&sh_sci, SCxRDR); status = sci_in(&sh_sci, SCxSR); sci_out(&sh_sci, SCxSR, SCxSR_RDxF_CLEAR(&sh_sci)); if (status & SCIF_ERRORS) handle_error(); if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci)) handle_error(); return ch; }