Commit 9e40ea1f authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman
Browse files

mxser: extract port ISR



The ISR is terrible mix of letters. Let's extract the proper per-port
handling to a separate function called mxser_port_isr. This way, we can
actually see what both mxser_interrupt and mxser_port_isr do now.

Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Link: https://lore.kernel.org/r/20210618061516.662-14-jslaby@suse.cz


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 15517806
Loading
Loading
Loading
Loading
+64 −55
Original line number Diff line number Diff line
@@ -2203,48 +2203,25 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port
	}
}

/*
 * This is the serial driver's generic interrupt routine
 */
static irqreturn_t mxser_interrupt(int irq, void *dev_id)
static bool mxser_port_isr(struct mxser_port *port)
{
	int status, iir, i;
	struct mxser_board *brd = dev_id;
	struct mxser_port *port;
	int max, irqbits, bits, msr;
	unsigned int int_cnt, pass_counter = 0;
	int handled = IRQ_NONE;
	struct tty_struct *tty;
	u8 iir, msr, status;
	bool error = false;

	max = brd->info->nports;
	while (pass_counter++ < MXSER_ISR_PASS_LIMIT) {
		irqbits = inb(brd->vector) & brd->vector_mask;
		if (irqbits == brd->vector_mask)
			break;

		handled = IRQ_HANDLED;
		for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) {
			if (irqbits == brd->vector_mask)
				break;
			if (bits & irqbits)
				continue;
			port = &brd->ports[i];

			int_cnt = 0;
			spin_lock(&port->slock);
			do {
	iir = inb(port->ioaddr + UART_IIR);
	if (iir & UART_IIR_NO_INT)
					break;
		return true;

	iir &= MOXA_MUST_IIR_MASK;
	tty = tty_port_tty_get(&port->port);
				if (!tty || port->closing ||
				    !tty_port_initialized(&port->port)) {
	if (!tty || port->closing || !tty_port_initialized(&port->port)) {
		status = inb(port->ioaddr + UART_LSR);
		outb(0x27, port->ioaddr + UART_FCR);
		inb(port->ioaddr + UART_MSR);
					tty_kref_put(tty);
					break;

		error = true;
		goto put_tty;
	}

	status = inb(port->ioaddr + UART_LSR);
@@ -2254,8 +2231,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
	if (status & UART_LSR_FE)
		port->err_shadow |= NPPI_NOTIFY_FRAMING;
	if (status & UART_LSR_OE)
					port->err_shadow |=
						NPPI_NOTIFY_HW_OVERRUN;
		port->err_shadow |= NPPI_NOTIFY_HW_OVERRUN;
	if (status & UART_LSR_BI)
		port->err_shadow |= NPPI_NOTIFY_BREAK;

@@ -2264,28 +2240,61 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
		    iir == MOXA_MUST_IIR_RDA ||
		    iir == MOXA_MUST_IIR_RTO ||
		    iir == MOXA_MUST_IIR_LSR)
						status = mxser_receive_chars(tty,
								port, status);

			status = mxser_receive_chars(tty, port, status);
	} else {
		status &= port->read_status_mask;
		if (status & UART_LSR_DR)
						status = mxser_receive_chars(tty,
								port, status);
			status = mxser_receive_chars(tty, port, status);
	}

	msr = inb(port->ioaddr + UART_MSR);
	if (msr & UART_MSR_ANY_DELTA)
		mxser_check_modem_status(tty, port, msr);

	if (port->board->must_hwid) {
					if (iir == 0x02 && (status &
								UART_LSR_THRE))
		if (iir == 0x02 && (status & UART_LSR_THRE))
			mxser_transmit_chars(tty, port);
	} else {
		if (status & UART_LSR_THRE)
			mxser_transmit_chars(tty, port);
	}

put_tty:
	tty_kref_put(tty);

	return error;
}

/*
 * This is the serial driver's generic interrupt routine
 */
static irqreturn_t mxser_interrupt(int irq, void *dev_id)
{
	struct mxser_board *brd = dev_id;
	struct mxser_port *port;
	unsigned int int_cnt, pass_counter = 0;
	int max, irqbits, bits, i;
	int handled = IRQ_NONE;

	max = brd->info->nports;
	while (pass_counter++ < MXSER_ISR_PASS_LIMIT) {
		irqbits = inb(brd->vector) & brd->vector_mask;
		if (irqbits == brd->vector_mask)
			break;

		handled = IRQ_HANDLED;
		for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) {
			if (irqbits == brd->vector_mask)
				break;
			if (bits & irqbits)
				continue;
			port = &brd->ports[i];

			int_cnt = 0;
			spin_lock(&port->slock);
			do {
				if (mxser_port_isr(port))
					break;
			} while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
			spin_unlock(&port->slock);
		}