Commit 7345b07f authored by Jiri Slaby (SUSE)'s avatar Jiri Slaby (SUSE) Committed by Greg Kroah-Hartman
Browse files

serial: 8250_omap: use guard()s



Having all the new guards, use them in the 8250_omap code. This improves
readability, makes error handling easier, and marks locked portions of
code explicit.

For this to work, UART_CAP_RPM has to be set to up->capabilities a bit
earlier.

Signed-off-by: default avatar"Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20250814072456.182853-13-jirislaby@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 302c8145
Loading
Loading
Loading
Loading
+37 −71
Original line number Diff line number Diff line
@@ -393,8 +393,8 @@ static void omap_8250_set_termios_atomic(struct uart_port *port, struct ktermios
	 * Ok, we're now changing the port state. Do it with
	 * interrupts disabled.
	 */
	pm_runtime_get_sync(port->dev);
	uart_port_lock_irq(port);
	guard(serial8250_rpm)(up);
	guard(uart_port_lock_irq)(port);

	/*
	 * Update the per-port timeout.
@@ -502,10 +502,6 @@ static void omap_8250_set_termios_atomic(struct uart_port *port, struct ktermios
		}
	}
	omap8250_restore_regs(up);

	uart_port_unlock_irq(&up->port);
	pm_runtime_mark_last_busy(port->dev);
	pm_runtime_put_autosuspend(port->dev);
}

/*
@@ -546,10 +542,9 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state,
	struct uart_8250_port *up = up_to_u8250p(port);
	u8 efr;

	pm_runtime_get_sync(port->dev);

	guard(serial8250_rpm)(up);
	/* Synchronize UART_IER access against the console. */
	uart_port_lock_irq(port);
	guard(uart_port_lock_irq)(port);

	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
	efr = serial_in(up, UART_EFR);
@@ -560,11 +555,6 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state,
	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
	serial_out(up, UART_EFR, efr);
	serial_out(up, UART_LCR, 0);

	uart_port_unlock_irq(port);

	pm_runtime_mark_last_busy(port->dev);
	pm_runtime_put_autosuspend(port->dev);
}

static void omap_serial_fill_features_erratas(struct uart_8250_port *up,
@@ -736,7 +726,11 @@ static int omap_8250_startup(struct uart_port *port)
			return ret;
	}

	pm_runtime_get_sync(port->dev);
#ifdef CONFIG_PM
	up->capabilities |= UART_CAP_RPM;
#endif

	guard(serial8250_rpm)(up);

	serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);

@@ -759,14 +753,10 @@ static int omap_8250_startup(struct uart_port *port)
	}

	/* Synchronize UART_IER access against the console. */
	uart_port_lock_irq(port);
	scoped_guard(uart_port_lock_irq, port) {
		up->ier = UART_IER_RLSI | UART_IER_RDI;
		serial_out(up, UART_IER, up->ier);
	uart_port_unlock_irq(port);

#ifdef CONFIG_PM
	up->capabilities |= UART_CAP_RPM;
#endif
	}

	/* Enable module level wake up */
	priv->wer = OMAP_UART_WER_MOD_WKUP;
@@ -775,15 +765,12 @@ static int omap_8250_startup(struct uart_port *port)
	serial_out(up, UART_OMAP_WER, priv->wer);

	if (up->dma && !(priv->habit & UART_HAS_EFR2)) {
		uart_port_lock_irq(port);
		guard(uart_port_lock_irq)(port);
		up->dma->rx_dma(up);
		uart_port_unlock_irq(port);
	}

	enable_irq(port->irq);

	pm_runtime_mark_last_busy(port->dev);
	pm_runtime_put_autosuspend(port->dev);
	return 0;
}

@@ -792,7 +779,7 @@ static void omap_8250_shutdown(struct uart_port *port)
	struct uart_8250_port *up = up_to_u8250p(port);
	struct omap8250_priv *priv = port->private_data;

	pm_runtime_get_sync(port->dev);
	guard(serial8250_rpm)(up);

	flush_work(&priv->qos_work);
	if (up->dma)
@@ -803,10 +790,11 @@ static void omap_8250_shutdown(struct uart_port *port)
		serial_out(up, UART_OMAP_EFR2, 0x0);

	/* Synchronize UART_IER access against the console. */
	uart_port_lock_irq(port);
	scoped_guard(uart_port_lock_irq, port) {
		up->ier = 0;
		serial_out(up, UART_IER, 0);
	uart_port_unlock_irq(port);
	}

	disable_irq_nosync(port->irq);
	dev_pm_clear_wake_irq(port->dev);

@@ -819,46 +807,33 @@ static void omap_8250_shutdown(struct uart_port *port)
	if (up->lcr & UART_LCR_SBC)
		serial_out(up, UART_LCR, up->lcr & ~UART_LCR_SBC);
	serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);

	pm_runtime_mark_last_busy(port->dev);
	pm_runtime_put_autosuspend(port->dev);
}

static void omap_8250_throttle(struct uart_port *port)
{
	struct omap8250_priv *priv = port->private_data;
	unsigned long flags;

	pm_runtime_get_sync(port->dev);
	guard(serial8250_rpm)(up_to_u8250p(port));
	guard(uart_port_lock_irqsave)(port);

	uart_port_lock_irqsave(port, &flags);
	port->ops->stop_rx(port);
	priv->throttled = true;
	uart_port_unlock_irqrestore(port, flags);

	pm_runtime_mark_last_busy(port->dev);
	pm_runtime_put_autosuspend(port->dev);
}

static void omap_8250_unthrottle(struct uart_port *port)
{
	struct omap8250_priv *priv = port->private_data;
	struct uart_8250_port *up = up_to_u8250p(port);
	unsigned long flags;

	pm_runtime_get_sync(port->dev);

	guard(serial8250_rpm)(up);
	/* Synchronize UART_IER access against the console. */
	uart_port_lock_irqsave(port, &flags);
	guard(uart_port_lock_irqsave)(port);

	priv->throttled = false;
	if (up->dma)
		up->dma->rx_dma(up);
	up->ier |= UART_IER_RLSI | UART_IER_RDI;
	serial_out(up, UART_IER, up->ier);
	uart_port_unlock_irqrestore(port, flags);

	pm_runtime_mark_last_busy(port->dev);
	pm_runtime_put_autosuspend(port->dev);
}

static int omap8250_rs485_config(struct uart_port *port,
@@ -996,32 +971,28 @@ static void __dma_rx_complete(void *param)
	struct omap8250_priv *priv = p->port.private_data;
	struct uart_8250_dma *dma = p->dma;
	struct dma_tx_state     state;
	unsigned long flags;

	/* Synchronize UART_IER access against the console. */
	uart_port_lock_irqsave(&p->port, &flags);
	guard(uart_port_lock_irqsave)(&p->port);

	/*
	 * If the tx status is not DMA_COMPLETE, then this is a delayed
	 * completion callback. A previous RX timeout flush would have
	 * already pushed the data, so exit.
	 */
	if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) !=
			DMA_COMPLETE) {
		uart_port_unlock_irqrestore(&p->port, flags);
	if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) != DMA_COMPLETE)
		return;
	}

	__dma_rx_do_complete(p);
	if (!priv->throttled) {
	if (priv->throttled)
		return;

	p->ier |= UART_IER_RLSI | UART_IER_RDI;
	serial_out(p, UART_IER, p->ier);
	if (!(priv->habit & UART_HAS_EFR2))
		omap_8250_rx_dma(p);
}

	uart_port_unlock_irqrestore(&p->port, flags);
}

static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
{
	struct omap8250_priv	*priv = p->port.private_data;
@@ -1117,14 +1088,13 @@ static void omap_8250_dma_tx_complete(void *param)
	struct uart_8250_port	*p = param;
	struct uart_8250_dma	*dma = p->dma;
	struct tty_port		*tport = &p->port.state->port;
	unsigned long		flags;
	bool			en_thri = false;
	struct omap8250_priv	*priv = p->port.private_data;

	dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr,
				UART_XMIT_SIZE, DMA_TO_DEVICE);

	uart_port_lock_irqsave(&p->port, &flags);
	guard(uart_port_lock_irqsave)(&p->port);

	dma->tx_running = 0;

@@ -1152,8 +1122,6 @@ static void omap_8250_dma_tx_complete(void *param)
		dma->tx_err = 1;
		serial8250_set_THRI(p);
	}

	uart_port_unlock_irqrestore(&p->port, flags);
}

static int omap_8250_tx_dma(struct uart_8250_port *p)
@@ -1804,15 +1772,13 @@ static int omap8250_runtime_resume(struct device *dev)
		up = serial8250_get_port(priv->line);

	if (up && omap8250_lost_context(up)) {
		uart_port_lock_irq(&up->port);
		guard(uart_port_lock_irq)(&up->port);
		omap8250_restore_regs(up);
		uart_port_unlock_irq(&up->port);
	}

	if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) {
		uart_port_lock_irq(&up->port);
		guard(uart_port_lock_irq)(&up->port);
		omap_8250_rx_dma(up);
		uart_port_unlock_irq(&up->port);
	}

	atomic_set(&priv->active, 1);