/* port->lock is held by caller and interrupts are disabled.  */
static unsigned int sc26xx_get_mctrl(struct uart_port *port)
{
	struct uart_sc26xx_port *up;
	int line = port->line;
	unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR;
	u8 ipr;

	port -= line;
	up = container_of(port, struct uart_sc26xx_port, port[0]);
	ipr = READ_SC(port, IPR) ^ 0xff;

	if (up->dsr_mask[line]) {
		mctrl &= ~TIOCM_DSR;
		mctrl |= ipr & up->dsr_mask[line] ? TIOCM_DSR : 0;
	}
	if (up->cts_mask[line]) {
		mctrl &= ~TIOCM_CTS;
		mctrl |= ipr & up->cts_mask[line] ? TIOCM_CTS : 0;
	}
	if (up->dcd_mask[line]) {
		mctrl &= ~TIOCM_CAR;
		mctrl |= ipr & up->dcd_mask[line] ? TIOCM_CAR : 0;
	}
	if (up->ri_mask[line]) {
		mctrl &= ~TIOCM_RNG;
		mctrl |= ipr & up->ri_mask[line] ? TIOCM_RNG : 0;
	}
	return mctrl;
}
static irqreturn_t sc26xx_interrupt(int irq, void *dev_id)
{
	struct uart_sc26xx_port *up = dev_id;
	struct tty_struct *tty;
	unsigned long flags;
	u8 isr;

	spin_lock_irqsave(&up->port[0].lock, flags);

	tty = NULL;
	isr = READ_SC(&up->port[0], ISR);
	if (isr & ISR_TXRDYA)
	    transmit_chars(&up->port[0]);
	if (isr & ISR_RXRDYA)
	    tty = receive_chars(&up->port[0]);

	spin_unlock(&up->port[0].lock);

	if (tty)
		tty_flip_buffer_push(tty);

	spin_lock(&up->port[1].lock);

	tty = NULL;
	if (isr & ISR_TXRDYB)
	    transmit_chars(&up->port[1]);
	if (isr & ISR_RXRDYB)
	    tty = receive_chars(&up->port[1]);

	spin_unlock_irqrestore(&up->port[1].lock, flags);

	if (tty)
		tty_flip_buffer_push(tty);

	return IRQ_HANDLED;
}
Esempio n. 3
0
static irqreturn_t sc26xx_interrupt(int irq, void *dev_id)
{
	struct uart_sc26xx_port *up = dev_id;
	unsigned long flags;
	bool push;
	u8 isr;

	spin_lock_irqsave(&up->port[0].lock, flags);

	push = false;
	isr = READ_SC(&up->port[0], ISR);
	if (isr & ISR_TXRDYA)
	    transmit_chars(&up->port[0]);
	if (isr & ISR_RXRDYA)
	    push = receive_chars(&up->port[0]);

	spin_unlock(&up->port[0].lock);

	if (push)
		tty_flip_buffer_push(&up->port[0].state->port);

	spin_lock(&up->port[1].lock);

	push = false;
	if (isr & ISR_TXRDYB)
	    transmit_chars(&up->port[1]);
	if (isr & ISR_RXRDYB)
	    push = receive_chars(&up->port[1]);

	spin_unlock_irqrestore(&up->port[1].lock, flags);

	if (push)
		tty_flip_buffer_push(&up->port[1].state->port);

	return IRQ_HANDLED;
}