static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) { int saw_console_brk = 0; int limit = 10000; while (limit-- > 0) { long status; long c = sun4v_con_getchar(&status); if (status == HV_EWOULDBLOCK) break; if (c == CON_BREAK) { if (uart_handle_break(port)) continue; saw_console_brk = 1; c = 0; } if (c == CON_HUP) { hung_up = 1; uart_handle_dcd_change(port, 0); } else if (hung_up) { hung_up = 0; uart_handle_dcd_change(port, 1); } if (tty == NULL) { uart_handle_sysrq_char(port, c); continue; } port->icount.rx++; if (uart_handle_sysrq_char(port, c)) continue; tty_insert_flip_char(tty, c, TTY_NORMAL); } return saw_console_brk; }
static void neo_parse_modem(struct jsm_channel *ch, u8 signals) { u8 msignals = signals; jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, "neo_parse_modem: port: %d msignals: %x\n", ch->ch_portnum, msignals); /* Scrub off lower bits. They signify delta's, which I don't care about */ /* Keep DDCD and DDSR though */ msignals &= 0xf8; if (msignals & UART_MSR_DDCD) uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD); if (msignals & UART_MSR_DDSR) uart_handle_cts_change(&ch->uart_port, msignals & UART_MSR_CTS); if (msignals & UART_MSR_DCD) ch->ch_mistat |= UART_MSR_DCD; else ch->ch_mistat &= ~UART_MSR_DCD; if (msignals & UART_MSR_DSR) ch->ch_mistat |= UART_MSR_DSR; else ch->ch_mistat &= ~UART_MSR_DSR; if (msignals & UART_MSR_RI) ch->ch_mistat |= UART_MSR_RI; else ch->ch_mistat &= ~UART_MSR_RI; if (msignals & UART_MSR_CTS) ch->ch_mistat |= UART_MSR_CTS; else ch->ch_mistat &= ~UART_MSR_CTS; jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", ch->ch_portnum, !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR), !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS), !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_CTS), !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DSR), !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_RI), !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DCD)); }
/* * Interrupt handler */ static irqreturn_t atmel_interrupt(int irq, void *dev_id) { struct uart_port *port = dev_id; struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; unsigned int status, pending, pass_counter = 0; status = UART_GET_CSR(port); pending = status & UART_GET_IMR(port); while (pending) { /* Interrupt receive */ if (pending & ATMEL_US_RXRDY) atmel_rx_chars(port); else if (pending & ATMEL_US_RXBRK) { /* * End of break detected. If it came along * with a character, atmel_rx_chars will * handle it. */ UART_PUT_CR(port, ATMEL_US_RSTSTA); UART_PUT_IDR(port, ATMEL_US_RXBRK); atmel_port->break_active = 0; } // TODO: All reads to CSR will clear these interrupts! if (pending & ATMEL_US_RIIC) port->icount.rng++; if (pending & ATMEL_US_DSRIC) port->icount.dsr++; if (pending & ATMEL_US_DCDIC) uart_handle_dcd_change(port, !(status & ATMEL_US_DCD)); if (pending & ATMEL_US_CTSIC) uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC | ATMEL_US_CTSIC)) wake_up_interruptible(&port->info->delta_msr_wait); /* Interrupt transmit */ if (pending & ATMEL_US_TXRDY) atmel_tx_chars(port); if (pass_counter++ > ATMEL_ISR_PASS_LIMIT) break; status = UART_GET_CSR(port); pending = status & UART_GET_IMR(port); } return IRQ_HANDLED; }
static inline void check_modem_status(struct uart_port *port) { uint8_t msr; msr = siu_read(port, UART_MSR); if ((msr & UART_MSR_ANY_DELTA) == 0) return; if (msr & UART_MSR_DDCD) uart_handle_dcd_change(port, msr & UART_MSR_DCD); if (msr & UART_MSR_TERI) port->icount.rng++; if (msr & UART_MSR_DDSR) port->icount.dsr++; if (msr & UART_MSR_DCTS) uart_handle_cts_change(port, msr & UART_MSR_CTS); wake_up_interruptible(&port->state->port.delta_msr_wait); }
void btlinux_handle_mctrl(struct uart_btlinux_port *linux_port, UINT8 signals, UINT8 values) { UINT16 status = 0; dbg("[USERSPACE <-- KERNEL] -- signals %x, values %x", signals, values); if (values & PORT_DTRDSR_ON) { info("BTPORT_DTRDSR_ON"); status |= TIOCM_DSR; }; if (values & PORT_CTSRTS_ON) { info("BTPORT_CTSRTS_ON"); status |= TIOCM_CTS; }; if (values & PORT_RING_ON) { info("BTPORT_RING_ON"); status |= TIOCM_RNG; }; if (values & PORT_DCD_ON) { info("BTPORT_DCD_ON"); status |= TIOCM_CAR; }; if (signals & MODEM_CNTRL_DTRDSR_MASK) { dbg("MODEM_CNTRL_DTRDSR_MASK, SET DTR %d", status & TIOCM_DSR); linux_port->port.icount.dsr++; } if (signals & MODEM_CNTRL_CTSRTS_MASK) { dbg("MODEM_CNTRL_CTSRTS_MASK, SET CTS %d", status & TIOCM_CTS); uart_handle_cts_change(&linux_port->port, status & TIOCM_CTS); } if (signals & MODEM_CNTRL_RNG_MASK) { dbg("MODEM_CNTRL_RNG_MASK, SET DTR %d", status & TIOCM_RNG); linux_port->port.icount.rng++; } if (signals & MODEM_CNTRL_CAR_MASK) { dbg("MODEM_CNTRL_CAR_MASK, SET CAR %d", status & TIOCM_CAR); uart_handle_dcd_change(&linux_port->port, status & TIOCM_CAR); } }
static void serial98_modem_status(struct uart_port *port) { int status; status = serial98_msr_in(port); if ((status & UART_MSR_ANY_DELTA) == 0) return; if (status & UART_MSR_TERI) PORT.icount.rng++; if (status & UART_MSR_DDSR) PORT.icount.dsr++; if (status & UART_MSR_DDCD) uart_handle_dcd_change(&PORT, status & UART_MSR_DCD); if (status & UART_MSR_DCTS) uart_handle_cts_change(&PORT, status & UART_MSR_CTS); wake_up_interruptible(&PORT.info->delta_msr_wait); }
static void tegra_uart_handle_modem_signal_change(struct uart_port *u) { struct tegra_uart_port *tup = to_tegra_uport(u); unsigned long msr; msr = tegra_uart_read(tup, UART_MSR); if (!(msr & UART_MSR_ANY_DELTA)) return; if (msr & UART_MSR_TERI) tup->uport.icount.rng++; if (msr & UART_MSR_DDSR) tup->uport.icount.dsr++; /* We may only get DDCD when HW init and reset */ if (msr & UART_MSR_DDCD) uart_handle_dcd_change(&tup->uport, msr & UART_MSR_DCD); /* Will start/stop_tx accordingly */ if (msr & UART_MSR_DCTS) uart_handle_cts_change(&tup->uport, msr & UART_MSR_CTS); }
static _INLINE_ void check_modem_status(struct uart_8250_port *up) { int status; status = serial_in(up, UART_MSR); if ((status & UART_MSR_ANY_DELTA) == 0) return; if (status & UART_MSR_TERI) up->port.icount.rng++; if (status & UART_MSR_DDSR) up->port.icount.dsr++; if (status & UART_MSR_DDCD) uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); if (status & UART_MSR_DCTS) uart_handle_cts_change(&up->port, status & UART_MSR_CTS); wake_up_interruptible(&up->port.info->delta_msr_wait); }
static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, struct zilog_channel *channel) { unsigned char status; status = readb(&channel->control); ZSDELAY(); writeb(RES_EXT_INT, &channel->control); ZSDELAY(); ZS_WSYNC(channel); if (up->curregs[R15] & BRKIE) { if ((status & BRK_ABRT) && !(up->prev_status & BRK_ABRT)) { if (uart_handle_break(&up->port)) up->tty_break = Rx_SYS; else up->tty_break = Rx_BRK; } } if (ZS_WANTS_MODEM_STATUS(up)) { if (status & SYNC) up->port.icount.dsr++; /* The Zilog just gives us an interrupt when DCD/CTS/etc. change. * But it does not tell us which bit has changed, we have to keep * track of this ourselves. */ if ((status ^ up->prev_status) ^ DCD) uart_handle_dcd_change(&up->port, (status & DCD)); if ((status ^ up->prev_status) ^ CTS) uart_handle_cts_change(&up->port, (status & CTS)); wake_up_interruptible(&up->port.state->port.delta_msr_wait); } up->prev_status = status; }
static void uart00_modem_status(struct uart_port *port) { unsigned int status; status = UART_GET_MSR(port); if (!(status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK))) return; if (status & UART_MSR_DDCD_MSK) uart_handle_dcd_change(port, status & UART_MSR_DCD_MSK); if (status & UART_MSR_DDSR_MSK) port->icount.dsr++; if (status & UART_MSR_DCTS_MSK) uart_handle_cts_change(port, status & UART_MSR_CTS_MSK); wake_up_interruptible(&port->info->delta_msr_wait); }
/* * Interrupt handler */ static irqreturn_t at91_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; unsigned int status, pending, pass_counter = 0; status = UART_GET_CSR(port); pending = status & port->read_status_mask; if (pending) { do { if (pending & AT91_US_RXRDY) at91_rx_chars(port, regs); /* Clear the relevent break bits */ if (pending & AT91_US_RXBRK) { UART_PUT_CR(port, AT91_US_RSTSTA); port->icount.brk++; uart_handle_break(port); } // TODO: All reads to CSR will clear these interrupts! if (pending & AT91_US_RIIC) port->icount.rng++; if (pending & AT91_US_DSRIC) port->icount.dsr++; if (pending & AT91_US_DCDIC) uart_handle_dcd_change(port, !(status & AT91_US_DCD)); if (pending & AT91_US_CTSIC) uart_handle_cts_change(port, !(status & AT91_US_CTS)); if (pending & (AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC)) wake_up_interruptible(&port->info->delta_msr_wait); if (pending & AT91_US_TXRDY) at91_tx_chars(port); if (pass_counter++ > AT91_ISR_PASS_LIMIT) break; status = UART_GET_CSR(port); pending = status & port->read_status_mask; } while (pending); } return IRQ_HANDLED; }
static inline void check_modem_status(struct uart_hsu_port *up) { int status; status = serial_in(up, UART_MSR); if ((status & UART_MSR_ANY_DELTA) == 0) return; if (status & UART_MSR_TERI) up->port.icount.rng++; if (status & UART_MSR_DDSR) up->port.icount.dsr++; /* We may only get DDCD when HW init and reset */ if (status & UART_MSR_DDCD) uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); /* Will start/stop_tx accordingly */ if (status & UART_MSR_DCTS) uart_handle_cts_change(&up->port, status & UART_MSR_CTS); wake_up_interruptible(&up->port.state->port.delta_msr_wait); }
static inline void serial_ambarella_check_modem_status(struct uart_port *port) { struct ambarella_uart_port_info *port_info; u32 ms; port_info = (struct ambarella_uart_port_info *)(port->private_data); if (port_info->get_ms) { ms = port_info->get_ms(port->membase); if (ms & UART_MS_RI) port->icount.rng++; if (ms & UART_MS_DSR) port->icount.dsr++; if (ms & UART_MS_DCTS) uart_handle_cts_change(port, (ms & UART_MS_CTS)); if (ms & UART_MS_DDCD) uart_handle_dcd_change(port, (ms & UART_MS_DCD)); wake_up_interruptible(&port->state->port.delta_msr_wait); } }
/* * Handle any change of modem status signal since we were last called. */ static void sa1100_mctrl_check(struct sa1100_port *sport) { unsigned int status, changed; status = sport->port.ops->get_mctrl(&sport->port); changed = status ^ sport->old_status; if (changed == 0) return; sport->old_status = status; if (changed & TIOCM_RI) sport->port.icount.rng++; if (changed & TIOCM_DSR) sport->port.icount.dsr++; if (changed & TIOCM_CAR) uart_handle_dcd_change(&sport->port, status & TIOCM_CAR); if (changed & TIOCM_CTS) uart_handle_cts_change(&sport->port, status & TIOCM_CTS); wake_up_interruptible(&sport->port.state->port.delta_msr_wait); }
static void pl011_modem_status(struct uart_amba_port *uap) { unsigned int status, delta; status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; delta = status ^ uap->old_status; uap->old_status = status; if (!delta) return; if (delta & UART01x_FR_DCD) uart_handle_dcd_change(&uap->port, status & UART01x_FR_DCD); if (delta & UART01x_FR_DSR) uap->port.icount.dsr++; if (delta & UART01x_FR_CTS) uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS); wake_up_interruptible(&uap->port.info->delta_msr_wait); }
static irqreturn_t ks8695uart_modem_status(int irq, void *dev_id) { struct uart_port *port = dev_id; unsigned int status; status = UART_GET_MSR(port); if (status & URMS_URDDCD) uart_handle_dcd_change(port, status & URMS_URDDCD); if (status & URMS_URDDST) port->icount.dsr++; if (status & URMS_URDCTS) uart_handle_cts_change(port, status & URMS_URDCTS); if (status & URMS_URTERI) port->icount.rng++; wake_up_interruptible(&port->state->port.delta_msr_wait); return IRQ_HANDLED; }
static unsigned int sw_uart_modem_status(struct sw_uart_port *sw_uport) { unsigned int status = serial_in(&sw_uport->port, SW_UART_MSR); status |= sw_uport->msr_saved_flags; sw_uport->msr_saved_flags = 0; if (status & SW_UART_MSR_ANY_DELTA && sw_uport->ier & SW_UART_IER_MSI && sw_uport->port.state != NULL) { if (status & SW_UART_MSR_TERI) sw_uport->port.icount.rng++; if (status & SW_UART_MSR_DDSR) sw_uport->port.icount.dsr++; if (status & SW_UART_MSR_DDCD) uart_handle_dcd_change(&sw_uport->port, status & SW_UART_MSR_DCD); if (!(sw_uport->mcr & SW_UART_MCR_AFE) && status & SW_UART_MSR_DCTS) uart_handle_cts_change(&sw_uport->port, status & SW_UART_MSR_CTS); wake_up_interruptible(&sw_uport->port.state->port.delta_msr_wait); } SERIAL_DBG("modem status: %x\n", status); return status; }
static void lh7a40xuart_modem_status (struct uart_port* port) { unsigned int status = UR (port, UART_R_STATUS); unsigned int delta = status ^ ((struct uart_port_lh7a40x*) port)->statusPrev; BIT_SET (port, UART_R_RAWISR, MSEOI); /* Clear modem status intr */ if (!delta) /* Only happens if we missed 2 transitions */ return; ((struct uart_port_lh7a40x*) port)->statusPrev = status; if (delta & DCD) uart_handle_dcd_change (port, status & DCD); if (delta & DSR) ++port->icount.dsr; if (delta & CTS) uart_handle_cts_change (port, status & CTS); wake_up_interruptible (&port->info->delta_msr_wait); }
static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) { int saw_console_brk = 0; int limit = 10000; while (limit-- > 0) { unsigned long ra = __pa(con_read_page); unsigned long bytes_read, i; unsigned long breaks_received = 0; long stat = sun4v_con_read(ra, PAGE_SIZE, &bytes_read); if (stat != HV_EOK) { bytes_read = 0; if (stat == CON_BREAK) { if (uart_handle_break(port)) continue; saw_console_brk = 1; *con_read_page = 0; bytes_read = 1; } else if (stat == CON_HUP) { hung_up = 1; uart_handle_dcd_change(port, 0); continue; } else { /* HV_EWOULDBLOCK, etc. */ break; } } #ifdef CONFIG_CONSOLE_POLL if (port->poll_rx_cb) { for (i = 0; i < bytes_read; i++) { if (port->poll_rx_cb(con_read_page[i] & 255)) { if ((bytes_read - i - 1) != 0) memcpy(&con_read_page[i], &con_read_page[i+1], bytes_read - i - 1); breaks_received++; continue; } else uart_handle_sysrq_char(port, con_read_page[i]); } } #endif if (hung_up) { hung_up = 0; uart_handle_dcd_change(port, 1); } #ifndef CONFIG_CONSOLE_POLL for (i = 0; i < bytes_read; i++) uart_handle_sysrq_char(port, con_read_page[i]); #endif if (tty == NULL) continue; port->icount.rx += bytes_read - breaks_received; tty_insert_flip_string(tty, con_read_page, bytes_read - breaks_received); } return saw_console_brk; }
static void h3600_dcd_intr(int irq, void *dev_id, struct pt_regs *regs) { struct uart_info *info = dev_id; /* Note: should only call this if something has changed */ uart_handle_dcd_change(info, !(GPLR & GPIO_H3600_COM_DCD)); }