[PATCH v8 01/11] serial: 8250_dw: allow port setup to report errors
From: James Hilliard
Date: Thu Nov 05 2026 - 16:05:44 EST
Return a status from dw8250_setup_port() and propagate failures through
the DW and LPSS probe paths before registering the UART. Use the existing
LPSS cleanup path to release board resources and IRQ vectors on failure.
Keep the current setup behavior by returning zero on both successful
paths. This separates error propagation from the configuration validation
that will use it.
Suggested-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
Signed-off-by: James Hilliard <james.hilliard1@xxxxxxxxx>
---
drivers/tty/serial/8250/8250_dw.c | 7 +++++--
drivers/tty/serial/8250/8250_dwlib.c | 6 ++++--
drivers/tty/serial/8250/8250_dwlib.h | 2 +-
drivers/tty/serial/8250/8250_lpss.c | 4 +++-
4 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 9cbe076463e0..80b2b673b422 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -765,8 +765,11 @@ static int dw8250_probe(struct platform_device *pdev)
dw8250_setup_dma_filter(p, data);
- if (!data->skip_autocfg)
- dw8250_setup_port(p);
+ if (!data->skip_autocfg) {
+ err = dw8250_setup_port(p);
+ if (err)
+ return err;
+ }
/* Use the BUSY-safe sequence for both integer and fractional divisors. */
p->set_divisor = dw8250_set_divisor;
diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
index 91b3607b64e6..4a06dec6e263 100644
--- a/drivers/tty/serial/8250/8250_dwlib.c
+++ b/drivers/tty/serial/8250/8250_dwlib.c
@@ -208,7 +208,7 @@ static const struct serial_rs485 dw8250_rs485_supported = {
SER_RS485_ADDR_DEST,
};
-void dw8250_setup_port(struct uart_port *p)
+int dw8250_setup_port(struct uart_port *p)
{
struct dw8250_port_data *pd = p->private_data;
struct uart_8250_port *up = up_to_u8250p(p);
@@ -250,7 +250,7 @@ void dw8250_setup_port(struct uart_port *p)
dev_dbg(p->dev, "CPR is not available, using 0x%08x instead\n", reg);
}
if (!reg)
- return;
+ return 0;
/* Select the type based on FIFO */
if (reg & DW_UART_CPR_FIFO_MODE) {
@@ -270,5 +270,7 @@ void dw8250_setup_port(struct uart_port *p)
pd->srbr = DW_UART_SRBR_0;
else
pd->srbr = UART_RX;
+
+ return 0;
}
EXPORT_SYMBOL_GPL(dw8250_setup_port);
diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h
index 7191cabfb086..4d32651956ab 100644
--- a/drivers/tty/serial/8250/8250_dwlib.h
+++ b/drivers/tty/serial/8250/8250_dwlib.h
@@ -100,7 +100,7 @@ struct dw8250_port_data {
unsigned int dw8250_get_divisor_dlf(struct uart_port *p, unsigned int baud, unsigned int *frac);
void dw8250_set_divisor_dlf(struct uart_port *p, unsigned int quot_frac);
void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, const struct ktermios *old);
-void dw8250_setup_port(struct uart_port *p);
+int dw8250_setup_port(struct uart_port *p);
static inline u32 dw8250_readl_ext(struct uart_port *p, int offset)
{
diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c
index f1b4b975571a..7ace0515038e 100644
--- a/drivers/tty/serial/8250/8250_lpss.c
+++ b/drivers/tty/serial/8250/8250_lpss.c
@@ -350,7 +350,9 @@ static int lpss8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret)
return ret;
- dw8250_setup_port(&uart.port);
+ ret = dw8250_setup_port(&uart.port);
+ if (ret)
+ goto err_exit;
ret = lpss8250_dma_setup(lpss, &uart);
if (ret)
--
2.53.0