Esempio n. 1
0
File: sunhv.c Progetto: 274914765/C
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;
}
Esempio n. 2
0
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));
}
Esempio n. 3
0
/*
 * 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;
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
	}
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
/*
 * 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;
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
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);
	}
}
Esempio n. 14
0
/*
 * 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);
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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);
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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));
}